回答

收藏

Redis 使用的底层数据结构是什么?

技术问答 技术问答 308 人阅读 | 0 人回复 | 2023-09-11

我试图在一个明确的列表中回答两个问题:) {$ R, I) u# t8 Q
[ol]Redis 使用的底层数据结构是什么?
4 x' F8 Z" g0 W每种类型的主要优缺点/用例是什么?[/ol]所以,我读过Redis列表实际上是通过链表实现的。但对于其他类型,我不能挖掘任何信息。此外,如果有人偶然发现了这个问题,并且没有对修改或访问不同数据结构的优缺点进行高级总结,他们也会有一个完整的列表来解释什么时候最好使用特定类型?进行引用。- P* I. q- E. }. p& \( [6 y
具体来说,我希望概述所有类型:字符串、列表、集合zset 和哈希。; e) k5 x+ Y" S5 C0 H% h. N) W+ R
                                                               
3 t4 j# y' _7 V/ e( X$ A1 ~1 @    解决方案:                                                               
# P1 h" ^9 k9 V- y                                                                我会试着回答你的问题,但我会从一开始可能看起来很奇怪的事情开始:如果你对 Redis 内部不感兴趣,你不要在意如何在内部实现数据类型。这是一个简单的原因:对于每个 Redis 操作,你会在文档中找到时间复杂性,如果你有一组操作和时间复杂性,那么你唯一需要的是一些关于内存使用的线索(因为我们有很多可能因数据而异的优化,获这些数据的最好方法是进行一些琐碎的现实世界测试)。
3 H, z5 l/ `* z- n9 x, j但既然你问了,这是每个 Redis 实现数据类型的底层。
1 a3 p+ V; C+ A6 T% o字符串是使用 C 动态字符串库已经实现,因此我们不需要为额外操作中的分配付费(更近)。例如,通过这种方式,我们有 O(N) 附加,而不是二次行为。
2 M( C2 v) U8 f7 O列表用链表实现。/ y( |' c# _6 }# A0 w; n; X9 A
集合哈希它是用哈希表实现的。
& z+ \8 g0 l* L$ @排序集跳过列表(一种特殊类型的平衡树)实现。
然而,当列表、集合和排序集合的项目数量和最大值较小时,将使用不同的、更紧凑的代码。该代码因类型而异,但其特点是它是一个紧凑的数据块,通常强制 每个操作O(N) 扫描。因为我们只使用这种格式的小对象,这不是问题;扫描一个小 O(N) blob 是缓存无意识,所以其实很快。当元素太多时,编码会自动切换到机器编码(链表、哈希等)。
- V3 k/ W9 d! t! s/ F' n但你的问题不仅仅是关于内部,你的观点是用什么类型来完成什么?.
& @3 N$ _. E' [; d8 P+ x) J字符串这是所有类型的基本类型。List 是字符串列表, Set 是一组字符串,等等。" F( }/ {) ^+ t0 R" k: T
想存放 HTML 页面的所有明显场景,以及当您想要避免转换已编码的数据时,Redis 字符串是个好主意。所以,比如你有 JSON 或 MessagePack,您可以将对象存储为字符串。Redis 2.你甚至可以在6 中使用 Lua 脚本操作此对象服务器端。
$ d; ]( s4 v) i8 y另一 Redis 导出命令访问随机字节,甚至单位。例如,查看这篇优秀的博客文章:使用 Redis 的 Fast Easy 实时指标。
0 ]5 J2 n' m$ k! U- L8 x列表当您可能只触及列表的极端时,列表是好的:接近尾或接近头。由于随机访问速度慢,列表不适合分页内容,O(N)。因此,列表的良好用途是简单的队列和堆栈,或使用具有相同源和目标的 RPOPLPUSH 以旋转项目环处理循环中的项目。
0 e1 ^4 ^! V/ R只想创建 N 收集项目上限时,列表也很好,通常当 N 很小时。9 ?6 P! j2 k; R) b
集合集合是一个无序的数据集合,所以每次你有一个项目集合,以一种非常快的方式检查集合的存在或大小是非常重要的。另一件很酷的事情是支持偷看或弹出随机元素(SRANDMEMBER 和 SPOP 命令)。
, Z  v$ w% O- d集合也可以很好的表达关系,比如用户 X 什么是朋友? 等等。但我们将看到,其他用于此类内容的好数据结构是排序集。
) O8 a8 y! r3 v+ l$ I7 I集合支持复杂的操作,如交集和并集。因此,当您有数据并想要转换数据以获得一些输出时,这是一种计算使用 Redis 数据结构良好。( A5 F$ g# u6 z& p- u
小集合以非常有效的方式编码。
! X& a, O. x: B2 C3 K哈希值哈希是由字段和值组成的表示对象的完美数据结构。 也可用于散列字段HINCRBY 以原子的形式增加。当你有对象时,如用户、博客文章或其他类型项目,如果你不想使用自己的代码,哈希很可能会去。JSON或类似的方法。" ?* `, E2 r# P* Y7 z6 K4 s
但请记住,Redis 非常高效地编码小散列,您可以要求 Redis 以非常快的方式原子地 GET、SET 或增加单个字段。
6 A6 O/ h) b" z! ~) ^% Q/ h散列也可以用来表示链接的数据结构,并使用引用。例如,检查 lamernews.com 评论的实现。) X5 f! i5 A( U; i
排序集排序集是除列表外唯一用于维护有序元素的数据结构。你可以用排序集做一些很酷的事情。例如,你可以在你的 Web 有各种各样的应用程序Top Something列表。按分数排名最高的用户,按页面浏览量排名最高的帖子,无论什么排名最高,但单个 Redis 实例将支持每秒大量插入和获取顶部元素的操作。' m5 V: \) s) k3 v* s# ?. \1 t( O! Y9 C" q
像常规集一样,排序集可以用来描述关系,但它们也允许你分页并记住项目列表的顺序。例如,如果我记得用户 X 朋友有一个排名集,我可以很容易地按照接受的友谊顺序记住他们。, M0 W, L" g0 A5 e) D
排序集适用于优先队列。
- c9 H# Q; Y0 l( `8 h9 ?排序集就像一个更强大的列表,从列表中间插入、删除或获取总是很快。但它们使用更多的内存和 O(log(N)) 数据结构。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则