描述
开 本: 16开纸 张: 胶版纸包 装: 平装-胶订是否套装: 否国际标准书号ISBN: 9787121415487丛书名: 深入理解精品
新版本:基于Redis 6.0.9,分析了Redis特性,如Redis 6的ACL、Tracking等机制。
重实践:本书在对应知识点的基础上提供了详细的应用示例,帮助读者循序渐进、由浅到深地学习和理解Redis特性。
易掌握:本书总结了Redis各个核心功能的实现原理,并以适量图文,对Redis源码及其实现原理进行详细分析,向读者展示Redis核心功能的设计思想和实现流程。
可扩展:本书由Redis延展出了两方面内容:一是Redis中使用的UNIX机制,二是如何通过Redis实现一个分布式系统,主要是Sentinel、Cluster机制的实现原理。
本书深入地分析了Redis核心功能的内部机制与实现方式,大部分内容源自对Redis源码的分析,并从中总结出实现原理。通过阅读本书,读者可以快速、轻松地了解Redis的内部运行机制。 本书首先介绍了Redis常用的数据类型的编码格式,包括字符串、列表、散列、集合、有序集合,这是Redis存储数据的基础。接着分析了Redis的事件机制,剖析了Redis事件驱动的实现原理,通过这部分内容,读者可以了解一个远程服务程序的整体架构。本书还分析了Redis持久化、主从复制、Sentinel机制、Cluster机制的实现原理,这部分内容是Redis的核心功能。在这部分内容中,本书也会延伸分析Redis中使用的UNIX机制,如UNIX网络编程、进程通信、线程同步等,并通过Redis源码展示这些UNIX机制的使用方式。 本书后介绍了Redis的高级特性,包括事务、非阻塞删除、Lua脚本、Module模块、Stream消息流,以及Redis 6提供的ACL访问控制列表、Tracking机制等,这部分内容不仅分析内部实现,还提供了详细的使用案例,帮助读者循序渐进地了解这些特性。
目 录
第1部分 数据结构与编码
第1章 字符串
1.1 redisObject
1.2 sds
1.2.1 定义
1.2.2 操作分析
1.2.3 编码
第2章 列表
2.1 ziplist
2.1.1 定义
2.1.2 字节序
2.1.3 操作分析
2.1.4 级联更新
2.2 quicklist
2.2.1 定义
2.2.2 操作分析
2.2.3 编码
第3章 散列
3.1 字典
3.1.1 定义
3.1.2 操作分析
3.1.3 扩容
3.1.4 缩容
3.1.5 编码
3.2 数据库
第4章 集合
4.1 无序集合
4.1.1 定义
4.1.2 操作分析
4.1.3 编码
4.2 有序集合
4.2.1 定义
4.2.2 操作分析
4.2.3 编码
第2部分 事件机制与命令执行
第5章 Redis启动过程
5.1 服务器定义
5.2 main函数
5.3 Redis初始化过程
第6章 事件机制
6.1 Redis事件机制概述
6.2 Redis启动时创建的事件
6.3 事件循环器的运行
第7章 epoll与网络通信
7.1 I/O复用模型
7.2 epoll网络编程
7.3 Redis网络通信启动过程
7.3.1 Redis网络服务
7.3.2 Redis中的epoll
第8章 客户端
8.1 定义
8.2 创建客户端
8.3 关闭客户端
8.4 客户端配置
第9章 Redis命令执行过程
9.1 RESP协议
9.2 解析请求
9.3 返回响应
9.4 执行命令
第10章 网络I/O线程
10.1 线程概述
10.2 互斥量概述
10.3 初始化I/O线程
10.4 解析请求
10.5 I/O线程主逻辑
10.6 返回响应
10.7 I/O线程状态切换
第3部分 持久化与复制
第11章 RDB
11.1 RDB定时逻辑
11.2 RDB持久化过程
11.2.1 fork子进程
11.2.2 生成RDB文件
11.2.3 写入RDB数据
11.2.4 父进程收尾
11.3 RDB文件加载过程
11.4 RDB文件分析示例
11.5 RDB配置
11.6 UNIX写时复制机制
11.7 UNIX I/O与缓存
11.7.1 内核缓冲区
11.7.2 I/O缓存区
11.7.3 sync与fdatasync
第12章 AOF
12.1 AOF定时逻辑
12.2 AOF持久化过程
12.2.1 命令传播
12.2.2 刷新AOF缓冲区
12.2.3 同步磁盘
12.3 AOF重写过程
12.3.1 fork子进程
12.3.2 子进程处理
12.3.3 父进程收尾
12.4 AOF文件加载过程
12.5 AOF文件分析示例
12.6 AOF配置
第13章 主从复制
13.1 流程概述
13.2 主从握手流程
13.2.1 处理REPLICAOF命令
13.2.2 主从连接
13.2.3 握手流程
13.3 从节点同步流程
13.3.1 发送PSYNC命令
13.3.2 部分同步
13.3.3 全量同步
13.4 主节点同步流程
13.4.1 处理PSYNC命令
13.4.2 全量同步
13.4.3 部分同步
13.4.4 部分同步的实现细节
13.5 PSYNC2
13.5.1 从节点重启
13.5.2 Cluster故障转移
13.6 主从复制流程
13.7 定时逻辑
13.8 主从复制配置
第4部分 分布式架构
第14章 Raft算法
14.1 分布式一致性的难点
14.2 CAP理论
14.3 Raft算法的设计
14.3.1 领导选举
14.3.2 日志复制
14.3.3 安全性
14.4 Redis中的Raft算法
第15章 Redis Sentinel
15.1 Redis Sentinel的应用示例
15.2 Redis Sentinel的实现原理
15.2.1 定义
15.2.2 Sentinel节点启动
15.2.3 Sentinel机制的主逻辑
15.2.4 Sentinel节点建立网络连接
15.2.5 Sentinel机制的定时消息
15.3 Redis Sentinel的故障转移
15.3.1 主观下线
15.3.2 客观下线
15.3.3 开始故障转移
15.3.4 选举leader节点
15.3.5 故障转移状态机
15.4 客户端交互
第16章 Redis Cluster
16.1 Redis Cluster的应用示例
16.1.1 搭建Redis Cluster集群
16.1.2 客户端重定向
16.1.3 槽位迁移案例
16.2 Redis Cluster槽位管理
16.2.1 定义
16.2.2 重定向的实现
16.2.3 槽位迁移的实现
16.3 Redis Cluster启动过程
16.3.1 节点启动
16.3.2 节点握手
16.3.3 指派槽位
16.3.4 建立主从关系
16.4 Redis Cluster节点通信
16.4.1 Gossip算法
16.4.2 消息定义
16.4.3 建立连接
16.4.4 握手过程
16.4.5 定时消息
16.5 Redis Cluster的故障转移
16.5.1 节点下线
16.5.2 选举过程
16.5.3 从节点晋升
16.5.4 更新集群信息
16.5.5 建立主从关系
第5部分 高级特性
第17章 事务
17.1 事务的应用示例
17.2 事务的实现原理
17.2.1 WATCH命令的实现
17.2.2 MULTI、EXEC命令的实现
第18章 非阻塞删除
18.1 UNLINK命令的实现原理
18.2 后台线程
18.2.1 条件变量
18.2.2 后台线程的实现
第19章 内存管理
19.1 动态内存分配器
19.1.1 内存分配器概述
19.1.2 Jemalloc设计概述
19.1.3 碎片整理机制
19.2 数据过期机制
19.2.1 定时删除
19.2.2 惰性删除
19.3 数据淘汰机制
19.3.1 LRU时间戳
19.3.2 LFU计数
19.3.3 数据淘汰算法
第20章 Redis Stream
20.1 Redis Stream的应用示例
20.1.1 添加、读取消息
20.1.2 消费组
20.1.3 ACK确认
20.1.4 删除消息
20.2 Stream的实现原理
20.2.1 listpack结构
20.2.2 Rax结构
20.2.3 Stream结构
20.2.4 Stream持久化与复制
第21章 访问控制列表ACL
21.1 ACL的应用示例
21.1.1 创建用户
21.1.2 可执行命令授权
21.1.3 可访问键授权
21.1.4 Pub/Sub频道授权
21.2 ACL的实现原理
21.2.1 定义
21.2.2 初始化ACL环境
21.2.3 用户规则设置
21.2.4 用户权限检查
第22章 Redis Tracking
22.1 Redis Tracking的应用示例
22.1.1 基本应用
22.1.2 广播模式
22.1.3 OPTIN、OPTOUT、NOLOOP
22.1.4 转发模式
22.2 Redis Tracking的实现原理
22.2.1 RESP3协议
22.2.2 开启Redis Tracking
22.2.3 记录查询键
22.2.4 非广播模式下发送失效消息
22.2.5 广播模式下发送失效消息
22.2.6 清除记录键
第23章 Lua脚本
23.1 Lua脚本的应用示例
23.1.1 使用EVAL命令
23.1.2 redis.call函数
23.1.3 类型转换
23.1.4 使用Lua实现数据类型
23.1.5 脚本超时
23.2 Lua脚本的实现原理
23.2.1 Lua与C语言交互
23.2.2 Redis中的Lua
第24章 Redis Module
24.1 Module的应用示例
24.1.1 使用Module实现数据类型
24.1.2 Module API
24.1.3 Module的特性
24.2 Module的实现原理
24.2.1 C语言动态库
24.2.2 定义
24.2.3 初始化Module的执行环境
24.2.4 加载Module
24.2.5 创建Module命令
24.2.6 内存自动管理
24.2.7 调用Redis命令
24.2.8 自定义数据类型
前 言
Redis是开源的key-value存储系统,可作为数据库、缓存、消息组件。Redis的作者是Salvatore Sanfilippo(网名为antirez),他在2009年开发完成并开源了Redis。Redis由于性能极高、功能强大,迅速在业界流行,现已成为高并发系统中常用的组件之一。
Redis提供了多种类型的数据结构,如字符串(String)、散列(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set)等。Redis还是分布式系统,主从集群可以实现数据热备份,哨兵(Sentinel)机制可以保证主从集群高可用,Cluster集群则提供了水平扩展的能力。Redis还提供了持久化、Lua脚本、Module模块、Stream消息流、Tracking机制等一系统强大功能,适用于各种业务场景。
写作目的
虽然笔者主要使用Java语言开发程序,却一直希望从源码层面深入分析一个C语言实现的分布式系统。C语言可以说是接近低级语言的开发语言,分析C语言程序,可以让我们更深入地理解操作系统的底层知识。于是,笔者学习了Redis源码,并编写了本书。
为什么选择Redis呢?因为Redis是一个典型的“小而美”的程序。Redis实现简单,源码非常优雅简洁,阅读起来并不吃力,而且Redis功能齐全,涵盖了数据存储、分布式、消息流等众多特性,非常值得深入学习。
通过编写本书,笔者对Redis、UNIX编程、分布式系统、存储系统都有了更深入的理解,再学习其他相关的系统(如MySQL、Nginx等),就可以举一反三、触类旁通。希望本书也可以帮助读者百尺竿头,更进一步。
本书特点
本书深入分析了Redis的实现原理,所以并不是Redis的入门书。为了尽量降低阅读难度,本书总结了Redis各个核心功能的实现原理,提取了Redis核心代码(本书会尽量避免堆积代码),并以适量图文,对Redis源码及其实现原理进行详细分析,向读者展示Redis核心功能的设计思想和实现流程。
虽然本书的大部分内容基于对Redis源码的分析,但是并不复杂,即使读者只是简单了解C语言的基础语法,也可以轻松读懂。
另外,本书结合Redis目前的版本6.0.9,分析了Redis特性,如Redis 6的ACL、Tracking等机制。为了照顾对Redis特性不熟悉的读者,这部分内容提供了详细的应用示例,帮助读者循序渐进、由浅到深地学习和理解Redis特性。
本书也不局限于Redis,而是由Redis延展出了两方面内容:
(1)Redis中使用的UNIX机制,包括UNIX网络编程、线程同步等内容,本书会通过源码展示Redis如何使用这些UNIX机制。
(2)如何通过Redis实现一个分布式系统,主要是Sentinel、Cluster机制的实现原理。
本书使用的源码版本是Redis 6.0.9,本书提供的Redis操作案例,如无特殊说明,也是在Redis 6.0.9版本上执行的操作实例。
本书结构
第1部分分析了Redis的字符串、列表、散列、集合这几种数据类型的编码格式。编码格式,即数据的存储格式,对于数据库,数据的存储格式至关重要,如关系型数据库的行式存储和列式存储。而Redis作为内存数据库,对于数据编码的总体设计思想是:限度地“以时间换空间”,从而限度地节省内存。这部分内容详细分析了Redis对内存的使用如何达到“锱铢必较”的程度。
第2部分分析了Redis的核心流程,包括Redis事件机制与命令执行过程。Redis利用I/O复用模型,实现了自己的事件循环机制,而Redis底层由该事件机制驱动运行(很多远程服务程序都使用类似的架构,如Nginx、MySQL等)。Redis事件机制设计优雅、实现简单,并且性能卓越,可以说是“化繁为简”。
第3部分分析了Redis持久化与复制机制。虽然Redis是内存数据库,但仍然限度地保证了数据的可靠性。不管是文件持久化,还是从节点复制,核心思想都是一样的:通过将数据复制到不同备份中,从而保持数据安全。这部分内容分析了RDB、AOF持久化机制,以及主从节点复制流程等内容,向读者展示了Redis数据是如何“不胫而走”的。
第4部分分析了Redis分布式架构。这部分内容从流行的分布式算法Raft出发,分析了Sentienl如何监控节点,Cluster集群如何实现数据分片,如何支持动态新增、删除集群节点,以及它们的“拿手好戏”——故障转移。分布式系统常常让笔者想到一个有趣的词—铁索连舟(将集群节点想象为“舟”,将节点之间的网络连接想象为“索”)。
第5部分分析了Redis中的高级特性,包括Redis事务、非阻塞删除、ACL访问控制列表、Tracking机制、Lua脚本、Module模块、Stream消息流等内容。Redis为各种高性能、高可用场景提供了非常全面的支持,可以说是“包罗万象”。
本书不是Redis工具书,并没有将Redis的全部功能都分析一遍,很多功能也非常有趣实用,但本书不会深入讨论,如Bitmaps、Hyperloglog、Geo、Pub/Sub等,读者可以自行深入学习。
表达约定
(1)本书会按顺序在源码函数(或代码块)中添加标志,并在源码展示结束后,按标志对源码进行说明,例如:
robj *tryObjectEncoding(robj *o) {
…
// [1]
if (o->refcount > 1) return o;
…
}
【1】该redisObject被多处引用,不再进行编码操作,以免影响他处的使用,直接退出函数。
这样可以保证源码展示的整洁,也方便读者阅读源码后,再结合书中说明,深入理解。
另外,也方便读者在阅读本书时,结合阅读完整的Redis源码。
在源码中使用“…”代表此处省略了代码(有些地方省略了日志等辅助的代码,可能不添加“…”标志)。
(2)如果源码中函数太长,为了版面整洁,本书将其划分为多个代码段,并使用“// more”标志该函数后续还有其他代码段,请读者留意该标志。
勘误和支持
在阅读本书的过程中有任何问题或者建议,可以关注公众号(binecy)与笔者交流。笔者十分感谢并重视您的反馈,会对您提出的问题、建议进行梳理与反馈,并在本书后续版本中及时做出勘误与更新。
致谢
感谢写作过程中身边朋友的支持,他们给予笔者很多的力量。
感谢Redis的作者antirez,优秀的Redis离不开antirez的辛勤付出,向他致敬。
感谢电子工业出版社博文视点的陈晓猛编辑,陈编辑专业的写作指导和出版组织工作,使得本书得以顺利出版。
感谢计算机行业的内容创作者,他们的各种分享、博客文章及图书都在积极推动行业的发展,也为本书的编写提供了灵感和参考。
梁国斌
评论
还没有评论。