我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Redis | 第7章 Redis 服务器《Redis设计与实现》

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Redis | 第7章 Redis 服务器《Redis设计与实现》

Redis | 第7章 Redis 服务器《Redis设计与实现》

目录
  • 前言
  • 1. 命令请求的执行过程
    • 1.1 发送命令请求
    • 1.2 读取命令请求
    • 1.3 命令执行器(1):查找命令实现
    • 1.4 命令执行器(2):执行预备操作
    • 1.5 命令执行器(3):调用命令的实现函数
    • 1.6 命令执行器(4):执行后续工作
    • 1.7 将命令回复发送给客户端
    • 1.8 客户端接收并打印命令回复
  • 2. serverCron 函数
  • 3. 初始化服务器
    • 3.1 初始化服务器状态结构
    • 3.2 载入配置选项
    • 3.3 初始化服务器数据结构
    • 3.4 还原数据库状态
    • 3.5 执行事件循环
  • 最后

参考资料:《Redis设计与实现 第二版》;

第二部分为单机数据库的实现,主要由以下模块组成:数据库持久化事件客户端服务器

本篇将介绍 Redis 的服务器端,从服务器接收客户端的命令请求serverCron 函数以及初始化服务器三个角度介绍;


1.1 发送命令请求

  • 用户在客户端键入一个命令请求 { SET KEY VALUE };
  • 客户端将命令请求转换成协议格式 { *3 $3 SET $3 KEY $5 VALUE };
  • 通过连接到服务器的套接字,将协议格式的命令请求发送给服务器;

发送命令请求过程

1.2 读取命令请求

  • 读取套接字中协议格式的命令请求,并将其保存到客户端状态的输入缓冲区里面;
  • 分析协议格式的命令请求,提取参数命令以及参数个数,存进客户端状态的 argvargc 属性;
  • 调用命令执行器,执行客户端指定命令;
    读取命令请求
    解析出的协议格式内容

1.3 命令执行器(1):查找命令实现

  • 根据客户端的 argv[0] 参数,在命令表中查找参数所指定的命令,并将找到的命令 redisCommand 保存到客户端状态的 cmd 属性里;

命令表示例

设置客户端状态的 cmd 指针

  • redisCommand 的主要参数:name(名字),proc(函数指针),arity(命令参数个数),sflags(命令属性标识),flags(sflags的二进制标识),calls(服务器总共执行了多少次这个命令),milliseconds(执行该命令的总耗时);

sflags属性的标识

1.4 命令执行器(2):执行预备操作

  • 检查客户端状态的 cmd 指针是否指向 NULL,是则返回错误;

  • 根据 cmd 指向的 redisCommand 结构的 arity 属性检查参数个数是否正确,不正确则返回错误;

  • 检查客户端是否通过身份验证,未通过的只能执行 AUTH 命令;

  • 若服务器打开了 maxmemory 功能,则在执行命令之前先检查服务器内存占用情况,在需要时回收内存。内存回收失败返回错误;

  • 等等……

1.5 命令执行器(3):调用命令的实现函数

  • 执行以下语句:client->cmd->proc(client)
  • 被调用的命令实现函数执行指定操作,返回相应命令回复;
    执行前客户端状态

执行后客户端状态

1.6 命令执行器(4):执行后续工作

  • 如果服务器开启了慢查询功能,慢查询日志模块会检查是否需要为刚刚执行完的命令请求添加一条新的慢查询日志;
  • 根据执行命令耗费时长更新 redisCommand 结构的 milliseconds 属性,同时将 calls 属性加一;
  • 如果服务器开启了 AOF 持久化功能,会将命令写入 AOF 缓冲期里;
  • 如果有从服务器正则复制当前服务器,服务器会将命令传播给所有从服务器;

1.7 将命令回复发送给客户端

  • 当客户端套接字变为可写状态时,服务器会执行命令回复处理器,将保存在客户端输出缓冲区中的命令回复发送给客户端 {+OK };

  • 当命令发送完毕后,回复处理器会清空客户端状态的输出缓冲区,为处理下一个命令请求最准备;

1.8 客户端接收并打印命令回复

  • 客户端接收协议格式的命令回复后,会将回复转成易读格式;

客户端接收并打印命令回复


  • serverCron 函数默认每隔 100ms 执行一次,负责管理服务器资源与保持服务器自身良好运转;

  • 下面是 serverCron 函数所做操作的介绍:

    • 更新服务器时间缓存:更新服务器状态的 unixtime(秒级) 属性和 mstime(毫秒级) 属性。精度不高,用于:打印日志、更新 LRU 时钟、决定是否执行持久化任务、服务器上线时间等;

    • 更新 LRU 时钟:更新服务器状态的 lruclock(10秒更新一次) 和 lru 属性。前者用于计算键的空转时间,后者保存了对象最后一次被命令访问的时间。空转时间=lruclock-lru;

    • 更新服务器每秒执行命令次数:调用 trackOperationsPerSecond 函数。以抽样计算的方式,估算并记录服务器在最近 1s 处理的命令请求数量;

    • 更新服务器内存峰值函数:更新stat_peak_memory 属性。该属性记录了服务器的内存峰值大小;

    • 处理 SIGTERM 信号:在启动服务器时,Redis 会为服务器进程的 SIGTERM 信号关联处理器 sigtermHandler 函数,信号处理器负责在服务器接到 SIGTERM 信号时,打开服务器状态的 shutdown_asap 标识;

    • 管理客户端资源:调用 clientsCron 函数。如果客户端与服务器之间的连接已经超时,则释放客户端。如果客户端输入缓冲区大小超过一定长度,则释放客户端当前的输入缓冲区,并创建一个默认大小的输入缓冲区;

    • 管理数据库资源:调用 databasesCron 函数,删除过期键,对字典进行收缩操作;

    • 执行被延迟的 BGREWRITEAOF:检查在执行 BGSAVE 命令期间,是否有 BGREWRITEAOF 命令被延迟执行;

    • 检查持久化操作的运行状态:检查 rdb_child_pid(记录 BGSAVE 命令的子进程 ID) 属性与 aof_child_pid(记录执行 BGREWRITEAOF 命令的子进程 ID) 属性。值为 -1 说明服务器没有进行持久化操作;

持久化检查过程

  • 将 AOF 缓冲区中的内容写入 AOF 文件:如果服务开启 AOF 功能,并且 AOF 缓冲区里有待写入数据,则将 AOF 缓冲区中的内容写入 AOF 文件里;

  • 关闭异步客户端:关闭输出缓冲区大小超过限制的客户端;

  • 增加 cronloops 计数器的值:对服务器状态的 cronloops 属性增 1;

3.1 初始化服务器状态结构

  • 即创建使用默认值一个 struct redisServer 结构体;
  • 负责初始化一般属性;
  • 初始化的工作由 redis.c/initServerConfig 函数完成,该函数的主要工作有:
    • 设置服务器的运行 ID;
    • 设置服务器的默认运行频率;
    • 设置服务器的默认配置文件路径;
    • 设置服务器的运行架构;
    • 设置服务器的默认端口号;
    • 设置服务器的默认 RDB 持久化条件和 AOF 持久化条件;
    • 初始化服务器的 LRU 时钟;
    • 创建命令表;

3.2 载入配置选项

  • 载入用户给定的配置参数和配置文件,并对 server 变量相关属性的值进行修改;
  • 指定端口号:redis-server --port 10086
  • 修改数据库数量与 RDB 文件压缩功能:redis-server redis.conf。并且 redis.conf 文件里包含以下内容:
    # 将数据库数量设置为32个
    database 32
    # 关闭 RDB 文件的压缩功能
    rdbcompression no
    

3.3 初始化服务器数据结构

  • 负责初始化数据结构

    • 调用 initServer 函数,初始化下列数据库:
    • 设置数据库:server.clients 链表(存客户端)、server.db 数组(存数据库)、server.pubsub_channels 字典(保存频道订阅信息)、server.lua(用于执行 Lua 脚本的 Lua 环境)、server.slowlog(用于保存慢查询日志)
  • 进行一些重要设置

    • 为服务器设置进程信号处理器;
    • 创建共享对象(如 OK、整数 0-9999);
    • 打开服务器的监听端口,为监听套接字关联连接应答事件处理器,等待服务器正式运行时接受客户端的连接;
    • serverCron 函数创建时间事件;
    • 当 AOF 持久化功能打开时,打开现有 AOF 文件或创建并打开一个新的 AOF 文件,为 AOF 写入做准备;
    • 初始化服务器的后台 I/O 模块,为将来 I/O 操作做准备;

3.4 还原数据库状态

  • 载入 RDB 文件或 AOF 文件(优先),并根据文件记录的内容还原服务器的数据库状态;
  • 成功还原的日志信息:
    [8040] 01 Dec 20:12:41.758 * DB loaded from disk: 0.001 seconds

3.5 执行事件循环

  • 在打印下列日志后执行事件循环(loop函数);
    [8040] 01 Dec 20:12:41.758 * The server is now ready to accept connections on port 6379


新人制作,如有错误,欢迎指出,感激不尽!
欢迎关注公众号,会分享一些更日常的东西!
如需转载,请标注出处!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Redis | 第7章 Redis 服务器《Redis设计与实现》

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Redis | 第7章 Redis 服务器《Redis设计与实现》

目录前言1. 命令请求的执行过程1.1 发送命令请求1.2 读取命令请求1.3 命令执行器(1):查找命令实现1.4 命令执行器(2):执行预备操作1.5 命令执行器(3):调用命令的实现函数1.6 命令执行器(4):执行后续工作1.7 将命令回复发送给客户端
Redis | 第7章 Redis 服务器《Redis设计与实现》
2022-04-27

Redis | 第11章 服务器的复制《Redis设计与实现》

目录前言1. 旧版复制功能的实现1.1 同步与命令传播1.2 旧版复制功能的缺陷2. 新版复制功能的实现2.1 部分重同步的实现原理3. PSYNC 命令的实现4. 复制的详细步骤4.1 设置主服务器的地址和端口4.2 建立套接字连接4.3 发送 PING 命
Redis | 第11章 服务器的复制《Redis设计与实现》
2020-11-24

Redis | 第3章 对象《Redis设计与实现》

目录前言1. Redis对象概述1.1 对象的定义2. 字符串对象3. 列表对象3.1 quicklist 快速链表4. 哈希对象5. 集合对象6. 有序集合对象7. Redis对象的特点7.1 类型检查与命令多态7.2 内存回收7.3 对象共享7.4 对象的
Redis | 第3章 对象《Redis设计与实现》
2016-10-04

Redis | 第4章 Redis中的数据库《Redis设计与实现》

目录前言1. Redis中的数据库2. 数据库的键空间3. 键的生成时间与过期时间4. Redis中的过期键删除策略5. AOF、RDB和复制功能对过期键的处理5.1 生成 RDB 文件5.2 载入 RDB 文件5.3 AOF 文件写入5.4 AOF 重写5.
Redis | 第4章 Redis中的数据库《Redis设计与实现》
2020-04-14

Redis | 第8章 发布订阅与事务《Redis设计与实现》

目录前言《Redis常用命令及示例总结(API)》:https://www.cnblogs.com/dlhjw/p/15639773.html1. 发布订阅1.1 频道的订阅与退订1.2 模式的订阅与退订1.3 发送消息1.4 查看订阅消息2. 事务2.1 事
Redis | 第8章 发布订阅与事务《Redis设计与实现》
2016-06-20

Redis | 第12章 Sentinel 哨兵模式《Redis设计与实现》

目录前言1. 启动并初始化 Sentinel2. Sentinel 与服务器间的默认通信2.1 获取主服务器信息2.2 获取从服务器信息2.3 向主服务器和从服务器发送信息3. 接受来自主服务器和从服务器的频道信息3.1 更新 Sentinel 字典3.2 创
Redis | 第12章 Sentinel 哨兵模式《Redis设计与实现》
2017-09-21

Redis | 第6章 事件与客户端《Redis设计与实现》

目录前言1. 事件1.1 文件事件1.1.1 I/O 多路复用程序的实现1.1.2 事件类型与 API1.1.3 文件事件的处理器1.2 时间事件1.2.1 API1.2.2 serverCron 函数1.3 事件的调度与执行2. 客户端2.1 客户端属性2.
Redis | 第6章 事件与客户端《Redis设计与实现》
2014-08-19

Redis | 第9章 Lua 脚本与排序《Redis设计与实现》

目录前言1. Lua 脚本1.1 Redis 创建并修改 Lua 环境的步骤1.2 Lua 环境协作组件1.3 EVAL 命令的实现1.4 EVALSHA 命令的实现1.5 脚本管理命令的实现1.6 脚本复制1.6.1 EVAL、SCRIPT FLUSH、SC
Redis | 第9章 Lua 脚本与排序《Redis设计与实现》
2017-01-01

Redis | 第5章 Redis 中的持久化技术《Redis设计与实现》

目录前言1. RDB 持久化1.1 RDB 文件的创建与载入1.2 自动间隔性保存1.2.1 设置保存条件1.2.2 dirty 计数器和 lastsave 属性1.2.3 检查保存条件是否满足1.3 RDB 文件1.3.1 RDB 的文件结构1.3.2 da
Redis | 第5章 Redis 中的持久化技术《Redis设计与实现》
2018-11-05

Redis | 第10章 二进制数组、慢查询日志和监视器《Redis设计与实现》

目录前言1. 二进制位数组1.1 位数组的表示1.2 GETBIT 命令的实现1.3 SETBIT 命令的实现1.4 BITECOUNT 命令的实现1.5 BITOP 命令的实现2. 慢查询日志2.1 慢查询记录的保存2.2 慢查询日志的阅览与删除2.3 添加
Redis | 第10章 二进制数组、慢查询日志和监视器《Redis设计与实现》
2019-06-28

《Redis设计与实现》

由浅到深,逐步讲解Redis本书主要分为四大部分。第一部分"数据结构与对象": 介绍了Redis中的各种对象及其数据结构,并说明这些数据结构如何影响对象的功能和性能。第二部分"单机数据库的实现": 对Redis实现单机数据库的方法进行了介绍,包括数据库、RDB
《Redis设计与实现》
2020-06-17

Redis | 第一部分:数据结构与对象 上篇《Redis设计与实现》

目录前言1. 简单动态字符串1.1 SDS的定义1.2 空间预分配与惰性空间释放1.3 SDS的API2. 链表2.1 链表与节点的定义2.2 链表的API3. 字典3.1 哈希表与哈希节点3.2 字典3.3 哈希算法3.4 解决键冲突3.5 rehash3.
Redis | 第一部分:数据结构与对象 上篇《Redis设计与实现》
2016-08-18

Redis | 第一部分:数据结构与对象 中篇《Redis设计与实现》

目录前言1. 跳跃表1.1 跳跃表与其节点的定义1.2 跳跃表的API2. 整数集合2.1 整数集合的实现2.2 整数集合的类型升级2.3 整数集合的API3. 压缩列表3.1 压缩列表的结构3.2 压缩列表节点的定义3.3 连锁更新3.4 压缩列表的API最
Redis | 第一部分:数据结构与对象 中篇《Redis设计与实现》
2021-12-06

怎么设计与实现Redis

本篇内容主要讲解“怎么设计与实现Redis”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么设计与实现Redis”吧!Redis的设计与实现其实 Redis 主要是通过三个方面来满足这样高效吞吐
2023-06-16

Redis设计与实现2.1:主从复制

主从复制这是《Redis设计与实现》系列的文章,系列导航:Redis设计与实现笔记SLAVEOF新旧复制功能旧版复制功能旧版复制功能的实现为 同步 和 命令传播:当刚连上Master时,要做一次全同步:sequenceDiagramparticipant Sl
Redis设计与实现2.1:主从复制
2021-05-11

Redis压缩列表的设计与实现

目录1. 哈希表(Hash)使用条编程网件2. 列表(List)使用条件3. 有序集合(Sorted Set)使用条件优点与缺点示例及实际应用底层实现1. 整体结构2. 节点结构3. 编码方式4. 操作插入删除查找扩容机制1. 扩容触发条件
Redis压缩列表的设计与实现
2024-08-25

Redis过期时间的设计与实现代码

目录1. 设置过期时间示例:2. 过期键的存储结构3. 设置过期时间4. 删除过期键的策略5. 检查并删除过期键6. 获取过期时间总结定期删除activeExpireCycle函数详细解析关键步骤解析1. 初始化变量2. 确定时间限制3.
Redis过期时间的设计与实现代码
2024-08-25

编程热搜

目录