一、src/server.c 中的redisCommandTable列出的所有redis支持的命令,其中字符串命令包括从get到mget;列表命令从rpush到rpoplpush;集合命令包括从sadd到sscan;有序集合命令从zadd到zscan;哈希表命令包括从hse到hscan;地理命令包括从geoadd到geodist;位操作从bitop到bitpos;HyperLogLog命令包含padd到pfmerge等。

二、每种存储类型对应的底层数据结构

  • 字符串-->sds.c  简单动态字符串,该类型取代char *类型,这里动态指的是字符长的buff是动态增长的。当append字符串且剩余空间不足时会分配请求空间加上原有空间的总和的两倍空间。在目前版本的 Redis 中, SDS_MAX_PREALLOC 的值为 1024 * 1024 , 也就是说, 当大小小于 1MB 的字符串执行追加操作时, sdsMakeRoomFor 就为它们分配多于所需大小一倍的空间; 当字符串的大小大于 1MB , 那么 sdsMakeRoomFor 就为它们额外多分配 1MB 的空间。执行过 append 命令的字符串会带有额外的预分配空间, 这些预分配空间不会被释放, 除非该字符串所对应的键被删除, 或者等到关闭 Redis 之后, 再次启动时重新载入的字符串对象将不会有预分配空间。因为执行 append命令的字符串键数量通常并不多, 占用内存的体积通常也不大, 所以这一般并不算什么问题。另一方面, 如果执行 append 操作的键很多, 而字符串的体积又很大的话, 那可能就需要修改 Redis 服务器, 让它定时释放一些字符串键的预分配空间, 从而更有效地使用内存。

struct __attribute__ ((__packed__)) sdshdr8 {
uint8_t len; /* used */
uint8_t alloc; /* excluding the header and null terminator */
unsigned char flags; /* 3 lsb of type, 5 unused bits */
char buf[];
};

  • 列表--> Quicklist.c 快表,一种双向链表和ziplist(压缩表)相结合的链表,存储的内容是zl(ziplist), ziplist由于是一整块连续内存,所以存储效率很高。但是,它不利于修改操作,每次数据变动都会引发一次内存的realloc。特别是当ziplist长度很长的时候,一次realloc可能会导致大批量的数据拷贝,进一步降低性能。

typedef struct quicklistNode {
struct quicklistNode *prev;
struct quicklistNode *next;
unsigned char *zl;
unsigned int sz; /* ziplist size in bytes */
unsigned int count : 16; /* count of items in ziplist */
unsigned int encoding : 2; /* RAW==1 or LZF==2 */
unsigned int container : 2; /* NONE==1 or ZIPLIST==2 */
unsigned int recompress : 1; /* was this node previous compressed? */
unsigned int attempted_compress : 1; /* node can't compress; too small */
unsigned int extra : 10; /* more bits to steal for future usage */
} quicklistNode;

  • 哈希表-->Dict.c  字典

typedef struct dict {

dictType *type;
void *privdata;
dictht ht[2];
long rehashidx; /* rehashing not in progress if rehashidx == -1 */
unsigned long iterators; /* number of iterators currently running */
} dict;

  • 有序集合-->T_zset.c ,用跳跃表skiplist,查找元素的平均复杂度为O(logn)

typedef struct zskiplist {
struct zskiplistNode *header, *tail;
unsigned long length;
int level;
} zskiplist;

typedef struct zskiplistNode {
sds ele;
double score;
struct zskiplistNode *backward;
struct zskiplistLevel {
struct zskiplistNode *forward;
unsigned int span;
} level[];
} zskiplistNode;

其余类型基本用的sds与dict相结合的方式。

这篇微博里有更详细的描述,建议下载源码一并读。

最新文章

  1. 安装VS 2015完成后,VS2012 打开报错
  2. 仿QQ侧滑菜单<大自然的搬运工-代码不是我的>
  3. Linux C编程(1) vim及gcc命令
  4. window resize的时候禁止频繁触发事件
  5. ArcEngine 异常:field is not editable
  6. Qt 中使用vector
  7. mysql SQL SERVER 的算法
  8. winform 自定义控件以及委托事件的使用
  9. java比较相等符
  10. HttpHelps类,用来实现Http访问,Post或者Get方式的,直接访问,带Cookie的,带证书的等方式,可以设置代理
  11. Angular20 nginx安装,angular项目部署
  12. 电梯调度编写(oo-java编程)
  13. c/c++ 拷贝控制 右值与const引用
  14. 码农人生——从未学过Android如何开发Android App 案例讲解-第002期案例
  15. Object.defineProperty方法
  16. HTTP请求头和响应头部包括的信息有哪些?
  17. 【CF809E】Surprise me!(动态规划,虚树,莫比乌斯反演)
  18. 如何创建线程第一种继承Thread类
  19. Java,JDK动态代理的原理分析
  20. [转载] Spring框架——AOP前置、后置、环绕、异常通知

热门文章

  1. [CSS] The :empty Pseudo Selector Gotchas
  2. 测试使用API
  3. Postgresql vacuum freeze相关参数
  4. 使用 Java 创建聊天客户端-1
  5. 定时器( setInterval和 setTimeout)
  6. Codechef July Challenge 2019 Division 1题解
  7. webpack4温习总结
  8. mongodb的权限操作
  9. python eval的用法
  10. python3编程基础之一:注释模块和包