高性能IO模型:为什么单线程Redis能那么快?( 二 )
讲到这里 , 你应该已经明白了“Redis为什么用单线程” , 那么 , 接下来 , 我们就来看看 , 为什么单线程Redis能获得高性能 。
单线程Redis为什么那么快?
你好 , 我是蒋德钧 。
今天 , 我们来探讨一个很多人都很关心的问题:“为什么单线程的Redis能那么快?”
首先 , 我要和你厘清一个事实 , 我们通常说 , Redis是单线程 , 主要是指Redis的网络IO和键值对读写是由一个线程来完成的 , 这也是Redis对外提供键值存储服务的主要流程 。 但Redis的其他功能 , 比如持久化、异步删除、集群数据同步等 , 其实是由额外的线程执行的 。
所以 , 严格来说 , Redis并不是单线程 , 但是我们一般把Redis称为单线程高性能 , 这样显得“酷”些 。 接下来 , 我也会把Redis称为单线程模式 。 而且 , 这也会促使你紧接着提问:“为什么用单线程?为什么单线程能这么快?”
要弄明白这个问题 , 我们就要深入地学习下Redis的单线程设计机制以及多路复用机制 。 之后你在调优Redis性能时 , 也能更有针对性地避免会导致Redis单线程阻塞的操作 , 例如执行复杂度高的命令 。
【高性能IO模型:为什么单线程Redis能那么快?】好了 , 话不多说 , 接下来 , 我们就先来学习下Redis采用单线程的原因 。
Redis为什么用单线程?
要更好地理解Redis为什么用单线程 , 我们就要先了解多线程的开销 。
多线程的开销
日常写程序时 , 我们经常会听到一种说法:“使用多线程 , 可以增加系统吞吐率 , 或是可以增加系统扩展性 。 ”的确 , 对于一个多线程的系统来说 , 在有合理的资源分配的情况下 , 可以增加系统中处理请求操作的资源实体 , 进而提升系统能够同时处理的请求数 , 即吞吐率 。 下面的左图是我们采用多线程时所期待的结果 。
但是 , 请你注意 , 通常情况下 , 在我们采用多线程后 , 如果没有良好的系统设计 , 实际得到的结果 , 其实是右图所展示的那样 。 我们刚开始增加线程数时 , 系统吞吐率会增加 , 但是 , 再进一步增加线程时 , 系统吞吐率就增长迟缓了 , 有时甚至还会出现下降的情况 。
文章图片
为什么会出现这种情况呢?一个关键的瓶颈在于 , 系统中通常会存在被多线程同时访问的共享资源 , 比如一个共享的数据结构 。 当有多个线程要修改这个共享资源时 , 为了保证共享资源的正确性 , 就需要有额外的机制进行保证 , 而这个额外的机制 , 就会带来额外的开销 。
拿Redis来说 , 在上节课中 , 我提到过 , Redis有List的数据类型 , 并提供出队(LPOP)和入队(LPUSH)操作 。 假设Redis采用多线程设计 , 如下图所示 , 现在有两个线程A和B , 线程A对一个List做LPUSH操作 , 并对队列长度加1 。 同时 , 线程B对该List执行LPOP操作 , 并对队列长度减1 。 为了保证队列长度的正确性 , Redis需要让线程A和B的LPUSH和LPOP串行执行 , 这样一来 , Redis可以无误地记录它们对List长度的修改 。 否则 , 我们可能就会得到错误的长度结果 。
这就是多线程编程模式面临的共享资源的并发访问控制问题 。
文章图片
并发访问控制一直是多线程开发中的一个难点问题 , 如果没有精细的设计 , 比如说 , 只是简单地采用一个粗粒度互斥锁 , 就会出现不理想的结果:即使增加了线程 , 大部分线程也在等待获取访问共享资源的互斥锁 , 并行变串行 , 系统吞吐率并没有随着线程的增加而增加 。
- 阳光房型材为什么用铝合金?
- dram|为什么工业计算机是移动监控的关键组件?
- |为什么你亚马逊广告的ACOS那么高?
- |单板计算机为什么对于嵌入式计算设计很重要?
- |中国最大光刻机企业已被美列入黑名单,为什么还不与华为联手研发?
- 华为|Mate50系列为什么会一机难求?
- iPhone|印度网友的迷惑提问:为什么中国厂商没有能力生产高质量产品?
- 乔布斯|感慨!为什么乔布斯终其一生都未与生父相认?
- 在之前的文章中|宇宙形成的第一个分子是什么,为什么不是氢分子
- 京东|嵌入式开发中为什么选择C语言?它有哪些特点?