- 手艺 tags:
- c
- redis published: true comments: true
Redis的几个核心数据结构定义在redis.h和dict.h中。Redis服务器总的数据结构里的根节点是redisServer,下面包含一个redisDb结构数组。数组的大小定义在redis.conf中的databases项,客户端可以通过select命令选择相应的DB。
一个redisDb定义了redis数据库的基本数据结构,redisDb结构定义如下
[cc lang="c"]
typedef struct redisDb {
dict *dict; /* The keyspace for this DB */
dict *expires; /* Timeout of keys with a timeout set */
dict *blocking_keys; /* Keys with clients waiting for data (BLPOP) */
dict *io_keys; /* Keys with clients waiting for VM I/O */
dict *watched_keys; /* WATCHED keys for MULTI/EXEC CAS */
int id;
} redisDb;
[/cc]
其中
- dict 用于存储键值的哈希表结构
- expires 用于存储键、过期时间的哈希表结构
- blocking_keys 用于存储键、阻塞数据的哈希表结构。目前仅仅在阻塞式的blpop brpop中使用。
- io_keys 存储等待将数据从swap读出的key (vmThreadedIOCompletedJob, dontWaitForSwappedKey, waitForSwappedKey)
- watched_keys 用于支持WATCH命令,实现乐观锁功能
- id 数据库编号
dict结构定义在dict.h中,主要的定义有:
[cc lang="c"]
typedef struct dictEntry {
void *key;
void *val;
struct dictEntry *next;
} dictEntry;
typedef struct dictht {
dictEntry **table;
unsigned long size;
unsigned long sizemask;
unsigned long used;
} dictht;
typedef struct dict {
dictType *type;
void *privdata;
dictht ht[2];
int rehashidx; /* rehashing not in progress if rehashidx == -1 */
int iterators; /* number of iterators currently running */
} dict;
[/cc]
每个dict中包含两个dictht结构,用来在rehash的时候进行数据交换。rehashidx用于记录rehash的进程,值是当前rehash的table索引。dictht中table二维数组,以hash值为索引。size是哈希表的大小,初始值是4,随着rehash的进行,变成大于size的最小2n。sizemask是size-1,用来与哈希值做&运算。
redis在引如virtual memory之前,就是以这样的数据结构运行在内存中的。