回答

收藏

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

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

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

本版积分规则