1
头图

我是码哥,可以叫我靓仔。我人生中的第一本书《Redis 高手心法》出版了!

作为当今广受欢迎的内存数据库,Redis 以其卓越的性能和广泛的应用场景著称。

掌握 Redis 技术几乎成为每位开发人员、测试人员和运维人员的看家本领!

大约在 2021 ~2023 年期间,我在微信公众号「码哥跳动」(原「码哥字节」,后改名为「码哥跳动」)上发表了 40 多篇 Redis 技术相关文章,有很多读者也是因为看了我的 Redis 系列,关注了我的公众号,感谢大家一路陪伴。

自从签下约稿合同到正式出版,经历了两年之久。

千古无同局,叶底能否藏花,我们未来印证,愿此心法能让你学有所成,你来,我等着。

01打磨只为呈现完美的作品

Chaya:码哥,Redis 这么快,你咋就这么慢呢?从恋爱到生娃都没你这么久。

写书的难度可比写公众号文章大多了。公众号的文章,可能有一些错别字,也有可能存在语病。

编写书的话,要求严格多了,语言要精准正确,不能存在错别字和语病,内容需要循序渐进有层次感,还要经过出版社老师的多次审核、校正,每一段话和文字都是我们精心「雕刻」的成果。

此外,我经过多年对 Redis 的深耕,花了很多时间重新梳理了 Redis 技术架构,加入了 Redis 6.0 ~ 7.0 版本的各种全新特性 ,从更深层次的角度挖掘底层实现原理,并尽量用风趣幽默的语言和 158 张图片解释难懂的技术点

作为后端开发者的我深刻知道,学习是一件比较难的事情,所以我就想着站在开发者的角度,用拟人化、场景化诙谐幽默的言语,再加撩人心弦又准确图片让读者轻松愉快地学习 Redis 实现原理和开发实战技巧。

总之一句话,每一个章节都经过反复推敲,只为呈现出最精彩的内容给你们。在我花费了大量精力更系统更全面地规划,以及出版社老师不断编排打磨,《Redis 高手心法》纸质书成为了去繁存简,精益求精的作品,就好像从钢铁侠战甲马克 1 号,进化到成功拿下灭霸一血的马克 85 战甲。

Chaya:网络资料很多,但碎片化严重,如何才能成为 Redis 高手,建立完整的知识框架?

本书基于 Redis 7.0 版本的源码来讲解,并建立了一个完整的 Redis 知识框架,从全局视角整理 Redis 知识体系,结合难点给出 158 张图片,希望能让你们更容易理解。

对于一门技术,如果只接触了零散的技术点,没有在脑海里建立⼀个完整的知识框架和架构体系,没有系统观,就会很吃力,而且会出现一看好像会,过后就忘记,⼀脸懵逼的情况。

我会引导大家从全局出发,带着问题去寻找答案,尝试输出对一个技术点的思考和理解。

⼀起搭建⼀套完整的知识框架, 学会从全局视角整理整个知识体系

02欲练此功不必自宫只需放松

本书的特点是 Redis 化身成人,将复杂的概念与实际案例相结合,以简洁诙谐幽默的方式,为你揭示 Redis 的精髓

Redis 的第一人称视角出发,以拟人故事化的方式和诙谐幽默的语言与各路“神仙”对话,配合 158 张图片,由浅入深循序渐进地讲解 Redis 的数据结构实现原理。

篇幅有限,我从书中摘取少量内容,给大家感受下文字和图片的温度。

03底层数据结构实现原理

Chaya:我知道你支持很多种数据类型,对于不同的数据类型,底层应该用了多种数据结构来实现存储吧?

小姐姐很聪明,我给开发者提供了 String(字符串)、Hashes(散列表)、Lists(列表)、Sets(无序集合)、Sorted Sets(可根据范围查询的排序集合)、Bitmap(位图)、HyperLogLog、Geospatial(地理空间)和 Stream(流)等数据类型。

为了在速度和内存占用之间找到最优解,我设计了多种数据结构。总之为了实现多快好省(支持数据类型多、速度快、好用、节省内存)。

MySQL:“你都是用 C 语言开发出来的,C 语言本就有字符串,吓唬谁呢?!”

格局能不能打开一点儿,我并没有直接使用 C 语言的字符串,而是自己搞了一个 SDS 的结构体来表示字符串。

为了支持丰富和高性能的字符串操作函数、保存二进制格式数据、节省内存,以及实现“既 要又要还要”的目标。

SDS 中的 len 字段保存了字符串的长度,实现了 O(1) 时间复杂度获取字符串长度。

SDS 结构有一个 flags 字段,表示的是 SDS 类型。实际上 SDS 一共设计了 5 种类型,分别是 sdshdr5、sdshdr8、sdshdr16、sdshdr32 和 sdshdr64,区别在于数组的 len 长度和分配空间 长度 alloc 不同。

struct __attribute__ ((__packed__)) sdshdr8 {
   uint8_t len;
   uint8_t alloc;
   unsigned char flags;
   char buf[];
};

节省内存

之所以这么设计,是因为使用不同的 SDS 类型保存不同大小的字符串可以节省内存。

二进制格式数据安全

SDS 不仅可以存储字符串类型数据,还能存储二进制格式数据。SDS 并不是通过“\0” 来判断字符串结束的,而是采用 len 标志结束,所以可以直接存储二进制格式数据。

编码格式

我还对字符串类型的数据采用了三种编码格式来存储,分别是 int、embstr 和 raw,你可使 用 OBJECT encoding key 来查找对象所使用的编码类型。

空间预分配

当对 SDS 进行缩短操作时,程序并不会回收多余的内存空间,如果后面需要 append 追 加操作,则直接使用 buf 数组 alloc - len 中未使用的空间。

通过惰性空间释放策略,避免了减小字符串所需的内存重新分配操作。

篇幅有限,更多的底层数据结构实现原理,不再一一列举。大家可以看下一些书中的一些图片感受下温度。

ziplist 数据结构。

listpack 数据结构。

Lists 实现消息队列实现原理。

4RDB 与 AOF

Chaya:Redis 数据保存在内存,如果没有持久化,一旦断电或者宕机,保存在内存中的数据将全部丢失,咋办呢?

我有两大撒手锏,可以实现数据持久化,做到宕机快速恢复,“不丢数据稳如山”,无须从数据库中慢慢恢复数据。它们就是 RDB 快照和 AOF(Append Only File)。

MySQL:“在实际生产环境中,程序员通常会给你配置 6GB 的内存,将这么大的内存数据生成 RDB 快照文件落到磁盘的过程会持续比较长的时间。你如何做到在继续处理写命令请求的同时保证 RDB 与内存中的数据一致呢?”

作为唯快不破的 NoSQL 数据库扛把子,我在对内存数据做快照时,并不会暂停写操作(读操作不会造成数据的不一致)。我使用了操作系统的多进程写时复制技术(Copy On Write ,COW)来实现快照持久化。

Chaya:“随着写入操作持续执行,AOF 日志过大怎么办?文件越大,数据恢复就越慢。”

为了解决 AOF 文件体积膨胀的问题,创造我的 Antirez 老哥设计了 AOF 重写机制(AOF Rewrite),对文件进行瘦身。

5主从复制架构

Chaya:“有了 RDB 快照和 AOF 再也不怕宕机丢失数据了,但是 Redis 实例宕机了怎么办?如何实现高可用呢?”

Chaya 愣了一会儿,又赶紧补充道:“依然记得那晚我和我的恋人鸳语轻传,香风急促,走在成都的街头约会。可是这时候 Redis 忽然宕机了,无法对外提供服务,电话连环 call,岂不是折煞人也“。

莫怕,为了你们的幸福。我提供了主从模式,通过主从复制,将一份冗余数据复制到其他 Redis 服务器,实现高可用。你们放心地说温存,说风月。

Chaya:“master 和 slave 的同步是如何完成的呢?master 的数据是一次性传给 slave,还是分批同步?主从正常运行期间又怎么同步呢?要是 master 和 slave 间的网络断连了,重新连接后数据还能保持一致吗?”

你问题怎么这么多?不要急。我知道你想安心地与恋人相会,不受 Redis 宕机导致的服务报警的干扰。主从数据同步分为 4 种情况。

◎ master 和 slave 第一次全量同步。

◎ master 和 slave 正常运行期间的数据同步。

◎ master 和 slave 网络断开重连同步。

主从库第一次复制过程大体可以分为 3 个阶段:建立连接阶段(准备阶段)、同步数据阶段、发送同步期间接收的新写命令到 slave 阶段。

6哨兵集群

主从复制架构面临一个严峻问题:master 宕机,无法执行写操作,无法自动选择一个 slave 切换为 master,也就是无法实现故障自动切换。

Chaya 的恋人:“眼前是橡树的绿叶,白色的竹篱笆。好想告诉我的她,这里像幅画。一起手牵手么么哒(此处省略 10000 字)Redis 忽然宕机,我总不能把 Chaya 推开,停止甜蜜,然后打开电脑手工进行主从切换,再通知其他程序员把地址改成新 master 的信息上线?”。

如此一折腾恐,想必你心里的雨倾盆地下,万万使不得。所以必须有一个高可用的方案,为此,我提供一个高可用方案——哨兵(sentinel)。

哨兵是 Redis 的一种运行模式,它专注于对 Redis 实例(master、slave)运行状态的监控,并能够在 master 发生故障时通过一系列的机制实现选主及主从切换,实现自动故障切换,确保整个 Redis 系统的可用性。

你就可以安心地与你的恋人 Chaya 在欢乐港湾约会,尽情享受甜蜜,哪怕是吵架都那么醉人,不再需要担心 Redis 忽然宕机带来的烦恼。

我们先从全局看哨兵,简要地了解它的整个运作流程,接着针对每个任务详细分析,Redis 哨兵的主要职责如下。

Chaya:“来说下实现原理吧。”

篇幅有限,我就不继续细说实现原理的细节了,各位道友可拿出 50 灵石,购买查看完整版的《Redis 高手心法》。

—-这里放购买卡片。

6IT 大佬们的推荐语

以下来自一些 IT 技术大佬对本书的推荐语。


码哥字节
2.2k 声望14.1k 粉丝