视频
了解更多
下载 九项基本数据库功能 并确保您的数据库具备满足所有需求的能力。
使用 Redis 开发应用程序非常有趣,但与任何技术一样,在设计基于 Redis 的应用程序或 Redis 命名空间应用程序时,您应该牢记一些要点。您可能已经熟悉关系数据库开发,但请记住,Redis 是一个内存数据库,并且它是(主要)单线程的。继续阅读以探索 Redis 密钥最佳实践。
因此,在使用 Redis 时,您应该注意一些特殊之处。
数据库存储数据,但任何开发人员都可能丢失对存储在 Redis 中的一些数据的跟踪。这很正常,因为应用程序的需求会发生变化,或者您会更改存储数据的方式。也许您忽略了对一些密钥执行 EXPIRE 操作,或者应用程序的某个模块已停用。
无论如何,很有可能 Redis 数据库中的一些数据不再使用,并且毫无目的地占用空间。Redis 的无模式性质使得难以理解数据集的内容,除非您对密钥使用可靠的命名法。使用适当的命名方法和 Redis 命名空间为您的密钥命名可以使数据库的整理变得容易得多。当您按应用程序或服务对密钥进行命名空间划分时(约定是使用冒号(':')字符分隔密钥名称的各个部分) - 这是一种 Redis 命名空间最佳实践。这样,您可以在数据迁移、转换、删除或移动过程中轻松地识别它们。Redis 命名空间和 Redis 命名空间密钥有助于这种识别。
除了 Redis 命名空间之外,Redis 的另一个常见用例是作为“热”数据项的辅助数据存储,而大多数数据则保留在另一个数据库中(例如 PostgreSQL、MongoDB)。在这种情况下,开发人员经常会忘记在从主数据存储中移动数据时从 Redis 中删除数据。这种跨数据存储的依赖关系需要级联删除,可以通过将给定数据项的所有标识符保存在 Redis 集合中来实现。这确保了在从主数据存储中删除数据后调用的清理过程只需要遍历该集合的内容,以便删除所有相关的副本和相关信息(包括操作完成后该集合本身)。
这似乎与上面关于 Redis 命名空间的描述相矛盾,但由于密钥名称也会占用内存,因此您应该努力使它们保持简短。显然,当数据集包含数百万或数十亿个密钥时,这会成为一个问题,但事实是,长的密钥对任何哈希表来说都是一个负担。
例如:假设存储 1,000,000 个使用 Redis 命名空间的密钥,每个密钥都设置为一个 32 字符的值,那么在使用 6 个字符的密钥名称时,将消耗约 96MB 的内存,而在使用 12 个字符的名称时,将消耗 111MB 的内存(在 32 位 Redis 服务器上)。随着密钥数量的增加,超过 15% 的这种开销变得非常显著。通过 Redis 删除带有前缀的密钥也是一种可能。
无论是由于内存使用量还是性能,有时一种数据结构比另一种更适合您的数据集。以下是一些需要牢记的最佳实践。
不要将数据存储在数千(或数百万)个独立的字符串值中,而是考虑使用哈希数据结构对相关数据进行分组。哈希非常有效,可以减少内存使用量(此外,它们还提供了抽象一些细节并使代码更易读的附加价值)。有关这方面的更多信息,请查看此文章。
在适用时,使用列表而不是集合。如果您不需要集合的属性来确保唯一性或检查成员资格,列表将消耗更少的内存并更快地执行插入操作。
有序集合是最昂贵的数据结构,无论是在内存消耗方面还是在基本操作复杂度方面(例如,ZADD 一个新成员)。如果您只需要一种查找分数的方法,并且顺序并不重要,请考虑使用哈希。
Redis 中一个经常被忽视的功能是位图或位集(从 v2.2 开始可用)。位集允许您对 Redis 值执行多个位级操作,这意味着可以有效地存储大量数据。例如,这可以用于一些轻量级分析。
从 Redis v2.8 开始,SCAN 命令可以使用游标检索键空间中的密钥。此行为与(嘘)KEYS 命令不同,KEYS 命令会立即返回所有匹配元素,但在生产环境中被认为有风险,因为它可能会阻塞您的 Redis 服务器,甚至耗尽其 RAM 资源。另一方面,SCAN 使您能够检查数据,而无需冒阻塞服务器或依赖从属服务器的风险。
请注意,SCAN 需要您读取一个传递给对 SCAN 的后续调用的游标值。SCAN 还接受一个键名模式和一个可选的计数参数。SCAN 和 KEYS 之间的另一个区别是,使用 SCAN 可能多次获取相同的密钥名称。
SCAN 伴随着 SSCAN、HSCAN 和 ZSCAN,它们允许您迭代集合、哈希和有序集合(分别)的内容。
作为一名开发人员,一旦您接受了 Redis 运行 Lua 脚本的能力,您就会进入熟悉的领域。Lua 是最容易学习的语言之一,它为您提供了在 Redis 服务器本身内部运行代码的创造力。当正确应用时,Lua 脚本在性能和资源消耗方面可以产生巨大的影响。与其将数据传送到(应用程序的)CPU,不如使用脚本在数据附近执行逻辑,从而减少网络延迟和冗余数据传输。
Lua 产生巨大影响的经典示例是,当您从 Redis 中获取大量数据,然后在您的应用程序中对其进行过滤或聚合时。通过将处理工作流程封装在脚本中,您只需调用它即可以更快的速度和更少的资源获取更小的答案。
专家提示:Lua 很棒,但一旦您将工作流程迁移到 Lua,您可能会发现错误报告和处理变得更加困难(毕竟您是在 Redis 服务器内部运行的)。一个巧妙的方法是使用 Redis 的发布/订阅功能,让您的脚本将它们的“日志”消息发布到一个专用通道。然后,设置一个订阅者进程来接收这些消息并相应地处理它们。
在 Redis 探索之旅中,您可能会学到很多其他重要的提示,但这份清单应该可以帮助您开始学习一些最重要的提示。如果您还有其他建议想要分享,或者有任何反馈或问题,请随时联系我,我随时待命 🙂