Redis 常见问题
开始使用 Redis 时的常见问题
Redis 与其他键值存储有何不同?
- Redis 在键值数据库中具有不同的演变路径,其中值可以包含更复杂的数据类型,并对这些数据类型定义原子作。Redis 数据类型与基本数据结构密切相关,并且无需额外的抽象层即可向程序员公开。
- Redis 是内存中但持久存储在磁盘上的数据库,因此它代表了一种不同的权衡,即在数据集不能大于内存的限制下实现非常高的写入和读取速度。另一个优势 内存数据库是复杂数据结构的内存表示 与磁盘上的相同数据结构相比,作要简单得多,因此 Redis 可以做很多事情,而且内部复杂性很小。同时, 两种磁盘存储格式(RDB 和 AOF)不需要适合随机 access,因此它们很紧凑,并且始终以仅追加的方式生成 (甚至 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开发公司Redis开发公司开发了 “Redis on Flash”解决方案,使用 RAM/flash 混合方法 具有偏向访问模式的较大数据集。您可以查看他们的产品 有关更多信息,但此功能不是 Redis 社区版的一部分 代码库。
您可以将 Redis 与基于磁盘的数据库一起使用吗?
是的,常见的设计模式涉及获取写入量非常大的小数据 在 Redis 中(以及您需要 Redis 数据结构来对问题进行建模的数据 ),并将大量数据转换为 SQL 或最终 一致的磁盘数据库。同样,有时使用 Redis 是为了 在内存中获取存储在磁盘上的相同数据子集的另一个副本 数据库。这可能看起来类似于缓存,但实际上是一个更高级的模型 由于通常 Redis 数据集会与磁盘上的 DB 数据集一起更新,因此 并且不会在缓存未命中时刷新。
如何减少 Redis 的整体内存使用量?
一个好的做法是在将逻辑数据模型映射到 Redis 中的物理数据模型时考虑内存消耗。这些注意事项包括使用特定数据类型、键模式和规范化。
除了数据建模之外,Memory Optimization 页面中还有更多信息。
如果 Redis 内存不足会怎样?
Redis 具有内置保护功能,允许用户设置内存的最大限制
usage,使用maxmemory
选项来设置限制
到 Redis 可以使用的内存。如果达到此限制,Redis 将开始回复
写入命令时出错(但将继续接受只读
命令)。
您还可以将 Redis 配置为在达到最大内存限制时移出键 到达。有关更多信息,请参阅驱逐策略文档。
在 Linux 上后台保存失败,并显示 fork() 错误?
简短的回答:echo 1 > /proc/sys/vm/overcommit_memory
:)
现在是长篇大论:
Redis 后台保存架构依赖于fork
系统调用
现代作系统:Redis 分叉(创建子进程),它是一个
父级的精确副本。子进程将数据库转储到磁盘上,最后
出口。理论上,子级应该使用与父级作为
copy,但实际上要归功于大多数
现代作系统父进程和子进程将共享共同的
内存页。只有当页面在 child 或
父级。因为理论上所有页面都可能发生变化,而子进程是
保存,Linux 无法提前知道子节点将占用多少内存,因此如果
这overcommit_memory
设置设为零时,除非有
真正复制所有父内存页所需的可用 RAM。
如果您有一个 3 GB 的 Redis 数据集,但只有 2 GB 的免费
memory 它会失败。
设置overcommit_memory
设置为 1 时,指示 Linux 放松并在
更乐观的分配方式,而这确实是你对 Redis 想要的。
您可以参考 proc(5) 手册页来了解 available 值。
Redis 磁盘快照是原子的吗?
是的,当服务器处于 在命令执行之外,因此每个报告命令都是原子的 从 disk snapshot 的角度来看,RAM 也是原子的。
Redis 如何使用多个 CPU 或内核?
CPU 成为 Redis 的瓶颈并不常见,因为 Redis 通常是内存或网络受限的。 例如,当使用流水线时,运行在 Linux 系统上的 Redis 实例平均每秒可以传送 100 万个请求,因此如果您的应用程序主要使用 O(N) 或 O(log(N)) 命令,则几乎不会使用过多的 CPU。
但是,为了最大限度地提高 CPU 使用率,您可以在 相同的盒子,并将它们视为不同的服务器。在某个时候,单个 box 可能还不够,所以如果你想使用多个 CPU,你可以 尽早开始考虑一些分片方法。
您可以在 Partitioning (分区) 页面中找到有关使用多个 Redis 实例的更多信息。
从版本 4.0 开始,Redis 已开始实施线程作。目前,这仅限于在后台删除对象和阻止通过 Redis 模块实现的命令。对于后续版本,计划使 Redis 越来越线程化。
单个 Redis 实例最多可以容纳多少个 key?Hash、List、Set 和 Sorted Set 中的最大元素数是多少?
Redis 最多可以处理 2^32 个密钥,并且在实践中经过测试可以 每个实例至少处理 2.5 亿个密钥。
每个哈希、列表、集合和排序集合可以容纳 2^32 个元素。
换句话说,您的限制可能是系统中的可用内存。
为什么我的副本具有与主实例不同的键数?
如果您使用的密钥具有生存时间有限(Redis 过期),这是正常行为。这是发生的事情:
- 主数据库在与副本的第一次同步时生成 RDB 文件。
- RDB 文件将不包含已在主数据库中过期但仍在内存中的密钥。
- 这些键仍在 Redis 主数据库的内存中,即使逻辑上已过期。它们将被视为不存在,并且它们的内存将在以后以增量方式或显式访问时回收。虽然这些键在逻辑上不是数据集的一部分,但它们被计入
INFO
output 和DBSIZE
命令。 - 当副本读取主副本生成的 RDB 文件时,不会加载这组键。
因此,具有许多过期密钥的用户通常会在副本中看到较少的密钥。但是,从逻辑上讲,主副本和副本将具有相同的内容。
“Redis”这个名字从何而来?
Redis 是 REmote DIctionary Server 的首字母缩写词。
Salvatore Sanfilippo 为什么要启动 Redis 项目?
Salvatore 最初创建 Redis 是为了扩展实时日志分析工具 LLOOGG。但是,在基本 Redis 服务器正常工作后,他决定与其他人共享工作,并将 Redis 转变为开源项目。
Redis 是如何发音的?
“Redis” (/ˈrɛd-ɪs/) 的发音类似于“red”一词加上“kiss”一词,但没有“k”。