【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
突然想写点关于redis代码分析的东东,但是前人已经积累了很多。
我就不写出来自娱自乐了,那就紧贴redis最新版,介绍具体发生什么变化
OK,一切从Changelog开始:
[ Redis 2.6.11 ]
UPGRADE URGENCY: LOW, however updating is encouraged if you have many instances per server and you want to lower the CPU / energy usage.
- [BUGFIX] Replication: more strict error checking for master PING reply.
- [BUGFIX] redis-cli: use keepalive socket option for improved reliability.
- [BUGFIX] Allow AUTH while loading the DB in memory.
- [BUGFIX] Don't segfault on unbalanced quotes while parsing config file.
- [IMPROVED] serverCron() frequency is now a runtime parameter (was REDIS_HZ).
- [IMPROVED] Use a lot less CPU when idle, even with many configured DBs.
[BUGFIX] Replication: more strict error checking for master PING reply.
对应 commit :
34b420dbf3ca6ac82be458405752992a8132c32e
说明 :
对于使用了 requirepass 选项的master,slave机器连接时将报 "Unexpected reply to PING from master." 错误
[BUGFIX] redis-cli: use keepalive socket option for improved reliability.
对应 commit :
e9318d92dbee9421409f6959fc089fa25b90e9a3
说明 :
作者说明了两点理由:
-
- Prevent timeouts caused by the execution of long commands.
-
- Improve detection of real connection errors.
这儿简单解释一下: 对于长期空闲的tcp连接很容易被NAT、防火墙等直接close掉。这情况下对于client和server在没IO操作下,都是没办感知的。另外,像Server程序或网络(硬件)突然Crash掉,也是同样的情况。使用keepalive,内核会定时帮你发送一个空的ACK包,如果连接已断开或网络不可达,就会收到RST。btw,在Redis中,Server也可以设置keepalive,具体配置项是 tcp-keepalive
[BUGFIX] Allow AUTH while loading the DB in memory.
对应 commit :
a3273dbfa6435106bcadeb281303821e31c8ce73
说明 :
这儿增加了 'l' 标志,在redis中表示REDIS_CMD_LOADING,直观地说,就是允许redis仍在loading阶段(初始化、读rdb等等)就可以接收指令,详见populateCommandTable和processCommand两个函数。同样为'l'标志的有sub/pub相关的cmd和info。
[BUGFIX] Don't segfault on unbalanced quotes while parsing config file.
对应 commit :
a3273dbfa6435106bcadeb281303821e31c8ce73
说明 : 略... 不重要
[IMPROVED] serverCron() frequency is now a runtime parameter (was REDIS_HZ).
对应 commit :
aec5ea5d0751595cf0992190db6de077a7acbece
说明 :
把原来写死的宏定义REDIS_HZ改成可配置化。REDIS_HZ 表示每秒钟执行serverCron的次数,通过redis的aeCreateTimeEvent来实现。如果你也看过redis代码,应该会知道,几乎所有的定时任务都在serverCron里执行,并通过server.cronloops来控制执行的频度。
[IMPROVED] Use a lot less CPU when idle, even with many configured DBs.
对应 commit :
(这个作者实现上修改了多次,这儿就不列commit了,自己diff吧,源文件)
说明 :
主要为databasesCron和activeExpireCycle两个函数的更改。他们的实现方式大体是相似的:
- 限定每次cron只执行最多16个db的相关处理
- 使用一个static的变量,来保存当前处理的进度(dbid),下次接着处理。
现在redis可以自动定时rehash了:)
但是,在极端情况下,定时任务会花16*1ms的时间执行databasesCron
###其他没提到的修改###
增加lookupCommandOrOriginal API
对应 commit :
e7a61d287ed8912b2f855408d9f6707afa5ea6c7
说明 :
防止使用rename-command导致各种各样的问题,但作者没完全修复(可能在后续版本会改进),只fix了issue #986 所提到的问题。具体实现就是先后在server.commands和server.orig_commands两个dict里dictFetchValue,前者可能被rename-command过的,后者木有。在populateCommandTable函数里,同时填了这两个dict。
来源:oschina
链接:https://my.oschina.net/u/148003/blog/119251