Redis 的 CLIENT SETINFO 指令
潘忠显 / 2024-10-10
今天来介绍一下 Redis 7.2 版本中引入的 CLIENT SETINFO/SETNAME
指令,其加入目的、作用以及对你开发的影响。
背景
最近用 Python 实现的一个简单的服务,用到 Redis,本地测试 OK,但是发布到线上会建立连接失败。
建立连接的代码很常见:
r = redis.StrictRedis(host=redis_host, port=redis_port, password=redis_password)
简单的抓了一下包,发现是新版本的软件包,会在连接鉴权后,发送一个 CLENT SETINFO
指令。虽然本地和正式环境的 Redis 都不支持该指令,但由于正式环境的 Redis 在遇到不支持的指令,会直接关掉连接,而本地遇到不会断开连接。因此导致正式环境无法建立连接。
解决方法也很简单,就是将两个参数设置为 None
,以替代默认参数,就不会调用该指令了。
r = redis.StrictRedis(host=redis_host, port=redis_port, password=redis_password,
lib_name=None, lib_version=None)
接下来我们就来了解一下,为什么 Redis 库会默认加上这个指令,这个 CLIENT SETINFO
的作用到底是什么?
为什么引入 CLIENT SETINFO
类似指令
引入 CLIENT SETINFO
等命令,使得对客户端的管理更加灵活和细致。

该指令用于给一个连接打上库名和版本的信息。其实,还有另外一个指令 CLIENT SETNAME
就是直接给连接命名:

这样的指令,可以让你给当前连接打上一个标签,方便后续对这个连接进行识别和管理。可以通过 CLIENT LIST
或 CLIENT INFO
或 CLIENT GETNAME
命令查看当前连接的这些信息。
直接影响当然就是你的连接有了名字(以及其他信息),从 Client 或者 Server 侧都能用于做区分:
- 标识连接来源: 你可以给不同的客户端设置不同的名称,方便追踪连接来源。例如,你可以将来自 Web 服务器的连接命名为 “web_server”,来自后台任务的连接命名为 “background_task”。
- 区分连接类型: 如果你的 Redis 实例同时服务于多个不同的应用程序,你可以使用 CLIENT SETINFO 来区分不同类型的连接。例如,你可以将实时数据流的连接命名为 “realtime_stream”。
带来的进一步的好处,我们也比较容易理解,有了名字在问题排查和连接管理上就会变得简单:
- 监控和告警:你可以根据连接名称来设置不同的监控告警规则。例如 Redis 的连接异常告警可以带上连接名的标签,如果来自 “web_server” 的连接出现异常,很容易就知道出问题的具体服务。
- 调试和排查问题: 我们现在遇到 Redis 排查问题,先找 DBA 查日志,找出慢查询的 Key,然后四处问,这是谁操作的 key 呀?如果有了连接名,日志中可以直接过滤出慢查询的连接名称,从而找到对应的应用程序。
- 访问控制: 虽然 Redis 本身没有非常完善的访问控制机制,但你可以结合 CLIENT SETINFO 和 Lua 脚本实现一些简单的访问控制。例如,你可以限制某些连接只能执行特定的命令。
怎么样,学到了吧?
Redis 换了新 Logo
2024年4月,Redis 换新 Logo 了。如果你偶尔登录 Redis 官网查文档,你可能已经发现了吧?

又谈版本号
Redis CLIENT SETINFO 命令是在 Redis 7.2 版本中引入的。 你有没有发现,这里你常用的 Redis 版本都是偶数版本?比如 Redis 6.0、6.2、7.0、7.2 等等。
这种偶数结尾的版本标识意味着这些版本经过了充分的测试,适合在生产环境中使用。相对地,奇数结尾的版本如 Redis 6.1 可能是开发版本或者候选版本,这些版本包含了新的功能和改进,但可能还没有经过足够的测试以确保其稳定性。
见多识广的你肯定知道,很多软件会使用偶数/奇数模型来区分稳定版和开发版的方式。我甚至记得有书上还特意以 Linux 内核为例介绍过,比如著名的 2.6 版本。
但时过境迁,在敏捷开发的当下,很多软件的都放弃了这种奇偶区分是否稳定的方式,其中也包括 Linux 内核版本的维护,转而采用了时间驱动的发布模式。现在的 Linux 内核版本(如 Linux 5.x 或 Linux 6.x),都是按照这种新的发布策略进行的。
前文《为什么要升级编译器》中介绍的 Go 的版本发布历史,也是每半年会更新一个版本,不区分是否稳定:

Gemini 比 GPT 更有实效性?
我在查询 Redis CLIENT
指令的时候,去问了 GPT,比较了一下发现 Gemini 好像比 ChatGPT 的实效性更好一些。没比较过别的方面,欢迎留言讨论。
