Redis源码解析
一、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相结合的方式。
这篇微博里有更详细的描述,建议下载源码一并读。
Redis源码解析的更多相关文章
- .Net Core缓存组件(Redis)源码解析
上一篇文章已经介绍了MemoryCache,MemoryCache存储的数据类型是Object,也说了Redis支持五中数据类型的存储,但是微软的Redis缓存组件只实现了Hash类型的存储.在分析源 ...
- Redis源码解析:15Resis主从复制之从节点流程
Redis的主从复制功能,可以实现Redis实例的高可用,避免单个Redis 服务器的单点故障,并且可以实现负载均衡. 一:主从复制过程 Redis的复制功能分为同步(sync)和命令传播(comma ...
- Redis源码解析之跳跃表(三)
我们再来学习如何从跳跃表中查询数据,跳跃表本质上是一个链表,但它允许我们像数组一样定位某个索引区间内的节点,并且与数组不同的是,跳跃表允许我们将头节点L0层的前驱节点(即跳跃表分值最小的节点)zsl- ...
- Redis源码解析:13Redis中的事件驱动机制
Redis中,处理网络IO时,采用的是事件驱动机制.但它没有使用libevent或者libev这样的库,而是自己实现了一个非常简单明了的事件驱动库ae_event,主要代码仅仅400行左右. 没有选择 ...
- Redis源码解析:26集群(二)键的分配与迁移
Redis集群通过分片的方式来保存数据库中的键值对:一个集群中,每个键都通过哈希函数映射到一个槽位,整个集群共分16384个槽位,集群中每个主节点负责其中的一部分槽位. 当数据库中的16384个槽位都 ...
- Redis源码解析:25集群(一)握手、心跳消息以及下线检测
Redis集群是Redis提供的分布式数据库方案,通过分片来进行数据共享,并提供复制和故障转移功能. 一:初始化 1:数据结构 在源码中,通过server.cluster记录整个集群当前的状态,比如集 ...
- jedis的publish/subscribe[转]含有redis源码解析
首先使用redis客户端来进行publish与subscribe的功能是否能够正常运行. 打开redis服务器 [root@localhost ~]# redis-server /opt/redis- ...
- redis源码解析之内存管理
zmalloc.h的内容如下: void *zmalloc(size_t size); void *zcalloc(size_t size); void *zrealloc(void *ptr, si ...
- Redis源码解析之ziplist
Ziplist是用字符串来实现的双向链表,对于容量较小的键值对,为其创建一个结构复杂的哈希表太浪费内存,所以redis 创建了ziplist来存放这些键值对,这可以减少存放节点指针的空间,因此它被用来 ...
随机推荐
- Web前端 --- 前端基础简介
目录 web端 HTTP协议 web端 1.前端,后端 什么是前端 任何与用户直接打交道的操作界面,都可以称之为前端, eg:电脑界面 手机界面 什么是后端 真正的幕后操作者 2.前端学习的历程 HT ...
- ServletRequest、 HttpServletRequest、Request的联系与区别
一. servlet理论上可以处理多种形式的请求响应形式 http只是其中之一 所以HttpServletRequest HttpServletResponse分别是ServletRequest和Se ...
- HTML 005 段落
HTML 段落 HTML 可以将文档分割为若干段落. HTML 段落 段落是通过 <p> 标签定义的. 实例 <p>这是一个段落 </p> <p>这是另 ...
- sql server 事务和锁的作用
事务 事务就是作为一个逻辑工作单元的SQL语句,如果任何一个语句操作失败那么整个操作就被失败,以后操作就会回滚到操作前状态,或者是上个节点.为了确保要么执行,要么不执行,就可以使用事务.而锁是实现事务 ...
- jq导航
做外部前端都会用到导航栏应用 一般导航应用会鼠标碰到变颜色 或子导航出现 下面为基本的导航 <div class="header"> <ul style=&qu ...
- REST与RPC区别
OSI网络七层模型 第一层:应用层.定义了用于在网络中进行通信和传输数据的接口: 第二层:表示层.定义不同的系统中数据的传输格式,编码和解码规范等: 第三层:会话层.管理用户的会话,控制用户间逻辑连接 ...
- Oracle 11g 禁用 SQL Tuning Advisor 与 auto space advisor
生产上有一套11g数据库alert.log报错ORA-16957: SQL Analyze time limit interrupt. 查询MOS相关文档Troubleshooting: ORA-1 ...
- P1143 进制转换
漂亮小姐姐点击就送:https://www.luogu.org/problemnew/show/P1143 题目描述 请你编一程序实现两种不同进制之间的数据转换. 输入输出格式 输入格式: 输入数据共 ...
- Django系列(三):单表操作
1.ORM简介 MTV或者MTV框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人 ...
- linux系列(十六):which命令
1.命令格式: which 可执行文件名称 2.命令功能: which指令会在PATH变量指定的路径中,搜索某个系统命令的位置,并且返回第一个搜索结果. 3.命令参数: -n 指定文件名长度,指定的长 ...