zoukankan      html  css  js  c++  java
  • 单进程单线程的Redis如何能够高并发

    redis快的原因:

    1、纯内存操作
    2、异步非阻塞 IO

    参考文档: 

    (1)http://yaocoder.blog.51cto.com/2668309/888374 
    (2)http://www.cnblogs.com/syyong/p/6231326.html

    1、基本原理 
    采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗) 
    (1)为什么不采用多进程或多线程处理?

    多线程处理可能涉及到锁 
    多线程处理会涉及到线程切换而消耗CPU

    (2)单线程处理的缺点?

    无法发挥多核CPU性能,不过可以通过在单机开多个Redis实例来完善

    2、Redis不存在线程安全问题? 
    Redis采用了线程封闭的方式,把任务封闭在一个线程,自然避免了线程安全问题,不过对于需要依赖多个redis操作的复合操作来说,依然需要锁,而且有可能是分布式锁

    3、什么是多路I/O复用(Epoll) 
    (1) 网络IO都是通过Socket实现,Server在某一个端口持续监听,客户端通过Socket(IP+Port)与服务器建立连接(ServerSocket.accept),成功建立连接之后,就可以使用Socket中封装的InputStream和OutputStream进行IO交互了。针对每个客户端,Server都会创建一个新线程专门用于处理 
    (2) 默认情况下,网络IO是阻塞模式,即服务器线程在数据到来之前处于【阻塞】状态,等到数据到达,会自动唤醒服务器线程,着手进行处理。阻塞模式下,一个线程只能处理一个流的IO事件 
    (3) 为了提升服务器线程处理效率,有以下三种思路

    (1)非阻塞【忙轮询】:采用死循环方式轮询每一个流,如果有IO事件就处理,这样可以使得一个线程可以处理多个流,但是效率不高,容易导致CPU空转

    (2)Select代理(无差别轮询):可以观察多个流的IO事件,如果所有流都没有IO事件,则将线程进入阻塞状态,如果有一个或多个发生了IO事件,则唤醒线程去处理。但是还是得遍历所有的流,才能找出哪些流需要处理。如果流个数为N,则时间复杂度为O(N)

    (3)Epoll代理:Select代理有一个缺点,线程在被唤醒后轮询所有的Stream,还是存在无效操作。 Epoll会哪个流发生了怎样的I/O事件通知处理线程,因此对这些流的操作都是有意义的,复杂度降低到了O(1)

    4、其它开源软件采用的模型

    Nginx:多进程单线程模型 
    Memcached:单进程多线程模型

  • 相关阅读:
    Java实现 LeetCode 136 只出现一次的数字
    Java实现 LeetCode 136 只出现一次的数字
    Java实现 LeetCode 136 只出现一次的数字
    Java实现 LeetCode 135 分发糖果
    Java实现 LeetCode 135 分发糖果
    Java实现 LeetCode 135 分发糖果
    Java实现 LeetCode 134 加油站
    Java实现 LeetCode 134 加油站
    Java实现 LeetCode 134 加油站
    Java实现 LeetCode 133 克隆图
  • 原文地址:https://www.cnblogs.com/SuKiWX/p/8383584.html
Copyright © 2011-2022 走看看