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来存放这些键值对,这可以减少存放节点指针的空间,因此它被用来 ...
随机推荐
- BZOJ 3162 / Luogu P4895: 独钓寒江雪 树hash+DP
题意 给出一棵无根树,求本质不同的独立集数模100000000710000000071000000007的值. n≤500000n\le 500000n≤500000 题解 如果是有根树就好做多了.然 ...
- 测试使用API
https://api.github.com/users/github 返回值中的某些URL也可以作为测试API使用
- Elasticsearch环境搭建和介绍(Windows)
一.Elasticsearch介绍和安装 1.1 介绍 Elastic Elastic官网:https://www.elastic.co/cn/ Elastic有一条完整的产品线:Elasticse ...
- HTML与CSS网页开发基础
HTML标记语言 HTML文件的创建 整个编译器,或者记事本,文件扩展名改为.htm或者.html HTML文档结构 <html>标记:开头,所有HTML文件以<html>标记 ...
- Linux find,grep 命令
使用实验楼Linux环境开发,部分内容有所参考,link:https://www.shiyanlou.com/ 概述: find: 在目录中搜索文件,它的使用权限是所有用户 命令格式: find [路 ...
- geometry_msgs/PoseStamped 类型的变量的构造
#navpoint.msg geometry_msgs/PoseStamped target_pose uint8 floor uint8 type target_pose 的类型为geometry_ ...
- python生成二维码(简易)
首先要的配置: pillow image qrcode zxing 然后直接上代码: import PIL import qrcode # 实例化二维码生成类 qr = qrcode.QRCode( ...
- mysql触发器个人实战
create trigger idtriggerbefore insert on flow_management_copy1for each ROWBEGIN SET new.ID= CONCAT(R ...
- ArrayUtils.
String sfck=mp.get("SFCK")==null?"":mp.get("SFCK").toString(); Str ...
- spring boot 集成RabbitMQ的异常
com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.clos ...