1:redis为什么这么快
redis是基于内存的,内存的读写速度非常快
redis是单线程的,省去了很多上下文切换的时间
redis采用了多路复用技术,可以处理并发的连接。非阻塞IO内部采用epoll,而且redis自己实现了事件分离器效率高。epoll中的读、写、关闭等等都转化成了事件,绝不在IO上浪费一点时间。
2:redis为什么采用单线程
redis是基于内存的操作,cpu不是redis的瓶颈,redis的瓶颈最有可能是机器的内存和网络带宽。单线程最容易实现而且cpu又不会成为瓶颈,那么采用单线程的方案肯定就顺理成章了。。多线程处理会涉及到锁而且多线程处理会涉及到县城切换而消耗cpu。
redis的数据结构并不全是简单的key-value,还有list、hash、set、zset等复杂的结构,如果不是单线程的话:这些结构有可能会进行很细粒度的操作,如很长的列表中间插入一个元素,在hash当中插入或者删除一个对象。这些操作可能需要加入非常多的锁,加锁的结果是同步开销大大增加。总之在单线程的情况下,就不用去考虑各种锁的问题,不存在加锁释放锁的操作,也就没有了可能出现死锁而导致的性能消耗。
单线程+多进程 组成集群
采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程切换 带来的cpu消耗。如果cpu成为redis的瓶颈,可以考虑多起几个redis进程,redis是key-value数据库,不是关系数据库,数据之间没有约束,只要分清楚哪些key存放在哪个redis进程上就好了。。
3:redis单线程的优势和劣势
优势:代码清晰、处理逻辑更简单。不用去考虑各种锁的问题,不存在加锁释放锁的操作,没有因为可能出现死锁而导致的性能消耗。不存在多进程or多线程切换带来的cpu消耗
弊端:无法发挥多核cpu性能,可以在单机上通过启动多个redis实例来完善
4:IO多路复用技术
多路:多个socket 连接(网络连接)
复用:复用一个线程。
采用多路复用技术,可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗),而且redis在内存中的操作数据速度非常快(内存当中的操作不会成为这里的性能瓶颈)
所以单线程+IO多路复用造就了redis具有很高的吞吐量
每秒可以处理几十万的请求
总结:
redis是纯内存数据库,一般都是简单的内存操作,线程占用的时间很多,时间的花费主要集中在IO上,所以读取速度快
再说下IO,redis使用的是非阻塞IO,IO多路复用,使用了单线程来轮训描述符,将数据库的开、关、读、写都转成了事件,减少了线程切换时上下文的切换和竞争。
redis采用了单线程的模型,保证了每个操作的原子性,也减少了线程的上下文切换和竞争
数据结构也帮了不少忙,redis全程使用hash结构,读取速度快,还有一些特殊的数据结构,对数据存储进行优化,比如压缩表,对短数据进行压缩存储,再如跳表,使用有序的数据结构加快读取速度
redis采用自己实现的事件分离器,效率高,内部采用非阻塞的执行方式,吞吐能力大