CPU并不是您使用Redis的瓶颈,因为通常Redis要么受内存限制,要么受网络限制。例如,使用在一般Linux系统上运行的流水线Redis每秒可以发送一百万个请求,因此,如果您的应用程序主要使用O(N)或O(log(N))命令,则几乎不会使用过多的CPU 。
但是,为了最大程度地利用CPU,您可以在同一服务器上启动多个Redis实例,并将它们视为不同的服务器。在某个时候,单个实例可能还不够,因此,如果您要使用多个CPU,则可以开始考虑更早地分片的某种方法。
但是,在Redis 4.0中,我们开始使Redis具有更多线程。目前,这仅限于在后台删除对象,以及阻止通过Redis模块实现的命令。对于将来的版本,计划是使Redis越来越线程化。
Redis是基于内存操作
的,CPU并不是Redis的瓶颈,Redis的瓶颈是机器的内存
和网络带宽
,既然可以使用单线程来实现,那当然就使用单线程了。
相反,如果使用多线程的话,多个CPU还要进行上下文切换
,CPU上下文切换的效率远远比不上直接在内存中读取的速度;并且,采用多线程,还会带来数据安全的问题,假如我们在操作redis的List、Hash等数据结构时,多线程就可能存在数据不安全的情况,这时候就需要加锁,一旦加锁就又影响了程序的执行速度。
优势
:
劣势
:
4. 无法发挥多核CPU性能(可以通过在单机开多个Redis实例来完善,单一线程只能用到一个CPU核心,所以可以在同一个多核的服务器中,启动多个实例,组成master-master
或者master-slave
的形式,耗时的读命令可以完全在 slave 进行,充分发挥 Redis 的作用)。
减少了线程切换时上下文的切换和竞争
,也不存在多进程或者多线程导致的切换而消耗CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;非阻塞I/O多路复用机制
。redis 采用网络IO多路复用技术,来保证在多连接的时候系统的高吞吐量。
多路
指的是多个socket网络连接,复用
指的是复用一个线程。
多路复用主要有三种技术:select,poll,epoll(epoll是最新的、也是目前最好的多路复用技术),可以同时监察多个流的 I/O 事件,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流,并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作,从而提高效率。
采用多路I/O复用技术的原因:
主要以上两点造就了Redis具有很高的吞吐量。
由于redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。
redis提供两种方式进行持久化,一种是RDB持久化
(原理是将redis在内存中的数据库记录定时 dump到磁盘上的RDB持久化),另外一种是AOF(append only file)持久化
(原理是将redis的操作日志以追加的方式写入文件)。
持久化似乎和redis的速度并没有直接关系,但是这保证的redis数据的安全性和可靠性,也起到数据备份的作用。