写点什么

5 个步骤构建优质 Redis 模块

  • 2020-03-01
  • 本文字数:2515 字

    阅读完需:约 8 分钟

5个步骤构建优质Redis模块

编写 Redis 模块时,请牢记以下五个步骤。虽然这份清单并不详尽,但是如果你还没有太多的模块构建经验,我还是能为你提供一个很好的入门方法的。

1、确定一个有吸引力的模块用例

Redis 有大量的工具可以让你构建所需的解决方案。一个例子就是锁。通过将 SET 与 NX 选项一起使用,你可以创建一个锁的 key,并将其与 EXPIRE 结合使用,即可得到一个锁租约。这在解决协调一致问题时非常有用。当内置命令还不够用时,你还可以使用 Lua 脚本,这些脚本为复合操作添加了完全的可编程性,然后由 Redis 原子地执行这些操作。


与 Lua 相比,模块在访问低层次 API 的能力方面,具有更大的灵活性和更快的速度,但是它们在维护和分发方面更具挑战性。仅在 Lua 不能完全适用你的用例时才使用模块。


模块可以添加新的命令


模块可以使用 C 语言向 Redis 添加新的命令(确切地说,你也可以使用 Rust,Zig 或任何 C-ABI 兼容语言)。你在功能上做什么取决于你自己。可以从实现与现有命令相似但可以有更多功能的命令开始。SETNE(由用户在此 GitHub Pull Request 中首次提到)就是一个示例。SETNE 的行为与 SET 完全相同,但是当新值等于当前值时,它不会修改键值,从而避免产生假的键空间通知。通常,要进行一些练习,可以考虑对现有命令添加一些附加功能,以帮助处理特定的用例。


大多数这些小的附加功能最好使用 Lua 脚本来实现,如果你刚开始想不出有吸引力的模块,这将是一种好方式。留给读者的几个练习:SETEQ,HINCRDATEBY。


模块可以添加新的数据类型


模块向 Redis 添加功能的最有效方法是添加新的数据类型。Redis 非常注重数据结构及其相关算法和属性的设计。尽管你可能不知道 Set 数据类型具体是怎么实现的,但是你肯定知道 SISMEMBER 命令执行很快,却与 Set 大小无关(例如,它具有亚线性渐近复杂度)。| 有关 BigO /渐近复杂度和 Redis 数据类型的重要性的介绍,请查看 Rob Conery 的演讲:https://www.youtube.com/watch?v=znYgNXN98Ag


这是我们自己的模块背后的基础:


•RediSearch 是基于倒排索引的全文本搜索模块。


•RedisGraph 是基于稀疏矩阵的图形模块。


•RedisTimeSeries 与 Redis Streams 类似,但针对数字序列进行了优化。


•RedisBloom 提供了一些不同的概率数据结构。


•RedisAI 运行 Tensorflow 深度学习图(以及其他一些类型)。


这些是很重要的模块,但并不是每个引入新数据类型的模块都必须如此复杂。有许多更简单的数据类型可用作模块。一个基本的示例就是 Redis 中已经存在的数据类型的不同实现,例如,使用 ArrayList 实现 List。

2、完善你的 API

不要忘记模块命令的错误用法与正确用法一样重要。Redis 用户喜欢手动调试命令以获得更好的理解,并且会输入一些错误的参数。你的 API 应该易于使用且难以滥用,但是当不可避免的情况出现时,请确保输出的错误信息是有意义的。


查看 Redis 的标准命令是如何工作的,然后看看执行你自己的命令得到的结果是否符合相应的假设。这将减少使用命令所需的心理负担。一个例子是,在 Redis 中,当调用一个不存在的键时,大多数命令都有合理的行为:INCR 会假定缺少的键值为 0,因此它会将其设置为 1,SADD 会假定缺少的键是空键,依此类推。

3、做一个好公民

模块需要可以与 Redis 生态进行交互。确保阅读文档以了解如何正确获取详细信息,尤其是当你的模块实现了新的数据类型时。这是两个最重要的方面。


命令标志


声明新的命令时,必须指定一些标志来告诉 Redis 调用命令时将要执行的操作。它是要读取数据还是要写入数据?是分配内存还是只是修改现有的数据?确保正确填写这些选项。例如,在内存不足(OOM)的情况下,deny-oom 是一个重要标志,它将告诉 Redis 拒绝访问分配内存的命令,否则整个进程将被 OOM 杀掉!即使是只读标志也很重要。新的客户端缓存功能将使用它来决定是否启用对给定 key 的跟踪。


命令复制


当 Redis 是主从模式时,主服务器必须知道应该将哪些命令发送给从服务器。并非每个命令都应复制,某些命令可能仅在特定条件下才需要复制。例如,我上面提到的 SETNE 命令,该命令仅在新值与当前值不同时才设置 key 和 value(否则它什么也不做)。在这种情况下,仅当命令有效地对 key 进行更改时,才应复制该命令。如果没有执行任何写操作,就不用让每个从服务器都执行该命令。

4、撰写出色的文档

如果你的模块都没有人知道如何使用,那么无论它多么有用都没有意义。因此完善 API 文档会有很大帮助,至少你首先得说服潜在用户该模块是值得尝试的。一个好的模块应该具有好的文档,这些文档可以明确该模块的总体目标并列出每个命令的详细信息。


如果看一下 redis.io,你就会发现每个命令都列出了其相对的 BigO 复杂性,并在命令具有特别大或小的常量或有明显边界情况时提供了一些额外的说明。尝试模仿这样的格式,尤其是在命令示例的语法方面。请注意,每个示例都是用小写字母命名占位符,大写字母表示关键字,方括号之间是可选值。查看 SET 的文档https://redis.io/commands/set 以查看此示例。


最重要的是:力求简单


始终牢记,Redis 背后的第一个设计原则是简单。这并不是说你的模块就只有这一种选择,偶尔还是可以为了其他好处而牺牲这种简单性(模块的存在正是为了让 Redis 用户体验),但要时刻注意你所放弃的东西。


一般而言,当你为了方便使用而牺牲了简单性时,也隐含地限制了用户使用模块的方式。在 Redis 中,大多数程序并不是单独使用某个命令,而是将不同的命令组合在一起使用。更小,更清晰,更简单的命令会更易于组合,因此在整体方案中会产生更好的效果。因此,我建议在进行这种权衡之前,通过适当地应用上述技术来提高易用性。


另一个潜在的权衡取舍可能是执行效率。这可能值得探索,也是 Redis 偶尔做的一个。某些内置数据类型具有两种内部的优化方式:一种是在数据类型中只有几个元素时进行优化,另一种针对 key 增长超过某个阈值时进行优化。两种方式(加上在两种方式之间进行切换的机制)肯定比只有一种方式更为复杂,但是这样做是值得的。因为增加的复杂性不会显示在用户界面中,无论使用哪种内部优化的方式,用户都将以相同的方式与数据类型进行交互。


本文转载自 中间件小哥 公众号。


原文链接:https://mp.weixin.qq.com/s/x6WTI25xBeFhdqSv65ph0Q


2020-03-01 21:421787

评论

发布
暂无评论
发现更多内容

ETLCloud:重新定义AI驱动的数据集成未来

谷云科技RestCloud

人工智能 AI 数字化转型 ETL 数据集成

使用 Amazon Q Developer CLI 调用 MCP Server 实现 Amazon Support 案例自动创建

亚马逊云科技 (Amazon Web Services)

Go语言是现在进大厂的捷径?快来看看Golang学习语言图

Geek_Yin

Java 程序员 java面试 Java面试题

油气行业AI转型的三昧真火

脑极体

AI

通义灵码你问我答:看看 5 月上线了哪些新功能?

阿里巴巴云原生

BeeWorks 协同办公能力:局域网内企业级协作的全场景重构

BeeWorks

即时通讯 IM 私有化部署

95年,28岁、聊聊外包四年的真实感受

Geek_Yin

Java 程序员 java面试 Java面试题

面了个腾讯拿 38K 出来的,让我见识到了基础的天花板

Geek_Yin

Java 程序员 Java 面试题 java 架构

OpenAI SDK 上新 RealtimeAgent;OpenAudio S1 语音生成模型:语调情感标记,精确控制风格

RTE开发者社区

鸿蒙仓颉语言开发实战教程:商城搜索页

幽蓝计划

出版社教学资源网的主要功能

北京木奇移动技术有限公司

AI教育 软件外包公司 出版社 教学资源网

数字人如何通过垂类营销大模型获得“行业超脑”的能力

东信营销科技

智能体 #AI AI营销 #数字人 #东信营销科技

TortoiseSVN使用-合并深度介绍

刘大猫

人工智能 svn 算法 数据分析 tortoiseSVN

VMware VeloCloud SD-WAN 6.2 新增功能简介

sysin

velocloud

通义灵码你问我答:看看 5 月上线了哪些新功能?

阿里云云效

软件测试 | 使用 Playwright 实现滑动验证码

测试人

软件测试

相较于其他局域网聊天工具,BeeWorks优势在哪?

BeeWorks

即时通讯 IM 私有化部署

IM即时通讯软件,构建企业局域网内安全协作

BeeWorks

即时通讯IM 私有化部署

企业im,为企业设计的私有化即时通讯工具

BeeWorks

即时通讯 IM 私有化部署

React-native实战系列

溪抱鱼

前端 React

AI浪潮下的认知重构:从一个数据老兵的转型思考

金松(李博源)

职场 职业转型 #大模型 #产品经理

华为初面 + 综合面试,附上面试题,share 给大家~

Geek_Yin

Java 程序员 java面试 Java面试题

其实,从程序员到架构师,只需要掌握这些知识点就够了!

程序员高级码农

程序员 架构师

Rocky Linux 9.6 正式版发布 - RHEL 100% 1:1 兼容免费发行版

sysin

Rocky

出版社题库系统的开发

北京木奇移动技术有限公司

题库系统 软件外包公司 出版社

AI Agent 工程师绕不开的必修课:API 网关 vs API 管理

阿里巴巴云原生

阿里云 AI 云原生 API网关

全网首发!马士兵内部共享—1658页《Java面试突击核心讲》

Geek_Yin

Java 程序员 Java面试题

AI Agent需要什么样的数据库?

元闰子

2025Go面试八股(含100道答案)

王中阳Go

Go 最新面试题

什么是低代码?2025年低代码开发平台发展现状及标准化研究

优秀

低代码 低代码开发平台

驶向智能未来:车载 MCP 服务与边缘计算驱动的驾驶数据交互新体验

EMQ映云科技

人工智能 边缘计算 大模型 MCP

5个步骤构建优质Redis模块_文化 & 方法_翻译自redis.io_InfoQ精选文章