为了拿捏 Redis 数据结构,我画了 40 张图(完整版)

38e9a4e5e659acd82603634499d7636e.png

若有收获,请记得分享和转发哦

Redis 为什么那么快?

除了它是内存数据库,使得所有的操作都在内存上进行之外,还有一个重要因素,它实现的数据结构,使得我们对数据进行增删查改操作时,Redis 能高效的处理。

因此,这次我们就来好好聊一下 Redis 数据结构,这个在面试中太常问了。

注意,Redis 数据结构并不是指 String(字符串)对象、List(列表)对象、Hash(哈希)对象、Set(集合)对象和 Zset(有序集合)对象,因为这些是 Redis 键值对中值的数据类型,也就是数据的保存形式,这些对象的底层实现的方式就用到了数据结构

我画了一张 Redis 数据类型(也叫 Redis 对象)和底层数据结构的对应关图,左边是 Redis 3.0版本的,也就是《Redis 设计与实现》这本书讲解的版本,现在看还是有点过时了,右边是现在 Github 最新的 Redis 代码的(还未发布正式版本)。

35aa93ba34dce65580749e76374c7528.png

可以看到,Redis 数据类型的底层数据结构随着版本的更新也有所不同,比如:

  • 在 Redis 3.0 版本中 List 对象的底层数据结构由「双向链表」或「压缩表列表」实现,但是在 3.2 版本之后,List 数据类型底层数据结构是由 quicklist 实现的;

  • 在最新的 Redis 代码(还未发布正式版本)中,压缩列表数据结构已经废弃了,交由 listpack 数据结构来实现了。

这次,小林把新旧版本的数据结构说图解一遍,共有 9 种数据结构:SDS、双向链表、压缩列表、哈希表、跳表、整数集合、quicklist、listpack。

不多 BB 了,直接发车!

9c9667a083b37e10d4a87a1922602854.png

9318ec99839cf84c5e6804c5f28990c0.png

6ee302dd2d2bdda4e8dbedc2cf575042.png

f632191905d63d5b40cad261f8fe4eac.png

f1641642dcbc2ca679459d1ac91758cc.png

194f33815258bb09bbdcea903d47061b.png

361e8430f223250b2c9175702db18f41.png

44f4f63f6aafe5c7aff4216a17820081.png

806b2d926450d8f9b96775c4d66b60c7.png

1706eb8ec7622c611716971bfb8ea8d9.png

362fa98db3f9bd45d7a2287d67edde29.png

7d73aa81826cb4e718c8e909c2949bfd.png

4d49312a87ca1a3a2cf6f27443e4089e.png

d27e9569f757af27e134d8ecaa5e9db2.png

db3723b9ec2bd24736b2cfda7c51a75b.png

bb09a7bbbca71a13d7c8b792a97b2ac4.png

59e12d920c5ca1899ac89cb4f8f01343.png

c59ad9fe628b3f57580a6cda378f6ef7.png

ee41d67df066112e60b89ad4051d1003.png

02cd4a2736a7a04a2a592a860c347d01.png

af07ac1ed1c44c816752b0eb425b9306.png

09982bc70d25ed9c88705f17e5c73c76.png

d54bd89f1dda7637c3855cb9c6b3f0fb.png

db3e25a576abdbc7f10e0c1af9319e01.png

51ec71b1e9a982a8b01e8c9d45c5d966.png

ac3aa5ccef009ca51130495b67a0c163.png

b563243cd8416494dfaa723f3cd74f12.png

ba846f971bc1bd535eef39b3dd1cc445.png

997df0519397bb571db84af3c8444740.png

85edfec6b8e9403e31eb5d05a635e109.png

cd7dea924962bfb610584daaa7b6f6f1.png

dd8679b323ee35bdecb3a7115f85cd4b.png

eadfdf6fde8ab251168891355cd0653a.png

dee2f74350aa611fcc4543b49a5e24d7.png

e896c0fef8b5d8fa2f001a0128c7fea9.png

848f383bc3ba31cd48dc0476f66296bf.png

0783e217bb029d92d77369c6f22a04c6.png

8cb7eb1f99f9711f28d4a9c0e3fc361e.png

6780eb99fdfdb67bf2e619cd0433e0a5.png

193296df8fca383e0c1e6c560d7a8e45.png

6d24c97f209e6295efb9abffe6b05618.png

51d043f4e25df280c96cc1db4cc38b79.png

2495682f4829660d82f47a6b4a0d28a2.png

dd062385bc9b123230405ebc24e35249.png

a559131722c3ed5e97650814b25c8809.png

a7583845e11ed0a62c18414f66f27fa9.png

941d60f266ba4b928cbd7afd0925ad60.png

11f9eb32b5e9df75033792f761ed3fab.png

c052ee2bcac1ff02c8e74508b512ba16.png

98a44b6d401b60f2892664b28cff0aef.png

46e4b0d138dda77e0b0672ab31f5539d.png

d23aa999a94cc8a84cccb49f745763f4.png

03bce97f8d480a0d20fe149901a1dbab.png

333a2ab665ddb4d06edfb043f5386e02.png

6b617411b951335b52d526e1978faaa1.png

27258d144235a6dffa06878da5475482.png

0cd2e738cc83cad7f3f431a6ffedc297.png

4225bbe44e3708ce3cc47aefaf44a827.png

adc82ac9008b3c96a49232a91b69c40c.png

6fb0454e1829b9f15a75022d01c6cd94.png

可以看到,listpack 没有压缩列表中记录前一个节点长度的字段了,listpack 只记录当前节点的长度,当我们向 listpack 加入一个新元素的时候,不会影响其他节点的长度字段的变化,从而避免了压缩列表的连锁更新问题


参考资料:
  • 《Redis设计与实现》

  • 《Redis 源码剖析与实战》


总结

终于完工了,松一口气。

好久没写那么长的图解技术文啦,这次潇潇洒洒写了 2 万字 + 画了 35 多张图,花费了不少时间,又是看书,又是看源码。

希望这篇文章,能帮你破除 Redis 数据结构的迷雾!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值