Redis 常见问题解答

开始使用 Redis 时的常见问题

Redis 与其他键值存储有何不同?

  • Redis 在键值数据库中有着不同的发展路径,其中值可以包含更复杂的数据类型,并在这些数据类型上定义原子操作。Redis 数据类型与基本数据结构密切相关,并直接向程序员公开,无需额外的抽象层。
  • Redis 是一种内存数据库,但持久化在磁盘上,因此它代表了一种不同的权衡,即在数据集不能大于内存的情况下实现非常高的写入和读取速度。内存数据库的另一个优点是,与磁盘上的相同数据结构相比,复杂数据结构的内存表示更易于操作,因此 Redis 可以以很小的内部复杂性完成很多工作。同时,两种磁盘存储格式(RDB 和 AOF)不需要适合随机访问,因此它们紧凑且始终以追加方式生成(即使 AOF 日志轮换也是追加操作,因为新版本是从内存中的数据副本生成的)。然而,与传统的磁盘存储相比,这种设计也涉及不同的挑战。作为内存上的主要数据表示,Redis 操作必须小心处理,以确保磁盘上始终有数据集的更新版本。

Redis 内存占用是多少?

举几个例子(均使用 64 位实例获得):

  • 一个空实例使用约 3MB 内存。
  • 100 万个小的键 -> 字符串值对使用约 85MB 的内存。
  • 100 万个键 -> 哈希值,代表一个具有 5 个字段的对象,使用约 160 MB 的内存。

测试用例很简单。使用该redis-benchmark实用程序生成随机数据集,然后使用INFO memory命令检查所用的空间。

64 位系统将使用比 32 位系统多得多的内存来存储相同的键,特别是当键和值都很小时。这是因为指针在 64 位系统中占用 8 个字节。但当然,优势在于您可以在 64 位系统中拥有大量内存,因此为了运行大型 Redis 服务器,或多或少需要 64 位系统。另一种选择是分片。

为什么 Redis 将其整个数据集保存在内存中?

过去,Redis 开发人员曾尝试使用虚拟内存和其他系统来处理大于 RAM 的数据集,但毕竟,如果我们能做好一件事,我们就会非常高兴:数据从内存中提供,磁盘用于存储。因此,目前还没有计划为 Redis 创建磁盘后端。毕竟,Redis 的大部分功能都是其当前设计的直接结果。

如果您的真正问题不是所需的总 RAM,而是需要将数据集分成多个 Redis 实例,请阅读 本文档中的分区页面以获取更多信息。

Redis Ltd. 是 Redis 开发的赞助商,该公司开发了“Redis on Flash”解决方案,该解决方案使用混合 RAM/闪存方法处理具有偏向访问模式的较大数据集。您可以查看他们的产品以获取更多信息,但此功能不属于 Redis Community Edition 代码库。

可以将 Redis 与基于磁盘的数据库一起使用吗?

是的,一种常见的设计模式涉及将 Redis 中写入量很大的小数据(以及您需要 Redis 数据结构来以高效方式建模问题的数据)和大块数据放入 SQL 或最终一致的磁盘数据库中。同样,有时使用 Redis 来将存储在磁盘数据库中的相同数据子集的另一个副本放入内存中。这可能看起来类似于缓存,但实际上是一种更高级的模型,因为通常 Redis 数据集与磁盘数据库数据集一起更新,而不是在缓存未命中时刷新。

如何减少 Redis 的整体内存使用量?

一个好的做法是在将逻辑数据模型映射到 Redis 中的物理数据模型时考虑内存消耗。这些考虑因素包括使用特定数据类型、键模式和规范化。

除了数据建模之外,内存优化页面中还有更多信息。

如果 Redis 内存耗尽会发生什么?

Redis 具有内置保护功能,允许用户设置内存使用的最大限制,使用maxmemory配置文件中的选项来限制 Redis 可以使用的内存。如果达到此限制,Redis 将开始以错误回复写入命令(但将继续接受只读命令)。

您还可以将 Redis 配置为在达到最大内存限制时逐出键。有关此内容的更多信息,请参阅逐出策略文档。

在 Linux 上,后台保存因 fork() 错误而失败?

简短回答:echo 1 > /proc/sys/vm/overcommit_memory:)

接下来是长篇:

Redis 后台保存模式依赖于现代操作系统中系统调用的写时复制语义fork:Redis 派生(创建一个子进程),它是父进程的精确副本。子进程将数据库转储到磁盘上并最终退出。理论上,子进程作为副本应使用与父进程一样多的内存,但实际上由于大多数现代操作系统实现的写时复制语义,父进程和子进程将共享公共内存页面。只有当页面在子进程或父进程中发生变化时,才会复制页面。由于理论上所有页面都可能在子进程保存时发生变化,Linux 无法提前知道子进程将占用多少内存,因此如果将设置overcommit_memory设为零,则除非有足够的可用 RAM 来真正复制所有父内存页面,否则派生将失败。如果您的 Redis 数据集为 3 GB,但只有 2 GB 的可用内存,它将失败。

设置overcommit_memory为 1 告诉 Linux 放松并以更乐观的分配方式执行分叉,这确实是您想要的 Redis。

您可以参考proc(5)手册页来了解可用值的解释。

Redis 磁盘快照是原子的吗?

是的,当服务器不在命令执行范围内时,Redis 后台保存过程总是会分叉,因此从磁盘快照的角度来看,每个在 RAM 中被报告为原子的命令也是原子的。

Redis 如何使用多个 CPU 或核心?

CPU 很少成为 Redis 的瓶颈,因为 Redis 通常受内存或网络限制。例如,使用流水线时,在普通 Linux 系统上运行的 Redis 实例每秒可以处理 100 万个请求,因此,如果您的应用程序主要使用 O(N) 或 O(log(N)) 命令,则几乎不会占用太多 CPU。

但是,为了最大限度地提高 CPU 使用率,您可以在同一个机器中启动多个 Redis 实例,并将它们视为不同的服务器。在某些时候,单个机器可能不够用,因此如果您想使用多个 CPU,您可以尽早开始考虑分片的方法。

您可以在分区页面中找到有关使用多个 Redis 实例的更多信息。

从 4.0 版开始,Redis 开始实现线程化操作。目前,这仅限于在后台删除对象和阻止通过 Redis 模块实现的命令。在后续版本中,计划使 Redis 更加线程化。

单个 Redis 实例最多可以容纳多少个键?Hash、List、Set 和 Sorted Set 中最多可以容纳多少个元素?

Redis 最多可以处理 2^32 个键,经实践测试,每个实例至少可以处理 2.5 亿个键。

每个哈希、列表、集合和有序集合都可以容纳 2^32 个元素。

换句话说,您的限制可能是系统中的可用内存。

为什么我的副本与主实例的密钥数量不同?

如果你使用有限生存期的密钥(Redis 过期),这是正常现象。以下是发生的情况:

  • 主服务器在与副本服务器第一次同步时生成 RDB 文件。
  • RDB 文件将不包含主数据库中已过期但仍在内存中的密钥。
  • 即使逻辑上已过期,这些键仍位于 Redis 主节点的内存中。它们将被视为不存在,并且稍后将以增量方式或显式方式回收其内存。虽然这些键在逻辑上不是数据集的一部分,但它们会在输出INFO和命令中被考虑DBSIZE
  • 当副本读取主服务器生成的RDB文件时,将不会加载这组键。

因此,拥有大量过期密钥的用户通常会在副本中看到较少的密钥。但是,从逻辑上讲,主密钥和副本密钥的内容是相同的。

“Redis”这个名字从何而来?

Redis 是RE mote DI ctionary S erver的首字母缩写。

Salvatore Sanfilippo 为什么要启动 Redis 项目?

Salvatore 最初创建 Redis 是为了扩展实时日志分析工具LLOOGG 。但在使基本 Redis 服务器正常运行后,他决定与其他人分享这项工作,并将 Redis 变成一个开源项目。

Redis 怎么发音?

“Redis”(/ˈrɛd-ɪs/)的发音类似于单词“red”加上单词“kiss”,但不带“k”。

给此页面评分
返回顶部 ↑