随笔分类 - Redis设计与实现
摘要:一、设计优化 1. 估算Redis内存使用量 以非数字的字符串键值对为例,假设key和value的长度均为12个字节,则内部使用的编码方式为embstr。共计90000个键值对占用的空间 Redis中存储键值对使用字典,字典内部使用哈希表数组,数组的每个元素dictEntry中共有三个指针(指向键的
阅读全文
摘要:1. 分布式锁的特点 互斥性:同一时刻只有一个客户端可以持有锁 容错性:只要锁服务集群中大部分节点正常运行,客户端就可以进行锁操作 避免死锁:保证锁一定能释放,正常释放或超时释放 加锁和解锁是同一个客户端 2. 分布式锁的实现方式 基于数据库实现分布式锁(乐观锁、悲观锁) 基于zookeeper时节
阅读全文
摘要:Redis 5.0版本之后提供的新的数据类型,类似于MQ,是发布订阅模式的改进 1. Streams数据结构 每一个Streams有唯一的名称,对应了Redis的键。将所有加入的消息(xadd指令)串联起来,每个消息有一个ID Consumer Group:消费组,同一个消息可以被组内成员消费,但只
阅读全文
摘要:1. BitMap(Redis2.2版本之后) 内部编码为二进制字符串 1. 命令:setbit key offset value offset 必须是数字代表坐标,从0开始计数;value只能为0或1 底层初始化一个全为0的字符串(默认32位),根据offset的将对应位置的值更改为value,用
阅读全文
摘要:Redis的事务是指将多个命令请求打包,一次性地,按顺序执行的机制。通过MULTI、EXEC、WATCH等命令实现事务功能。 19.1 事务的实现 19.1.1 事务的开始 MULTI命令的执行代表了一个事务的开始,会将执行该命令的客户端由非事务状态切换成事务状态(在客户端状态的flags属性中打开
阅读全文
摘要:通过SUBSCRIBE命令,客户端可以订阅一个或多个频道,每当有其他客户端向被订阅的频道发送消息,频道的订阅者都会收到消息 通过PSUBSCRIBE命令,客户端可以订阅一个或多个模式,每当有其他客户端向被订阅的频道发送消息,与该频道相匹配的模式订阅者也会收到 18.1 频道的订阅和退订 redisS
阅读全文
摘要:Redis集群是Redis提供的分布式数据库方案,集群通过分片(sharding)来进行数据共享,并提供复制和故障转移功能 17.1 节点 一个Redis集群通常由多个节点(node,一个Redis服务器)组成。刚开始每个节点都是一个集群,需要手动指定将其他节点添加到当前集群。 CLUSTER ME
阅读全文
摘要:由一个或多个Sentinel实例组成的Sentinel系统,监测任意多主从服务器,一旦某个主服务器下线并超过等待时间,会将其下的某个从服务器上升为主服务器,对其余从服务器发送复制命令,将它们归属到新的主服务器下的从服务器,并且会继续监视下线的服务器,等其重新上线后,将其设置为新主服务器下的从服务器。
阅读全文
摘要:使用SLAVEOF命令或者设置slaveof选项,让一个服务器复制另一个服务器 15.1 旧版复制功能的实现 Redis的复制功能分为同步和命令传播 同步操作用于将从服务器的数据库状态更新为主服务器的数据库状态 当主服务器数据库状态被更改,会将执行的写命令传给从服务器执行 15.1.1 同步 客户端
阅读全文
摘要:14.1 命令请求的执行过程 14.1.1 发送命令请求 客户端将用户输入的命令转化成协议格式,连接到服务器的客户端套接字,将命令请求发送给服务器 14.1.2 读取命令请求 当客户端套接字因为客户端的写入而可读时,产生文字事件,服务器调用命令处理器处理 读取套接字中的命令,存储到客户端状态输入缓冲
阅读全文
摘要:12.1 文件事件 文件事件分为写事件(AE_WRITABLE)和读事件(AE_READABLE) 采用I/O复用程序监听多个套接字,根据套接字当前执行的任务关联事件处理器。当一个套接字准备好执行应答、读取、写入、关闭操作时,会产生对应的文件事件,文件事件分派器会将文件事件交给对应的事件处理器。 同
阅读全文
摘要:AOF持久化是通过保存Redis服务器所执行的写命令来记录数据库状态的。 11.1 AOF持久化的实现 AOF持久化功能的实现可以分为命令追加、文件写入、文件同步三个步骤 11.1.1 命令追加 当AOF持久化功能打开时,服务器执行完一个写命令,会在服务器状态的aof_buf缓冲区的末尾添加被执行的
阅读全文
摘要:将Redis中的非空数据库和其中保存的键值对称为数据库状态。RDB持久化即将内存中保存的数据库状态写入到RDB文件中,保存在磁盘上。 10.1 RDB文件的创建与载入 RDB文件的创建 SAVE命令:阻塞服务器进程,期间不再处理请求,直到RDB文件创建完毕 BGSAVE命令:派生一个子进程(fork
阅读全文
摘要:9.1 服务器中的数据库 Redis服务器将所有数据库都保存在服务器状态redis.h/redisServer结构的db数组中。 struct redisServer{ //一个数组,保存着服务器中的所有数据库 redisDb *db; //服务器的数据库数量 int denum; } denum属
阅读全文
摘要:Redis中的对象: 字符串对象 列表对象——压缩列表或双端链表 哈希对象——压缩列表或字典 集合对象——整数集合或字典 有序集合对象——压缩列表或跳表+字典 每个对象针对不同的使用场景选择底层实现,并使用引用计数器决定对象的回收,某些条件下可以通过引用计数器实现共享。 8.1 对象的类型和编码 R
阅读全文
摘要:当一个列表键只包含少量的列表项,并且每个列表项要么就是小整数值,要么就是长度比较短的字符串,Redis就会使用压缩列表作为列表键的底层实现。设计的目的是为了节省内存。作为列表键和哈希键的实现之一。 7.1 压缩列表的构成 zlbytes:代表了整个压缩列表占用的内存字节数 zltail:表尾距表头的
阅读全文
摘要:当一个集合只包含整数,且集合的元素数量不多时,Redis会使用整数集合作为底层实现。 6.1 整数集合的实现 可以保存int16_t、int32_t或者int64_t的整数值。并且保证集合中不会出现重复的元素。 typedef struct intset{ //编码方式 uint32_t encod
阅读全文
摘要:跳跃表 在每个节点维持多个指向其他节点的指针,达到快速访问节点的目的。Redis使用跳跃表作为有序集合键的底层实现之一。 5.1 跳跃表的实现 redis.h/zskiplistNode表示跳跃表节点。redis.h/zskiplist保存跳跃表节点的相关信息:节点数量、指向表头表尾节点的指针等。
阅读全文
摘要:在字典中,一个键(key)可以和一个值(value)进行关联(或者说将键映射为值),这些关联的键和值就称为键值对。 4.1 字典的实现 Redis的字段使用哈希表作为底层实现。 4.1.1 哈希表 typedef struct ditch{ //哈希表数组 dictEntry **table; //
阅读全文
摘要:链表提供了高效的节点重排,顺序性节点访问,并可以通过增删节点灵活调整链表的长度。链表是双向无环的。 3.1 链表和链表节点的实现 1. 节点 typedef struct listNode{ //前置节点 struct listNode *prev; //后置节点 struct listNode *
阅读全文

浙公网安备 33010602011771号