专栏名称: 数据分析与开发
伯乐在线旗下账号,分享数据库相关技术文章、教程和工具,另外还包括数据库相关的工作。偶尔也谈谈程序员人生 :)
目录
相关文章推荐
AustinDatabases  ·  泉城济南IvorySQL 2025 ... ·  15 小时前  
AustinDatabases  ·  泉城济南IvorySQL 2025 ... ·  15 小时前  
数据中心运维管理  ·  2025年度国家数据中心节能监察任务清单印发 ... ·  2 天前  
数据中心运维管理  ·  弱电智能化中究竟有多少个子系统? ·  3 天前  
数据分析与开发  ·  突发!TP-Link ... ·  3 天前  
51好读  ›  专栏  ›  数据分析与开发

Memcached 与 Redis 实现的对比(上)

数据分析与开发  · 公众号  · 数据库  · 2016-11-23 23:27

正文

请到「今天看啥」查看全文


unsigned type : 4 ; // 对象的类型,包括 /* Object types */

unsigned encoding : 4 ; // 底部为了节省空间,一种type的数据,

// 可   以采用不同的存储方式

unsigned lru : REDIS_LRU_BITS ; /* lru time (relative to server.lruclock) */

int refcount ; // 引用计数

void * ptr ;

} robj ;


说到底redis还是一个key-value的数据库,不管它支持多少种数据结构,最终存储的还是以key-value的方式,只不过value可以是链表,set,sorted set,hash table等。和memcached一样,所有的key都是string,而set,sorted set,hash table等具体存储的时候也用到了string。 而c没有现成的string,所以redis的首要任务就是实现一个string,取名叫sds(simple dynamic string),如下的代码, 非常简单的一个结构体,len存储改string的内存总长度,free表示还有多少字节没有使用,而buf存储具体的数据,显然len-free就是目前字符串的长度。


struct sdshdr {

int len ;

int free ;

char buf [];

};


字符串解决了,所有的key都存成sds就行了,那么key和value怎么关联呢?key-value的格式在脚本语言中很好处理,直接使用字典即可,C没有字典,怎么办呢?自己写一个呗(redis十分热衷于造轮子)。看下面的代码,privdata存额外信息,用的很少,至少我们发现。 dictht是具体的哈希表,一个dict对应两张哈希表,这是为了扩容(包括rehashidx也是为了扩容)。dictType存储了哈希表的属性。redis还为dict实现了迭代器(所以说看起来像c++代码)。


哈希表的具体实现是和mc类似的做法,也是使用开链法来解决冲突,不过里面用到了一些小技巧。比如使用dictType存储函数指针,可以动态配置桶里面元素的操作方法。又比如dictht中保存的sizemask取size(桶的数量)-1,用它与key做&操作来代替取余运算,加快速度等等。总的来看,dict里面有两个哈希表,每个哈希表的桶里面存储dictEntry链表,dictEntry存储具体的key和value。


前面说过,一个dict对于两个dictht,是为了扩容(其实还有缩容)。正常的时候,dict只使用dictht[0],当dict[0]中已有entry的数量与桶的数量达到一定的比例后,就会触发扩容和缩容操作,我们统称为rehash,这时,为dictht[1]申请rehash后的大小的内存,然后把dictht[0]里的数据往dictht[1]里面移动,并用rehashidx记录当前已经移动万的桶的数量,当所有桶都移完后,rehash完成,这时将dictht[1]变成dictht[0], 将原来的dictht[0]变成dictht[1],并变为null即可。不同于memcached,这里不用开一个后台线程来做,而是就在event loop中完成,并且rehash不是一次性完成,而是分成多次,每次用户操作dict之前,redis移动一个桶的数据,直到rehash完成。这样就把移动分成多个小移动完成,把rehash的时间开销均分到用户每个操作上,这样避免了用户一个请求导致rehash的时候,需要等待很长时间,直到rehash完成才有返回的情况。不过在rehash期间,每个操作都变慢了点,而且用户还不知道redis在他的请求中间添加了移动数据的操作,感觉redis太贱了 :-D


typedef struct dict {

dictType * type ; // 哈希表的相关属性

void * privdata ;







请到「今天看啥」查看全文