![](https://img-blog.csdnimg.cn/20201014180756930.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Redis源码初探
文章平均质量分 88
以源码为线索,逐步理解Redis设计思想和实现。
kinron_
一个路过的菜鸡程序员罢了
展开
-
Redis源码初探(十四)服务器-时间事件和服务器创建过程
serverCron函数 Redis服务器中的serverCron函数默认每隔100毫秒执行一次,这个函数负责管理服务器的资源,并保持服务器自身的良好运转。 int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) { int j; REDIS_NOTUSED(eventLoop); REDIS_NOTUSED(id); REDIS_NOTUSED(clientData);原创 2021-08-12 00:12:05 · 289 阅读 · 0 评论 -
Redis源码初探(十三)服务器-命令请求执行过程
服务器 Redis服务器负责与多个客户端建立网络连接,处理客户端发送的命令请求,在数据库中保存客户端执行命令所产生的数据,并通过资源管理来维持服务器自身的运转。 命令请求的执行过程 如果客户端执行了以下命令: SET KEY VALUE 那么客户端和服务器供需要执行以下操作: 客户端向服务器发送命令请求SET KEY VALUE 服务器接收并处理客户端发来的命令请求SET KEY VALUE,在数据库中进行设置操作,并产生命令回复OK 服务器将命令回复OK发送给客户端 客户端接收服务器返回的命令回复OK原创 2021-08-08 23:18:57 · 233 阅读 · 0 评论 -
Redis源码初探(十二)事件
事件 Redis基于reactor模型开发了自己的网络事件处理器:这个处理器被称为文件处理器: 文件事件处理器使用I/O多路复用程序来同时监听多个套接字,并根据套接字目前执行的任务来为套接字关联不同的事件处理器。 当被监听的套接字准备好执行连接应答(accept)、读取(read)、写入(write)、关闭(close)等操作时,与操作相对应的文件事件就会产生,这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。 虽然文件事件处理器以单线程方式运行,但通过使用I/O多路复用程序来监听多原创 2021-08-03 09:42:57 · 126 阅读 · 0 评论 -
Redis源码初探(十一)客户端
客户端 Redis服务器是典型的一对多服务器程序:一个服务器可以与多个客户端建立网络连接,每个客户端可以向服务器发送命令请求,而服务器则接收并处理客户端发送的命令请求,并向客户端返回命令回复。 通过使用I/O多路复用技术实现的文件事件处理器,Redis服务器使用单线程单进程的方式来处理命令请求,并与多个客户端进行网络通信。 Redis使用redis.h/redisClient结构保存客户端当前的状态: typedef struct redisClient { // 套接字描述符 int fd原创 2021-07-31 11:07:14 · 108 阅读 · 0 评论 -
Redis源码初探(十)AOF持久化
AOF持久化 除了RDB持久化功能之外,Redis还提供了AOF持久化功能。与RDB持久化通过保存数据库中的键值对来记录数据库状态不同,AOF持久化是通过保存Redis服务器所执行的写命令来记录数据库状态的。 AOF持久化的实现 AOF持久化功能的实现可以分为命令追加(append)、文件写入、文件同步(sync)三个步骤。 命令追加 当AOF持久化功能处于打开状态时,服务器在执行完一个写命令之后,会以协议格式将执行的写命令追加到服务器状态的aof_buf缓冲区的末尾: struct redisServer原创 2021-07-17 10:46:36 · 73 阅读 · 0 评论 -
Redis源码初探(九)RDB持久化
RDB持久化 因为Redis是内存数据库,它将自己的数据库状态存储在内存里面,所以如果不想办法将储存在内存中的数据库状态保存在磁盘里面,那么一旦服务器进程退出,服务器中的数据库状态也会消失不见。 为了解决这个问题,Redis提供了RDB持久化功能,这个功能可以将Redis在内存中的数据库状态保存到磁盘里面,避免数据意外丢失。 RDB持久化既可以手动执行,也可以根据服务器配置选项定期执行,该功能可以将某个时间点上的数据库状态保存到一个RDB文件中。 RDB持久化功能所生成的RDB文件是一个经过压缩的二进制文件原创 2021-07-16 22:53:10 · 125 阅读 · 0 评论 -
Redis源码初探(8)过期键删除策略
过期键删除策略 对于过期键的删除,有三种常用的删除策略: 定时删除:在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除操作。 惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期,就删除该键;如果没有过期,就返回该键。 定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。 三种策略的对比 定时删除: 优点:对内存是最友好的,通过使用定时器,定时删除策略可以保证过期键尽可能快地被删除,并释放过期键所占用的内存。原创 2021-07-16 17:24:45 · 116 阅读 · 0 评论 -
Redis源码初探(7)对象的实现
对象 Redis并没有使用基础的数据结构来实现键值对数据库,而是基于这些数据结构创建了一个对象系统,这个系统包含字符串对象、列表对象、哈希对象、集合对象这五种类型的对象,这种对象都用到了至少一种之前介绍的数据结构。 同时,Redis的对象系统还实现了基于引用计数技术的内存回收机制,当程序不再使用某个对象时,这个对象所占用的内存就会被自动释放;另外,Redis还通过引用技术技术实现了对象共享机制,这一机制可以在适当的条件下,通过让多个数据库键共享同一个对象来节约内存。 对象的类型和编码 Redis使用对象来表原创 2021-06-29 14:36:34 · 97 阅读 · 0 评论 -
Redis源码初探(6)位图bitmap
位图 Redis使用字符串对象来表示位数组,因为字符串对象使用的SDS数据结构是二进制安全的,所以程序可以直接使用SDS结构来保存位数组,并使用SDS的操作函数来处理位数组。 位数组的表示 Redis通过如下方式用SDS表示一字节长的位数组: redisObject.type的值为Redis_String表示这是一个字符串对象。 sdshdr.len的值为1,表示这个SDS保存了一个一字节长的位数组。 buf数组中的buf[0]字节保存了一字节长的位数组。 buf数组中的buf[1]字节保存了SDS程序自原创 2021-06-21 16:15:27 · 164 阅读 · 0 评论 -
Redis源码初探(5)快表quicklist
快表 快速列表 quicklist 是 3.2 版本新添加的编码类型,结合了 ziplist 和 linkedlist 的一种编码。 同时在 3.2 版本中,列表也废弃了 ziplist 和 linkedlist,这也是《Redis设计与实现》一书中没有提到的一种底层数据结构。 快表构成 这里我直接下载了Redis6.0源码,快表实现在quicklist.h: typedef struct quicklist { quicklistNode *head; quicklistNode *tai原创 2021-06-10 09:45:03 · 397 阅读 · 1 评论 -
Redis源码初探(4)压缩列表ziplist
压缩列表 压缩列表(ziplist)是列表键和哈希键的底层实现之一。当一个列表键只包含少量列表项,并且每个列表项要么就是小整数值,要么就是长度比较短的字符串,那么Redis就会使用压缩列表来做列表键的底层实现。 压缩列表的构成 压缩列表是Redis为了节约内存而开发的,是由一系列特殊编码的连续内存块组成的顺序型数据结构。一个压缩列表可以包含任意多个节点,每个节点可以保存一个字节数组或者一个整数值。 area |<---- ziplist header ---->|<--- e原创 2021-06-09 16:11:35 · 195 阅读 · 0 评论 -
Redis源码浅析(3)跳跃表skiplist和整数集合intset
跳跃表 跳跃表(skiplist)是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。 跳跃表支持平均O(log N)、最快O(N)复杂度的节点查找,还可以通过顺序性操作来批量处理节点。在大部分情况下,跳跃表的效率和平衡树相媲美,并且因为跳跃表的实现比平衡树要来得更为简单,所以有不少程序都使用跳跃表来替代平衡树。 跳跃表的实现 Redis的跳跃表由redis.h/zskiplistNode和redis.h/zskiplist两个结构定义。 跳跃表节点 typedef原创 2021-06-04 17:15:00 · 175 阅读 · 1 评论 -
Redis源码初探(2)链表和字典
链表 链表提供了高效的节点重排能力,以及顺序性的节点访问方式,并且可以通过增删节点来灵活地调整链表的长度。链表在Redis中的应用非常广泛,比如列表键的底层实现之一就是链表。当一个列表键包含了数量比较多的元素,又或者列表中包含的元素都是比较长的字符串时,Redis就会使用链表作为列表键的底层实现。 链表和链表节点的实现 每一个链表节点使用一个adlist.h/listNode来表示: typedef struct listNode { // 前置节点 struct listNode *pre原创 2021-06-03 10:42:28 · 97 阅读 · 1 评论 -
Redis源码初探(1)简单动态字符串SDS
前言 现在面试可太卷了,Redis基本是必问的知识点,为了在秋招中卷过其他人(虽然我未必参加秋招),本菜鸡决定从源码层面再次学习Redis,不过鉴于本菜鸡水平有限,且没有c语言基础,本文不会对源码过于深究,达到能在面试中能吹一波的水平即可。本文以黄建宏《Redis设计与实现》为参考书籍,源码选择黄建宏老师提供的带中文注释的redis3.0源码,github地址:https://github.com/huangz1990/redis-3.0-annotated。虽然redis版本较低,但是对于新手来说足够了,原创 2021-06-02 14:37:41 · 190 阅读 · 2 评论