回答

收藏

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

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

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

本版积分规则