视频

了解更多
Redis 7.0 的发布正按计划进行,我们刚刚发布了其第二个候选版本。这个候选版本是一个计划中的里程碑,旨在完成版本的特性,但对于我们在新版本中展示附加内容来说,这也是一个机会。例如,Redis 函数已从 Redis 自 2.6 版以来就有的对脚本现有支持演变而来。类似地,Redis 的更多特性已演变而来。
在自然界,进化显然是随机发生的,而自然选择负责对进化结果进行分类。一般而言,对于软件而言,特定对于 Redis,这一过程是向后发生的:我们选择预期的路径并使项目随之进化。我们没有让随机性决定未来,而是让我们的路线图的计划和执行主要受到用户反馈和 Redis 最合适的新用例的指导。
在 Redis 7.0 中,访问控制列表 (ACL) 也进了一步进化。ACL 引入到 Redis 6.0 中,它通过添加用于管理用户及其权限的机制逆转了将安全性视为超出项目范围的长期看法。然而,我们的社区很快告诉我们,虽然这是向着正确方向迈出的一个步骤,但该特性仍然缺乏必要的容量。
ACL 中的一个空白已经由 Redis 6.2 处理,即控制发布/订阅频道名称的允许模式。但这只是部分权宜之计,我们花更多时间才想到解决剩余空白的简单且有效的方法。
ACL 的原始设计仅提供基本权限控制用例的供应。它允许仅对每个用户的单个命令集、键和频道名称模式授予或拒绝访问。例如,不可能将`SET` 命令限制到键的一个子集,同时允许`GET`对给定用户的键另一个子集进行操作。实际上,ACL 不是实施安全策略的有效机制。
Redis 7.0 的访问控制列表,简称 ACLv2,与原始版本兼容,但增添了两项重要改进。首先,ACLv2 完全关乎于选择器。其次,ACLv2 允许为特定键设置访问类型权限。这一容量使得将用户专门限制到对键子集只读、只写或读写操作成为可能。
原始的 ACL 设计仅为每个用户提供一个选择器 - 默认选择器。选择器描述用户可以访问的键和频道、类别和命令。ACLv2 允许在按顺序应用的默认选择器之上添加任意数量的选择器。这种方法满足了要求更高安全性的安全策略,使 ACL 更加完整。
Redis 的自省能力是其在 7.0 版本中显著提升的另一个方面。Redis 通过命令字典公开了一个 API,并通过它进行交互。随着项目的演进,不同命令(及其子命令)的数量不断增加,在 7.0 版本中达到 380 多个。由于每个 Redis 命令都是针对特定任务设计的,因此为每个命令的调用参数和行为编制文档是项目的核心原则。此文档是服务器与其客户端之间的唯一契约。
从历史上看,命令以外部文档形式存储在项目本身之外的独立代码仓库中。我们将所有文档都保留为(大部分)人类可读的格式,因为预期由人来阅读。这对机器(或者更确切地说,对编程机器的人)提出了挑战,因为将散文翻译成代码既混乱又不稳定。具体而言,Redis 客户端的作者只能通过监控文档的更改并阅读发行说明,才能使项目保持最新状态。
因此,到了 2.8 版本,我们意识到还需要一种编程方式,允许服务器报告其命令。命名贴切(但也是绕口令)的 `COMMAND` 命令在运行时列出服务器支持的命令。此外,`COMMAND GETKEYS` 子命令允许客户端发送字面命令及其参数,让服务器从其中提取任何键名。需要从命令中提取键名,以便客户端能够在集群部署中正确地执行操作。
一方面是由 ACLv2 相关的工作推动,另一方面也是为了使运行时命令列表对客户端更有用,7.0 版本全面改造了服务器命令管理内部机制的许多部分。此外,我们还丰富了服务器保留的有关每个命令的元数据,使得构建几乎无需事先了解服务器功能的复杂客户端成为可能。最后,改进后的命令表构建方式使得 Redis 模块可以用各自的命令对其进行扩展,以提供与核心命令相同的自省级别。
新的 命令键规范 允许客户端在不涉及集群服务器的情况下从字面命令中本地提取键,从而提高了延迟并降低了网络带宽。命令参数 的元数据允许客户端发现和适应服务器版本之间命令语法中的更改。从 命令提示 中,客户端还能获得有关在特殊情况下和不同部署类型下执行命令的更多信息。
此努力还包括将子命令提升为服务器命令表的一等公民。最初,子命令被引入 Redis 以对抗 API 持续增长的基数。其理由是,不必针对每项任务添加一个新命令,而是通过调用仅一个“父”命令来调用相关任务。该“父”命令将子命令的名称作为其第一个参数,而子命令的名称又决定了要执行的操作。从技术角度看,子命令继承了其父命令的所有特性(例如,ACL 类别、读/写标记、键说明,等等),因此无法获得其不同行为之间的细粒度差异。
例如,“CLIENT”命令是一个用于连接管理任务的大杂烩,拥有不少于 15 个不同的子命令。其中一些子命令,例如“CLIENT SETNAME”,通常由普通客户端连接调用,而另一些子命令,例如“CLIENT KILL”,可能会被滥用,因此应该仅限管理员使用。早期版本的 Redis 缺少支持进行此类区分的内部机制,因此会直接向开发人员提供文档并且会造成困惑。然而,在 Redis 7.0 中,每个子命令都具有自己的特性集,与自己的父级或同级无关,能够准确描述自身。
这篇博文最后演变成了一个文字墙,到了结尾部分可能进入过多技术细节了(如果存在“过多技术细节”这回事的话)。我们希望该博文不会让人觉得无聊,希望它能让我们对新版本及其在项目中的适用性有所了解。我们正在为该版本正式发布候选版做最后的准备,敬请期待系列文章中的下一篇博文,该博文将继续对新版本进行讲解。