Redis作者@antirez 的博文,由NoSQLFan进行翻译。在文中他首先解释了由于Redis集群可能在较长一段时间内还处理开发阶段,为了避免稳定版本由于这一原因被无限延后,于是从2.2版本fork出了一个2.4分支,这一分支目前进行了一些新的优化改进及bug修复,如果没有严重bug将会在近几个星期内发布稳定版本。
优化改进及Bug修复,主要有下面一些:
- sorted sets结构的内存使用做很大的优化
- RDB文件的持久化速度也将会大大提高
- 对目前的一些写操作命令进行了改进,支持批量写入功能
- jemalloc.
- 通过对copy on write机制使用的优化,数据持久化保存的子进程的内存占用将大大减少
- INFO内容更加丰富
- OBJECT命令,提供对Redis存储value结构描述
- CLIENT命令,提供对Redis客户端连接的信息描述
- 彻底将Slave对Master的连接改成非阻塞,之前connect(2)系统调用是会阻塞的
- Redis-benchmark、Redis-cli 都进行了几个方面的改进
- Make 改为彩色输出,更易读
- VM机制彻底废弃
- 总的来说2.4版本会在各方面有性能上的提升
- Redis测试框架也有非常大的提升
后面又详细对其中的一些方面做了深入讲解
1.对Sorted Sets的内存优化
实际上在2.2版本中,Redis就对小数据量Value的情况做了性能优化,主要优化方式是将小数据量的Value值不再按具体的数据结构存储,而是存在一块二进制的整块数据。而这一改进一直没能应用于Sorted Sets数据结构上来,而在2.4版本中,作者终于想到合适的办法把Sorted Sets在小数据量下也进行了此种优化。
2.RDB文件持久化提速
这块很大程度上依赖于上面第1点,由于小量数据被存为一个大的二进制数据块,所以在持久化的时候,就不需要再遍历数据了,只需要一个key进行一次持久化写入。
3.提供批量写入功能
下面是所有提供批量写入功能的命令
- SADD set val1 val2 val3 …
- HDEL hash field2 field3 field3 …
- SREM set val1 val2 val3 … – 返回删除的元素个数
- ZREM zset val1 val2 val3 … – 返回删除的元素个数
- ZADD zset score1 val1 score2 val2 … – 返回添加的元素个数
- LPUSH/RLPUSH list val1 val2 val3 … – 返回操作后的LIST的长度
一次性写入200w个元素,仅仅花费了1.28秒,每秒超过100w元素的写入!
为何不为所有写入命令都加上批量功能呢?作者解释说,由于很多命令在返回值上需要携带信息,如果改成批量的,无法批量返回信息内容。不过相信上面的改进已经可以让很多应用场景得到大大改进了。
4.改用jemalloc的内存分配模式
Redis长期以来的思想就是尽量不产生外部依赖,比如网络事件库没有用传统的libevent库,而是自己单独抽离出几个文件组成的更简单且性能更高的网络事件启动库,这一库目前在很多开源项目中也被采用。而此次引入jemalloc实在是由于作者认为Linux下的glibc的内存分配器实在是太烂了,无法有效地防止碎片的产生。
虽然jemalloc是外部引入,你也不需要在安装Redis时先安装一堆东西,因为它已经包含在Redis源码里了,你还是像往常一样直接Make编译即可,还是那么方便贴心。
5.减少 copy-on-write 使用
AOF日志写入,都是通过调用fork()方法产生子进程来做的。由于主进程还是继续处理请求,当有数据写操作导致数据内容发生变化时,原来的内存段会被复制一份,这就是我们熟知的copy-on-write机制。而采用这一机制的问题就是,在最坏的情况下,进行一次RDB文件写入,可能导致使用内存加倍。所以在2.4版本中,作者对这一机制的使用进行了优化,大大减少了对copy-on-write的使用。
作者还坦言,自己在2.2版本中在这方面的一些修改是有问题的,这导致了2.2版本中的许多Bug。
6.INFO输出内容增强
2.4版本的INFO内容会有较大改变,其中比较重要的有下面两个
used_memory_peak:185680824 used_memory_peak_human:177.08M
你的实际物理内存使用(RSS)和内存碎片情况通常都与最高峰内存使用相关,而这参数就是用来描述这些情况。一个是以byte为单位(185680824),一个是自动智能单位(177.08M)。
7.测试框架的优化和提速
这一点在NoSQLFan之前的文章《Redis 测试引擎将升级提速》中有比较详细的描述。有兴趣的朋友可以查看之前的文章。