redis6.0之后的多线程版本的问题
一、redis早期版本和新版本的讨论
这个问题其实有些废话,哪个版本肯定都有不同啊。其实这里主要是提到的网上的大家对Redis6.0中的多线程版本的不同即以前宣传的Redis是单线程程版的,之后变成了多线程版本的。网上对这个讨论非常激烈,反正各种说法都有。
其实,结论只有一个,很多讨论的人都是就事论事,没有真正看源码也没有看所谓多线程和单线程应对的场景也就是Redis的正常应用下,它的适应情况。所以,往往大家抓住一个点,开始各种各种表达,然后就没然后了,为了讨论而讨论。
二、redis的单线程和多线程版本
既然是讨论,不妨咱们也多句嘴,百花齐放一下。对Redis来说,其做为一种内存型数据库,其主要目的就是在内存中存储键值对,也就是常说的KV数据。对内存操作来说,速度有多快,开发者们不想都可以知道。假设有一种存储能快到和Cache一样的速度并且容量大,那么多线程意义更不大。前面分析过,所谓各种的处理手段的目的就是为了解决计算机中资源处理速度的不匹配而出来的,多线程也是如此(当然,不能说完全是为了这个)。
那么如果从这种思想出发,可以发现,内存对网络IO的速度那是辗压级别的。好,回头看一下Redis的单线程模型的主要内容:
从上层来看就是一个线程+IO多路复用(epoll或 kevent 或 select)。一个线程对应着这种IO多路复用,恰恰正是优势所在。而前面的网络系列中分析过,无论哪种多路复用,一个前提是,活跃的连接一定不能太多,否则其基本的速度都是差不多的,甚至还不如最简单的select。
如果你要坚持开多个IO多路复用,对Redis这种多点部署的程序来说,不如多部署几个节点。也就是说,需要考虑多点和多线程间的效率、成本和其它条件了。
所以说,所谓单线程指的是这一部分,而不是说整个Redis没有使用多线程,这是第一个要明白的单线程和多线程的区别;其次,单线程在这种环境下,相对多线程至少没有劣势,特别成开发、维护等上反而更有优势。
三、应用场景的分析
在设计和开发一个软件时,最初一定是为了达到自己的某些想法或者说设定目标,如果这种想法和目标不需要某种复杂的技术就可以实现,那么为什么要杀鸡用牛刀呢?换句话说,如果小学的知识可以解决的问题,为什么非要升级到大学知识才去解决呢?但反过来又想,目前小学知识可以解决这个问题,可过了两年发现新的应用场景或者目标如果用到中学的会更好,大学的会更好?做为问题的解决者,你会怎么办?或者可以理解成,可不可以老中青三年一起来解决问题呢?这样想就明白了Redis多线程版本了。推而广之,也就明白了所有的软件迭代升级的特点了。
与时俱进,是每一个人必须掌握的基本思想。
做为内存型的数据库,快是最主要的一种特点。而数据库最典型的特征就是要读写数据到数据库。这二者的目标提出来,可以用后来者的眼光分析一下,多线程在这种场景下是否比单线程更有优势,而且这种优势必须是全面的,成倍以上的。这是什么意思呢。全面,必须要考虑技术的先进性和安全稳定性;也要兼顾容易开发和后期的易维护性,还有其它如成本等等。而不是单纯的考虑一个技术问题。另外,如果使用一项新技术仅仅比旧的技术提高了不多的效率,那么整体的成本仍然是让人无法忍受的。
具体到Redis,其最主要的核心是通过网络接收数据然后通过处理读写内存,这是最基础最核心的需求。前面分析过多路复用,然后再增加一个线程搞一搞读写,既可以快速操作内存,又可以防止出现多线程中的数据一致性和锁,同步等问题。这样一看,单线程没有啥劣势啊,甚至还有优势。然后,再实际测试一下,多线程与单线程在这种情况下,根本没有什么大的优势。而且官方的声明中也提到了:在这种内存IO的数据库中,限制性能的瓶颈不是CPU,而是内存大小和网络IO的处理(注意,这也是后来升到多线程的一个重要原因)。
那么既然不是瓶颈,为什么Redis6要升级多线程呢?
仍然回头看Redis的主流应用线程+IO多路复用。这里有没有可以使用多线程进行优化,从而进一步提高效率的呢?特别是随着Redis的广泛应用,一些复杂的命令和数据结构也被应用上来,协议也在不断的升级和扩充等等。有过网络开发经验的开发者会想到,在网络开发中,高并发是一个重要的特点,虽然不能在同一时间有大量活跃,但可以轮换活跃,保持着一种中等并发的持续性应用。那么此时一个瓶颈出现了,多路复用中,读和写的处理以及监听的处理速度往往不匹配;而且数据读出来的原始解析(解析协议)也很浪费时间,可不可以用一些线程来处理这些功能呢?这些功能如果用多线程处理能提高多少效率呢?会增加多少开发和维护成本呢?而且物理硬件也在不断的推陈出新,多核的CPU已经被广泛在服务器中应用,一些新的技术也涌现出来。这对Redis的开发维护者也提出了更高的要求。
从Redis6.0中提供了这个多线程版本来看,应该是效率明显的,不然不会推出。但仔细看源码,发现整个Redis6.0的核心命令执行仍然是单线程的,这是什么意思?就是最初的设计的意思,简单、安全而又保证效率的情况下,为什么要引入多线程呢?
那么以后会不会继续改进甚至全部改成多线程呢?这个还是得看发展。如果协程被广泛应用后,可以就是协程版了,大家说有没有这种可能?
四、总结
早就跟大家一起分享过,一定要抓住事物本质。针对软件就是找到其应用的目的,其核心思想是什么,而不是简单的说哪种技术好,哪种技术不好。最合适的就最好的,而这个最合适一定是随着应用的发展不断的变化的。孤立的、片面的和僵化的看问题,就很容易陷入到无何止的争论中去。教条主义、本本主义和经验主义,其实大家都犯,但一定要记得打破这层牢笼。否则,就会固步自封,难建寸功。
所以科学和哲学,往往是无法分开的。这也是学习一些思想的目的和原因。