书海网短评:
Redis是互联网技术架构在存储系统中使用得广泛的中间件,也是中高级后端工程师技术面试中面试官喜欢问的工程技能之一,特别是那些优秀的互联网公司,通常要求面试者不仅仅掌握Redis基础用法,还要理解Redis内部实现的细节原理
Redis是互联网技术架构在存储系统中使用得广泛的中间件,也是中高级后端工程师技术面试中面试官喜欢问的工程技能之一,特别是那些优秀的互联网公司,通常要求面试者不仅仅掌握Redis基础用法,还要理解Redis内部实现的细节原理。《Redis 深度历险:核心原理与应用实践》作者老钱在使用Redis上积累了丰富的实战经验,可以帮助更多后端开发者更快、更深入地掌握Redis技能,还能帮助读者更轻松地通过技术面试,进入心仪企业。
Redis是互联网技术架构在存储系统中使用得为广泛的中间件,也是中高级后端工程师技术面试中面试官喜欢问的工程技能之一,特别是那些优秀的互联网公司,通常要求面试者不仅仅掌握Redis基础用法,还要理解Redis内部实现的细节原理。《Redis深度历险:核心原理与应用实践》作者老钱在使用Redis上积累了丰富的实战经验,希望帮助更多后端开发者更快、更深入地掌握Redis技能。
《Redis深度历险:核心原理与应用实践》分为基础和应用篇、原理篇、集群篇、拓展篇、源码篇共5大块内容。基础和应用篇讲解对读者来说有价值的内容,可以直接应用到实际工作中;原理篇、集群篇让开发者透过简单的技术表面看到精致的底层世界;拓展篇帮助读者拓展技术视野和夯实基础,便于进阶学习;源码篇让高阶的读者能够读懂源码,掌握核心技术实力。
《Redis深度历险:核心原理与应用实践》适合以下人群阅读:有Redis基础,渴望深度掌握Redis技术原理的中高级后端开发者;渴望成功进入大型互联网企业研发部的中高级后端开发者;需要支撑公司Redis中间件运维工作的初中级运维工程师;对Redis中间件技术好奇的中高级前端技术研究者。
钱文品(老钱)
互联网分布式高并发技术领域奋战十年的老兵,目前担任掌阅服务端技术专家。
熟练使用Java、Python、Golang等多种计算机语言,是开源项目爱好者。
开发过多人在线RPG游戏,制作过大型网站,写过消息推送系统和MySQL中间件。
运营公众号“码洞”(codehole)。
Redis本身的设计颇具特色,作为数据库从业者,我从中获益匪浅。《Redis 深度历险:核心原理与应用实践》是我见过的内容相对全面、讲解极为生动的Redis实践指导书,其中有大量直观的插图和实例。区别于市面上大量较为浅显介绍Redis内容的作品,《Redis 深度历险:核心原理与应用实践》对Redis原理的介绍深入浅出、循序渐进,章节安排条理清晰,非常适合中高级后端开发者作为参考书,入门学习和进阶学习Redis应用。
——蚂蚁金服OceanBase数据库高级技术专家席华峰
Redis作为互联网存储系统中使用极为广泛的中间件,由于其纯内存访问的特性,有着极高的存取性能和丰富的分布式数据结构。《Redis 深度历险:核心原理与应用实践》由浅入深,从Redis的基础使用出发,结合实际项目中遇到的诸多应用场景,最后详细讲解集群环境,图文并茂地对Redis的特性做了全面解析。强烈建议想要入门学习和进阶学习Redis、渴望通过Redis来解决实际问题的小伙伴们认真阅读。
——掌阅用户中心技术团队Leader牛新龙
第1篇基础和应用篇/1
1.1授人以鱼不如授人以渔/1
1.1.1由Redis面试想到的/1
1.1.2《Redis 深度历险:核心原理与应用实践》的内容范围/2
1.1.3Redis可以做什么/3
1.1.4小结/3
1.1.5扩展阅读/4
1.2万丈高楼平地起——Redis基础数据结构/4
1.2.1Redis的安装/5
1.2.25种基础数据结构/6
1.2.3容器型数据结构的通用规则/17
1.2.4过期时间/17
1.2.5思考&作业/17
1.3千帆竞发——分布式锁/18
1.3.1分布式锁的奥义/18
1.3.2超时问题/20
1.3.3可重入性/21
1.3.4思考&作业/24
1.4缓兵之计——延时队列/24
1.4.1异步消息队列/24
1.4.2队列空了怎么办/26
1.4.3阻塞读/26
1.4.4空闲连接自动断开/26
1.4.5锁冲突处理/27
1.4.6延时队列的实现/27
1.4.7进一步优化/30
1.4.8思考&作业/31
1.5节衣缩食——位图/31
1.5.1基本用法/31
1.5.2统计和查找/34
1.5.3魔术指令bitfield/35
1.5.4思考&作业/38
1.6四两拨千斤——HyperLogLog/38
1.6.1使用方法/39
1.6.2pfadd中的pf是什么意思/41
1.6.3pfmerge适合的场合/42
1.6.4注意事项/42
1.6.5HyperLogLog实现原理/42
1.6.6pf的内存占用为什么是12KB/49
1.6.7思考&作业/50
1.7层峦叠嶂——布隆过滤器/50
1.7.1布隆过滤器是什么/51
1.7.2Redis中的布隆过滤器/51
1.7.3布隆过滤器的基本用法/52
1.7.4注意事项/59
1.7.5布隆过滤器的原理/60
1.7.6空间占用估计/61
1.7.7实际元素超出时,误判率会怎样变化/62
1.7.8用不上Redis4.0怎么办/63
1.7.9布隆过滤器的其他应用/63
1.8断尾求生——简单限流/64
1.8.1如何使用Redis来实现简单限流策略/64
1.8.2解决方案/65
1.8.3小结/67
1.9一毛不拔——漏斗限流/68
1.9.1Redis-Cell/71
1.9.2思考&作业/72
1.9.3扩展阅读:Redis-Cell作者介绍/72
1.10近水楼台——GeoHash/73
1.10.1用数据库来算附近的人/73
1.10.2GeoHash算法/74
1.10.3Geo指令的基本用法/75
1.10.4注意事项/78
1.11大海捞针——scan/79
1.11.1scan基本用法/80
1.11.2字典的结构/82
1.11.3scan遍历顺序/82
1.11.4字典扩容/83
1.11.5对比扩容、缩容前后的遍历顺序/84
1.11.6渐进式rehash/85
1.11.7更多的scan指令/85
1.11.8大key扫描/85
第2篇原理篇/87
2.1鞭辟入里——线程IO模型/87
2.1.1非阻塞IO/87
2.1.2事件轮询(多路复用)/88
2.1.3指令队列/90
2.1.4响应队列/90
2.1.5定时任务/90
2.1.6扩展阅读/90
2.2交头接耳——通信协议/90
2.2.1RESP/91
2.2.2客户端→服务器/92
2.2.3服务器→客户端/92
2.2.4小结/95
2.2.5扩展阅读/95
2.3未雨绸缪——持久化/95
2.3.1快照原理/96
2.3.2fork(多进程)/96
2.3.3AOF原理/97
2.3.4AOF重写/98
2.3.5fsync/98
2.3.6运维/98
2.3.7Redis4.0混合持久化/99
2.3.8思考&作业/100
2.4雷厉风行——管道/100
2.4.1Redis的消息交互/100
2.4.2管道压力测试/101
2.4.3深入理解管道本质/102
2.4.4小结/104
2.5同舟共济——事务/104
2.5.1Redis事务的基本用法/104
2.5.2原子性/105
2.5.3discard(丢弃)/106
2.5.4优化/106
2.5.5watch/107
2.5.6注意事项/108
2.5.7思考&作业/110
2.6小道消息——PubSub/110
2.6.1消息多播/110
2.6.2PubSub/111
2.6.3模式订阅/113
2.6.4消息结构/114
2.6.5PubSub的缺点/115
2.6.6补充/115
2.7开源节流——小对象压缩/115
2.7.132bitVS64bit/116
2.7.2小对象压缩存储(ziplist)/116
2.7.3内存回收机制/120
2.7.4内存分配算法/120
第3篇集群篇/122
3.1有备无患——主从同步/122
3.1.1CAP原理/122
3.1.2最终一致/123
3.1.3主从同步与从从同步/123
3.1.4增量同步/124
3.1.5快照同步/124
3.1.6增加从节点/125
3.1.7无盘复制/125
3.1.8wait指令/125
3.1.9小结/126
3.2李代桃僵——Sentinel/126
3.2.1消息丢失/128
3.2.2Sentinel基本用法/128
3.2.3思考&作业/129
3.3分而治之——Codis/130
3.3.1Codis分片原理/131
3.3.2不同的Codis实例之间槽位关系如何同步/132
3.3.3扩容/132
3.3.4自动均衡/133
3.3.5Codis的代价/133
3.3.6Codis的优点/134
3.3.7mget指令的操作过程/134
3.3.8架构变迁/135
3.3.9Codis的尴尬/135
3.3.10Codis的后台管理/136
3.3.11思考&作业/136
3.4众志成城——Cluster/137
3.4.1槽位定位算法/138
3.4.2跳转/138
3.4.3迁移/138
3.4.4容错/140
3.4.5网络抖动/140
3.4.6可能下线(PFAIL)与确定下线(Fail)/141
3.4.7Cluster基本用法/141
3.4.8槽位迁移感知/142
3.4.9集群变更感知/143
3.4.10思考&作业/143
第4篇拓展篇/144
4.1耳听八方——Stream/144
4.1.1消息ID/145
4.1.2消息内容/145
4.1.3增删改查/145
4.1.4独立消费/147
4.1.5创建消费组/148
4.1.6消费/150
4.1.7Stream消息太多怎么办/152
4.1.8消息如果忘记ack会怎样/153
4.1.9PEL如何避免消息丢失/153
4.1.10Stream的高可用/153
4.1.11分区Partition/154
4.1.12小结/154
4.2无所不知——Info指令/154
4.2.1Redis每秒执行多少次指令/155
4.2.2Redis连接了多少客户端/156
4.2.3Redis内存占用多大/156
4.2.4复制积压缓冲区多大/157
4.2.5思考&作业/158
4.3拾遗补漏——再谈分布式锁/158
4.3.1Redlock算法/158
4.3.2Redlock使用场景/159
4.3.3扩展阅读:redlock-py的作者/160
4.4朝生暮死——过期策略/160
4.4.1过期的key集合/160
4.4.2定时扫描策略/160
4.4.3从节点的过期策略/161
4.5优胜劣汰——LRU/162
4.5.1LRU算法/163
4.5.2近似LRU算法/164
4.5.3思考&作业/165
4.6平波缓进——懒惰删除/165
4.6.1Redis为什么使用懒惰删除/165
4.6.2flush/166
4.6.3异步队列/166
4.6.4AOFSync也很慢/166
4.6.5更多异步删除点/166
4.7妙手仁心——优雅地使用Jedis/167
4.7.1重试/171
4.7.2思考&作业/172
4.8居安思危——保护Redis/172
4.8.1指令安全/172
4.8.2端口安全/173
4.8.3Lua脚本安全/174
4.8.4SSL代理/174
4.8.5小结/174
4.9隔墙有耳——Redis安全通信/175
4.9.1spiped原理/176
4.9.2spiped使用入门/176
4.9.3思考&作业/179
第5篇源码篇/180
5.1丝分缕析——探索“字符串”内部/180
5.1.1embstrVSraw/181
5.1.2扩容策略/184
5.1.3思考&作业/184
5.2循序渐进——探索“字典”内部/184
5.2.1dict内部结构/184
5.2.2渐进式rehash/186
5.2.3查找过程/187
5.2.4hash函数/188
5.2.5hash攻击/188
5.2.6扩容条件/188
5.2.7缩容条件/189
5.2.8set的结构/189
5.2.9思考&作业/189
5.3挨肩迭背——探索“压缩列表”内部/190
5.3.1增加元素/192
5.3.2级联更新/192
5.3.3intset小整数集合/194
5.3.4思考&作业/195
5.4风驰电掣——探索“快速列表”内部/195
5.4.1每个ziplist存多少元素/197
5.4.2压缩深度/198
5.5凌波微步——探索“跳跃列表”内部/198
5.5.1基本结构/199
5.5.2查找过程/199
5.5.3随机层数/200
5.5.4插入过程/201
5.5.5删除过程/202
5.5.6更新过程/203
5.5.7如果score值都一样呢/203
5.5.8元素排名是怎么算出来的/203
5.5.9思考&作业/204
5.5.10题外话/204
5.6破旧立新——探索“紧凑列表”内部/205
5.6.1级联更新/207
5.6.2取代ziplist尚需时日/207
5.6.3思考&作业/207
5.7金枝玉叶——探索“基数树”内部/207
5.7.1应用/208
5.7.2结构/210
5.7.3思考&作业/213
5.8精益求精——LFUVSLRU/213
5.8.1Redis对象的热度/213
5.8.2LRU模式/213
5.8.3LFU模式/214
5.8.4为什么Redis要缓存系统时间戳/217
5.8.5Redis为什么在获取lruclock时使用原子操作/217
5.8.6如何打开LFU模式/218
5.8.7思考&作业/218
5.9如履薄冰——懒惰删除的巨大牺牲/218
5.9.1懒惰删除的最初实现不是异步线程/219
5.9.2异步线程方案其实也相当复杂/219
5.9.3异步删除的实现/221
5.9.4队列安全/224
5.9.5思考&作业/225
5.10跋山涉水——深入字典遍历/225
5.10.1一边遍历一边修改/226
5.10.2重复遍历的难题/227
5.10.3迭代器的结构/227
5.10.4迭代过程/229
5.10.5迭代器的选择/231
5.10.6思考&作业/232
攀登技术之山
为什么我要尝试写作技术类书籍
我毕业至今已经十年了。这十年的技术生涯犹如艰辛的登山过程,中间虽有停停歇歇,但整体而言,我始终在向上努力攀登。
我是个对新技术有着强烈好奇心的人,曾经学习了很多种计算机语言,有些语言与我的工作并没有太大关系,但这不妨碍我花费时间去钻研它们。相比身边很多技术高手,我本人并不算一个特别有天赋的人,所以爬山的过程比较缓慢。
2018年年中,我偶然回顾了一下自己的技术生涯,感觉总算有所小成,登山达到了一定高度,但与此同时,我也意识到技术日新月异,顶峰遥不可及,总会有我爬不动的那一天,那么在此之前我能做些什么呢?
闲暇之时,我开始尝试写作技术类书籍,希望将自己多年来的所学所想记录下来,分享给山下的学弟学妹们,希望他们阅读之后,可以在登山时轻松一些。等到他们未来达到我所处的高度时,也能偶而记起我这样一个前辈曾经写过一点东西对他们有过些许帮助。
我必须承认,我的语文水平不算好,写作对我来说是一个挑战。不过当我开始着手尝试时,却发现自己有一种停不下来的感觉。
我发现写作技术类书籍这件事特别适合我,一方面这类书并不需要华丽的辞藻以及别出心裁的情节设计,因为写出简明易懂的内容才是最重要的,另一方面我很清楚普通人在面对一门新技术时所遇到的难点在哪里,门槛在哪里,因为登山时遇到的艰难我都心中有数。
技术大神们可能会觉得那些“难点”都特别简单,他们很难站在普通人的角度思考问题,对于读者的抱怨会觉得难以理解。我时常翻阅一些国外的技术博客,发现这些大神写的文章其实并不易懂,一篇文章往往要仔细地阅读好多遍才能大致理解。如果读者希望更轻松地理解他们所写的内容,就太需要我们这些愿意写作技术类书籍的人。我们将来自山顶的晦涩的知识抽丝剥茧,让它们变得易于理解,让更多人可以享受到来自山顶的阳光。
人们常说,一个人年轻时经历的艰难会在未来成为他的财富,我想这大概就是我能完成这《Redis 深度历险:核心原理与应用实践》的原因。
为什么我要写Redis
Redis是互联网技术架构在存储系统中使用得最为广泛的中间件,它也是中高级后端工程师技术面试中面试官最喜欢问的工程技能之一,特别是那些优秀的、竞争激烈的大型互联网公司(比如Twitter、新浪微博、阿里云、腾讯云、淘宝、知乎等),通常要求面试者不仅仅掌握Redis基础使用方法,更要求深层理解Redis内部实现的细节原理。毫不夸张地说,只要能把Redis的知识点全部吃透,你的半只脚就已经踏进心仪公司的技术研发部了。
但我在以往的很多面试中,发现大多数同学只会拿Redis做数据缓存,使用最简单的get/set方法,除此之外几乎一无所知。也有小部分同学知道Redis的分布式锁,但也不清楚其内部实现机制,甚至在使用上就不标准,导致生产环境中出现意想不到的问题。还有很多同学没认识到Redis是个单线程结构,也不理解单线程的Redis为何还可以支持高并发。
我希望通过梳理和总结自己的实践经验,能够帮助更多后端开发者更快、更深入地掌握Redis技能。这就是我写作《Redis 深度历险:核心原理与应用实践》的初衷。
我所在的掌阅科技公司,为了支撑海量(亿级)的用户服务,使用了上千个Redis实例,如图0-1所示,包含大约100个Redis集群(Codis)以及很多独立的Redis节点,因此我在使用Redis作为缓存和持久存储中间件上积累了较为丰富的实战经验,这些我都将毫无保留地分享到《Redis 深度历险:核心原理与应用实践》中。
Redis涉及到的知识点是非常多的,《Redis 深度历险:核心原理与应用实践》将讲解其中最常见的Redis核心原理和应用实践经验,让读者在阅读之后可以将知识快速应用到平时的Redis项目开发中。
除此之外,《Redis 深度历险:核心原理与应用实践》还会深入探究一些底层的至关重要的计算机科学基础原理,以及技术应用的思考方式,这些基础的知识和技能将最终决定你的技术人生道路可以走多快、走多远。
《Redis 深度历险:核心原理与应用实践》内容结构
《Redis 深度历险:核心原理与应用实践》分为基础和应用篇、原理篇、集群篇、拓展篇、源码篇共5大块内容。
基础和应用篇:占据篇幅最长,这也是对读者最有价值的内容,可以直接应用到实际工作中。
原理篇和集群篇:适合对技术有着极致追求的开发者学习,他们希望透过简单的技术表面看到精致的底层世界。
拓展篇:作为最核心内容的补充部分,帮助读者进一步拓展技术视野或者夯实基础,便于进阶学习。
源码篇:满足高阶用户深入探索Redis内部实现原理的强烈需要,这类读者坚信读懂源码才是技术实力的真正体现。
图文并茂是《Redis 深度历险:核心原理与应用实践》一大特色
为了便于读者理解《Redis 深度历险:核心原理与应用实践》内容,我花费了不少时间绘制了大量原创彩色插图。希望这些彩图能够帮助读者更有效率地理解《Redis 深度历险:核心原理与应用实践》知识点,实现事半功倍的效果。
适合阅读《Redis 深度历险:核心原理与应用实践》的读者
《Redis 深度历险:核心原理与应用实践》适合以下类型的读者阅读。
1.有Redis基础,渴望深度掌握Redis技术原理的中高级后端开发者。
2.渴望成功进入大型互联网企业研发部的中高级后端开发者。
3.需要支撑公司Redis中间件运维工作的初中级运维工程师。
4.希望更好地设计Redis面试题目的后端技术面试官。
5.对Redis中间件技术好奇的中高级前端技术朋友们。
老钱
2018年10月




