为什么 Redis 采用单线程还那么快?

本来在总结并发 B+ 树中的死锁问题,看到笔记里面写着 redis 不用做并发死锁活锁那些东西的处理,于是理解一下这一点。

CPU 速度的定量数据主要根据 jeff dean 10年前的经典文件:Latency Numbers Every Programmer Should Know

Redis 为什么单线程

  • redis 是单线程的,采用 IO multiplexing,因为他是内存数据库,根本没有 CPU 运算瓶颈,只要内存够大,本来内存速度就 10GB/s 左右。redis 采用 Reactor ,能用 epoll select 和 kqueue。主要还是 linux 上的 epoll。
  • 然后 redis 主要是 kv,只需要快速做一次 hashmap 查询或者跳表(ordered map,sorted set 跳表还用在集群查询里,内存数据库当然不用上 B+ tree, B Tree 的内存替代品是红黑树,但是理论跳表可以做到和红黑树差不多的效率,而且跳表进行范围查询很简单,红黑树就很麻烦了,理论可以改装成 B+ 红黑树加一个内部链表,但是这浪费内存)。
  • redis benchmark 支持10万到100万的QPS(1GigEth,TCP localhost,Unix socket 都差不多,其中数据量大的时候因为会分包,所以 Eth 的会拉一点),while memcache 采用了多线程,却只赢了一点点。

Redis 瓶颈不是 CPU 的定量&定性分析

  • 为了严谨,还是用 jeff dean  的 latency 文件来相对阐述数量级,前面说了理论加法一hz一次,那就是 1ns,context swich 大概是几十倍到几百倍,L1 cache 不用运算,0.5ns,if 分支 5ns,读内存两个数量级,所以理论做一次查询 3到 4个数量级的 hz 估计是比较靠谱的了。
  • 我们考虑 10G 的高速网卡,一个 packet 几十个bytes,数量级降了两个,CPU 独立一个核处理(因为 redis 只用单核)中断或者NAPI 的轮询,CPU 1Ghz 的话每秒10亿次运算,因为有流水线,理论一次加法可以一次完成,所以理论对于 100bytes 的数据包来说,1Ghz CPU 应该可以全部处理。实际考虑上下文切换这些,等于每个请求去掉5个数量级的 CPU cycle 来处理,100万QPS 应该不是问题,反而是网卡驱动那边能不能更快的处理数据包,内存缓冲区够不够才是问题。更保守的 10万 QPS 肯定也不在话下(对于 1Gig 的网卡,10万就差不多极限?我感觉5个数量级是保守估计,实际网卡 1Gig 的时候如果全是100byte数据包,一秒最多的请求数是一百万,但是 redis 只能跑 10万,然而考虑上包头包尾,以及各种网络其他控制包,1/10 的网络利用率可能已经很不错了?)。
  • 由于本来应用层也要等到所有的网络数据包成功解出来了才能运作,IO multiplexing 就够用了,所以结论是多线程可能就不必要的了。当然,如果能进一步减少切换,独立的 IO 和 CPU,可能会加快一点,但是考虑到这样也还要计入进行同步原语调用的花费,结果就是像 memcached 那样只能稍微稍微快一点点而已。
  • 并且如果用户的确想多线程加速,完全可以自己开多个 redis 配置在多核机上运行,也是经典 reactor 方案。redis 4.0 之后会引入多线程做一些非主要任务的事情,比如一些其他的后台任务。像持久化(虽然 redis 是内存数据库,这个内存主要指的是 runtime 全部加载到内存)和后台删除。
  • ref:How fast is Redis? – RedisFAQ – Redis

Redis 的数据结构和算法

  • 首先是跳表,跳表上面讲了,注意不要忘记了他比红黑树多的优点(range query)。至于他为什么不用 B 树这个属于常识。
  • 然后是渐进式哈希的算法思路。
  • 渐进式哈希也是经典的空间换时间。渐进式 incremental 这个东西我在学 Garbage Collection 的时候已经熟悉到不得了了属于。思路也很简单,不过就是扩容的时候不全部 rehash(谁会引发 stop the world)保留 bucket 里面的所有东西,然后另开一个新的空间,同时记录当前处于 incremental rehashing 状态,然后每次对字典执行添加、删除、查找或者更新操作时都移动一部分(rehash & relocate)。
  • 实现的话就有点麻烦,不过如果熟悉垃圾回收的增量算法,还是比较通用的实现方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值