MySQL · RocksDB · Memtable flush分析

概述

首先我们知道在RocksDB中,最终数据的持久化都是保存在SST中,而SST则是由Memtable刷新到磁盘生成的,因此这次我们就主要来分析在RocksDB中何时以及如何来Flush内存数据(memtable)到SST.

阅读全文

MySQL · RocksDB · MemTable的写入

简介

在之前的文章中我们知道RocksDB每一次写入,都是先写WAL,然后写Memtable,这次我们就来分析下MemTable的实现.

在RocksDB中,每个ColumnFamily都有自己的Memtable,互不影响.而在RocksDB中Memtable有多种实现(SkipList/HashSkipList/HashLinkList/Vector),具体的区别可以看这里,我们这次主要来分析默认的实现skiplist(只有skiplist是可以并发插入的).

阅读全文

MySQL · RocksDB · 写入逻辑的实现

简介

在RocksDB中,每次写入它都会先写WAL,然后再写入MemTable,这次我们就来分析这两个逻辑具体是如何实现的.
首先需要明确的是在RocksDB中,WAL的写入是单线程顺序串行写入的,而MemTable则是可以并发多线程写入的。

阅读全文

MySQL · RocksDB · Column Family介绍

概述

在RocksDB 3.0中加入了Column Family特性,加入这个特性之后,每一个KV对都会关联一个Column Family,其中默认的Column Family是 “default”.
Column Family主要是提供给RocksDB一个逻辑的分区.从实现上来看不同的Column Family共享WAL,而都有自己的Memtable和SST.这就意味着我们可以很
快速已经方便的设置不同的属性给不同的Column Family以及快速删除对应的Column Family.

阅读全文

MySQL · RocksDB · MANIFEST文件介绍

概述

在RocksDB中MANIFEST保存了存储引擎的内部的一些状态元数据,简单来说当系统异常重启,或者程序异常被退出之后,RocksDB需要有一种机制能够恢复到一个一致性的状态,
而这个一致性的状态就是靠MANIFEST来保证的.

阅读全文

MySQL · RocksDB · WAL(WriteAheadLog)介绍

概述

在RocksDB中每一次数据的更新都会涉及到两个结构,一个是内存中的memtable(后续会刷新到磁盘成为SST),第二个是WAL(WriteAheadLog)。
本篇文章主要就是来介绍WAL.

阅读全文

Lua源码剖析(五)

这次主要来分析lua的gc。

首先lua中的数据类型包括下面9种,ni, Boolean, number, string, table,user data, thread , functions 以及 lightusedata.其中 string, table,thread , function 是会被垃圾回收管理的,其他的都是值存在。

因此我们来看对应的GC数据结构.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  
#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked

typedef struct GCheader {

CommonHeader;

} GCheader;

union GCObject {

GCheader gch;

union TString ts;

union Udata u;

union Closure cl;

struct Table h;

struct Proto p;

struct UpVal uv;

struct lua_State th; /\* thread \*/

};

我们可以看到在lua中字符串,userdata, thread, table ,string, thread(以及Upval, proto) 都会被垃圾回收管理。这里比较关键的就是GCheader这个结构体,我们可以看到这个结构体其实就是一个链表,也就是说所有的gc对象都会被链到一个链表中,其中tt表示当前对象的类型,在lua中包括下面这些类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  
#define LUA_TNIL 0

#define LUA_TBOOLEAN 1

#define LUA_TLIGHTUSERDATA 2

#define LUA_TNUMBER 3

#define LUA_TSTRING 4

#define LUA_TTABLE 5

#define LUA_TFUNCTION 6

#define LUA_TUSERDATA 7

#define LUA_TTHREAD 8

而marked表示当前对象的状态(涉及到gc算法,后续会详细分析),状态位包括下面这些:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  
#define WHITE0BIT 0

#define WHITE1BIT 1

#define BLACKBIT 2

#define FINALIZEDBIT 3

#define KEYWEAKBIT 3

#define VALUEWEAKBIT 4

#define FIXEDBIT 5

#define SFIXEDBIT 6

#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)

阅读全文

Lua源码剖析(四)

前面三篇请看我前面的 blog

这篇主要来分析lua的虚拟机的实现,我看的代码依旧是5.1

因此首先从luaL_loadfile开始,这个函数我们知道是在当前的lua state加载一个lua文件,其中第二个参数就是filename。

其中LoadF结构很简单,它用来表示一个load file:

struct LoadF {
1
2
3
4
5
6
7
8
    
int extraline;

FILE *f;

char buff[LUAL_BUFFERSIZE];

} LoadF;

其中会使用fopen来打开对应的文件名,然后根据第一个字符来判断是否是注释(#),如果是则跳过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
      
lua_pushfstring(L, "@%s", filename);

lf.f = fopen(filename, "r");

if (lf.f == NULL) return errfile(L, "open", fnameindex);

}

c = getc(lf.f);

if (c == ‘#’) { /\* Unix exec. file? \*/

lf.extraline = 1;

while ((c = getc(lf.f)) != EOF && c != ‘\n’) ; /\* skip first line \*/

if (c == ‘\n’) c = getc(lf.f);

}

阅读全文

Early Retransmit for TCP原理以及实现

Early Retransmit for TCP(ER)是google为了解决快重传的一些局限,从而对快重传(fast retransmit)做出的一些改变,其中ER在linux kernel 3.5进入了内核,他的paper在这里:

http://tools.ietf.org/html/rfc5827

首先我们要知道快重传算法的弱点很多,比如如果发送端接收不到足够数量(一般来说是3个)的ack,那么快重传算法就无法起作用,这个时候就只能等待RTO超时。ER主要就是为了解决这个问题的。在下面的条件下,就会导致收不到足够的ack。

  • 拥塞窗口比较小
  • 窗口中一个很大的段丢失或者在传输的结尾处发生了丢包

阅读全文

linux 内核tcp拥塞处理(二)

这篇接的是我最早在javaeye的那篇blog. http://simohayha.iteye.com/blog/614258

首先我们要知道在linux下分为5个拥塞状态,定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  
enum tcp_ca_state {

TCP_CA_Open = 0,

#define TCPF_CA_Open (1<<TCP_CA_Open)

TCP_CA_Disorder = 1,

#define TCPF_CA_Disorder (1<<TCP_CA_Disorder)

TCP_CA_CWR = 2,

#define TCPF_CA_CWR (1<<TCP_CA_CWR)

TCP_CA_Recovery = 3,

#define TCPF_CA_Recovery (1<<TCP_CA_Recovery)

TCP_CA_Loss = 4

#define TCPF_CA_Loss (1<<TCP_CA_Loss)

}

TCP_CA_OPEN这个就是初始状态,也就是没有检测到任何拥塞的情况.

TCP_CA_Disorder 顾名思义,这个状态就是当第一次由于收到SACK或者重复的ack而检测到拥塞时,就进入这个状态.

TCP_CA_CWR 由于一些拥塞通知事件而导致拥塞窗口减小,然后就会进入这个状态。比如ECN,ICMP,本地设备拥塞。

TCP_CA_Recovery 当CWND减小

TCP_CA_Loss 超时或者SACK被拒绝,此时表示数据包丢失,因此进入这个状态.

阅读全文