最大化 Redis 效率:利用 Redis 哈希降低内存成本
Redis 等内存数据库以其速度和效率而闻名,但其以内存为中心的设计使得内存使用成为扩展应用程序时的关键因素。随着应用程序的增长,开发人员需要考虑内存优化策略,以保持低成本和高性能。
当您有多个相关字段与单个实体关联时,Redis 哈希非常有用。您可以将它们作为具有多个字段的哈希值合并为单个键,而不是为每个字段创建多个单独的键。
本博客探讨了当用例具有与单个实体关联的多个相关字段时,Redis 哈希如何节省内存、降低基础设施成本。
Redis:以内存为中心的数据库
Redis 将所有数据存储在内存中,速度快得令人难以置信,但对内存消耗也很敏感。高效的内存使用直接影响 Redis 实例的性能和成本,尤其是在可能管理数百万个键的大规模系统中。
存储在 Redis 中的每个密钥都会产生内存开销,通常每个密钥大约 40 字节,这主要归因于密钥管理、指针、哈希表桶。当处理大量键时,这种开销会迅速增加,导致更高的内存成本。对于需要显着扩展的系统,优化内存变得至关重要,Redis 提供了多种数据结构来实现这一点,包括哈希、集合和列表。
什么是 Redis 哈希?
Redis 哈希是一种键值数据结构,其中每个 Redis 键都包含一个字段值对,类似于编程语言中字典的工作方式。与将每个字段存储为单独的 Redis 键不同,多个字段可以存储在一个键下。
`示例:
普通键值:
用户:123:姓名 ->“约翰”
用户:123:年龄 ->“30”
使用 Redis 哈希:
用户:123 ->
{ 姓名:“约翰”,
年龄:“30”}`
通过哈希,我们将相关字段(例如姓名和年龄)存储在单个 Redis 键中,有效地减少了键的数量,从而减少了产生的开销。
为什么使用 Redis 哈希而不是普通的键值对?
现在我们了解了基础知识,让我们更深入地了解为什么 Redis 哈希对于内存优化如此有效。
- 减少内存开销
在 Redis 中,管理各个键的内存开销会迅速增加。通过将相关字段合并到单个 Redis 哈希中,您可以显着减少数据集中的键数量。这直接减少了每个键 40 字节的开销。
- Ziplist 压缩
当 Redis 哈希包含的字段数量少于可配置数量(默认 512)时,它们将存储为 ziplist。 Ziplist 针对内存效率进行了优化,因为它们将数据存储在连续的内存块中,从而避免了与每个字段关联的指针和元数据的开销。
- 大型系统中更好的内存管理
在可能拥有数亿个键值对的系统中,Redis 哈希允许您更有效地组织和压缩数据。通过减少键的数量,Redis 可以减少调整哈希表大小的时间,从而提高性能并减少内存碎片。 Redis 哈希表动态增长和收缩,并且使用较少的键,Redis 避免了频繁的调整大小操作。
- 节省成本
使用 Redis 哈希最引人注目的好处之一是节省成本。
让我们举一个现实世界的例子:考虑一个拥有数百万用户的应用程序,其中每个用户的活动都在 Redis 中进行跟踪。如果将每条用户数据存储为单独的 Redis 键,则内存开销会迅速增长。但是,通过切换到 Redis 哈希,您可以显着减少内存消耗 - 减少多达 60%,具体取决于数据集。
这意味着您可以在更小、更便宜的硬件上运行 Redis 实例,或降低云基础设施成本。随着时间的推移,通过 Redis 哈希进行内存优化可以节省大量成本,尤其是在规模上。
使用 Redis 哈希的挑战
虽然 Redis 哈希提供了显着的内存优化优势,但仍存在一些需要注意的挑战:
大型哈希的内存使用情况
如果哈希增长超过 hash-max-ziplist-entries 阈值,Redis 会将 ziplist 转换为传统哈希表,这会产生更多内存开销。虽然这对于较大的数据集通常是可以接受的,但监视哈希大小并相应地调整 hash-max-ziplist-entries 设置以平衡内存效率和性能非常重要。
粒度TTL
在 Redis 7 之前的版本中,Redis 哈希不支持哈希内字段的单独 TTL。您只能为整个哈希键设置过期时间,这意味着如果一个字段需要比其他字段早过期,则无法单独使用 Redis 哈希来实现这一目标。 Redis Community Edition 7.4 中的新增功能是能够为各个哈希字段指定过期时间或生存时间 (TTL) 值。
使用案例:游戏排行榜中的实时分析
考虑一个在线游戏平台,该平台可以跟踪玩家在多个游戏中的得分。最初,您可以将每个游戏的每个玩家的得分存储为单独的键:
玩家:123:游戏:567:得分 -> 100
玩家:123:游戏:890:得分 -> 150
在这种场景下,随着越来越多的玩家参与更多的游戏,Redis 中的 key 数量迅速增长,导致内存开销和管理复杂度较高。键的爆炸式增长使得 Redis 效率低下,因为它需要处理大量键,并且由于与每个键相关的元数据开销而增加了查找时间和内存使用量。
使用 Redis 哈希进行优化:
为了优化这一点,您可以将分数存储在 Redis 哈希中,其中玩家 ID 是键,游戏 ID 及其各自的分数存储为哈希中的字段:
玩家:123 -> {游戏:567 -> 100,游戏:890 -> 150}
这种方法显着减少了键的数量,从而最大限度地减少了内存消耗。 Redis 不是为每个玩家-游戏组合维护一个单独的密钥,而是只处理每个玩家一个密钥,并将特定于游戏的分数存储在哈希中。
优点:
内存效率:您可以通过将多个键合并为一个键来减少内存开销,从而避免与 Redis 密钥管理相关的每个键 40 字节的开销。
检索速度更快:可以一次性检索玩家的所有游戏分数,提高排行榜查询或分数查找的性能。
降低复杂性:管理数百万玩家和数千款游戏的分数变得更加易于管理,在数据复制或备份过程中需要处理的密钥更少。
结论
从普通键值对切换到 Redis 哈希是优化 Redis 内存使用的最强大、最有效的策略之一。通过将多个相关的键值对合并到单个哈希中,您可以显着减少数据库中单个键的数量,从而最大限度地减少开销并提高整体内存效率。 Redis 还应用了额外的内存优化,例如针对小型哈希值的 ziplist 压缩,使您可以进一步节省空间。
在管理数百万个密钥或高交互率成为常态的大型应用程序中,这些优化可以显着减少内存消耗。这不仅可以提高系统性能,还可以减少内存碎片,而内存碎片会随着时间的推移而降低性能。更重要的是,通过降低内存使用量,Redis 哈希可以显着降低基础设施成本,使您能够使用相同的硬件或云资源实现更高的效率。
如果使用得当,Redis 哈希提供了一个有效管理复杂数据集的优秀工具。通过将相关数据分组到单个键下,您不仅可以简化数据模型,还可以确保 Redis 即使在重负载下也能实现最佳性能。这种方法在内存受限的环境中或在优先考虑成本优化的场景中特别有价值。
最终,采用 Redis 哈希的组织可以期望减少基础设施开支,同时提高 Redis 集群的响应能力和可扩展性,使其成为任何高需求、数据密集型应用程序的明智选择。