转自:https://www.zhihu.com/question/23162208 https://www.zhihu.com/question/55818031;加了一些个人的理解。

Redis为什么是单线程的?(注:并不是说redis内部只有一个线程,而是说执行同步队列中的命令对象是统一由一个线程来poll的,但是和客户端的交互是可以为多线程)

因为CPU不是Redis的瓶颈。Redis的瓶颈最有可能是机器内存或者网络带宽。(以上主要来自官方FAQ)既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。关于redis的性能,官方网站也有,普通笔记本轻松处理每秒几十万的请求,参见:How fast is Redis?

如果万一CPU成为你的Redis瓶颈了,或者,你就是不想让服务器其他核闲置,那怎么办?(注:因为一个redis里key不能重复,因此一般来说有多少个应用需要redis就可以开启多少个redis进程,或者每个key都应该有对应的应用后缀和ops后缀;或者通过select每个模块都选择不同的库但需要自己记录好index对应的模块名)

那也很简单,你多起几个Redis进程就好了。Redis是keyvalue数据库,又不是关系数据库,数据之间没有约束。只要客户端分清哪些key放在哪个Redis进程上就可以了。redis-cluster可以帮你做的更好。

单线程可以处理高并发请求吗?

当然可以了,Redis都实现了。

有一点概念需要澄清,并发并不是并行。

(相关概念:并发性I/O流,意味着能够让一个计算单元来处理来自多个客户端的流请求。并行性,意味着服务器能够同时执行几个事情,具有多个计算单元)

Redis总体快速的原因:

采用队列模式将并发访问变为串行访问(?)(注:这里个人认为是的,之前自己写了个日志系统也是采用命令队列的形式,每次log都是提交一个日志命令,然后由单独的线程对此队列poll,如果poll为null,这wait,而每次log都会notifyAll唤醒此线程去poll命令执行)

单线程指的是网络请求模块使用了一个线程(所以不需考虑并发安全性),其他模块仍用了多个线程。(注:这里个人不认可,redis是可以同时和多个客户端打交道的,因此网络请求是可以为多线程或线程池,不过redis的命令队列是同步队列[有点像java的vector],然后由一个单独的线程从这个队列里poll 命令/事务 并执行)

总体来说快速的原因如下:

1)绝大部分请求是纯粹的内存操作(非常快速)

2)采用单线程,避免了不必要的上下文切换和竞争条件(注:指获取命令或事务并执行的线程,执行完后获得的结果将提供给线程池中和客户的连接的socket/socketchannel对象去返回,包括返回错误消息或成功消息或返回值)

3)非阻塞IO(注:tcp通信方面,对于java可以理解为用的是nio)

内部实现采用epoll,采用了epoll+自己实现的简单的事件框架。epoll中的读、写、关闭、连接都转化成了事件,然后利用epoll的多路复用特性,绝不在io上浪费一点时间

这3个条件不是相互独立的,特别是第一条,如果请求都是耗时的,采用单线程吞吐量及性能可想而知了。应该说redis为特殊的场景选择了合适的技术方案。

======

1. Redis服务端是个单线程的架构,不同的Client虽然看似可以同时保持连接,但发出去的命令是序列化执行的,这在通常的数据库理论下是最高级别的隔离(serialize)
2. 用MULTI/EXEC 来把多个命令组装成一次发送,达到原子性。(注:用了MULTI命令后服务端收到然后对接下来的命令都缓存到一个List里,直到EXEC,然后将这个List作为一个特殊命令offer到命令队列里,命令执行线程将这个List的所有命令一起执行)
3. 用WATCH提供的乐观锁功能,在你EXEC的那一刻,如果被WATCH的键发生过改动,则MULTI到EXEC之间的指令全部不执行,不需要rollback
4. 其他回答中提到的DISCARD指令只是用来撤销EXEC之前被暂存的指令,并不是回滚;(注:MULTI后如果用了discard则会撤销此次MULTI命令并清除之前用于缓存命令的List,此次MULTI结束不需要EXEC;如果在MULTI后提交事务的命令时被redis检测到有错误的命令则redis会提示,那么这时候应该直接discard而不是exec,用后者也是被discard且还会提示操作失败,这里个人有个小疑问,有没有撤销MUTIL中上个命令的cmd指令?)

Redis为什么是单线程的更多相关文章

  1. Redis为什么是单线程、及高并发快的3大原因详解

    Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了很多上下文切换线程的时间: 3.redis使用多路复用技术,可以处理并发的连接.非阻塞 ...

  2. 对Redis 单进程、单线程模型的理解(网摘)

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

  3. 高并发架构系列:Redis为什么是单线程、及高并发快的3大原因详解

    Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了很多上下文切换线程的时间: 3.redis使用多路复用技术,可以处理并发的连接.非阻塞 ...

  4. Redis为什么是单线程的

    一.前言   最近在学习Redis,这篇文章就来简单聊聊一道常考的面试题--Redis为什么是单线程的.废话不多说,直接开始吧. 二.正文 2.1 为什么需要多线程   首先,现在的CPU一般都是由多 ...

  5. Redis 到底是单线程还是多线程?我要吊打面试官!

    最近在Java技术栈公众号发布的一篇文章,其中有一道题: Redis是多线程还是单线程?(回答单线程的请回吧,为什么请回,请往下看) 好些粉丝在后台问我:为什么请回,Redis不是单线程吗? 大家注意 ...

  6. Redis为什么是单线程,高并发快的3大原因详解

    出处知乎:https://zhuanlan.zhihu.com/p/58038188 Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了 ...

  7. redis 为什么是单线程的?

    一.Redis为什么是单线程的? 因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽.既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理 ...

  8. Redis 是单进程单线程的?

    Redis 是单进程单线程的,redis 利用队列技术将并发访问变为串行访问,消 除了传统数据库串行控制的开销.

  9. Redis使用单进程单线程方式的优缺点分析

    [转] http://www.syyong.com/db/Redis-why-the-use-of-single-process-and-single-threaded-way-so-fast.htm ...

随机推荐

  1. ABAP-反调JCO服务

  2. 主流JS库一览

    主流JS库一览 标签: prototypedojomootoolsprototypejsjqueryjavascript 2009-10-14 22:52 19936人阅读 评论(2) 收藏 举报   ...

  3. ubuntu 安装搜狗输入法

    from:http://blog.csdn.net/qq_21792169/article/details/53152700 最近开始学习linux 在安装输入法中遇到的一些问题,最终成功安装,也得益 ...

  4. 使用sql获取primary key名称

    使用sql获取mysql主键名称: 方法1: 这种方法返回一行数据,如果只是需要主键的名称,可以使用方法2. SHOW KEYS FROM <table_name> WHERE Key_n ...

  5. mysql改数据库名称

    第一种方法: 1.创建需要改成新名的数据库.2.mysqldum 导出要改名的数据库3.删除原来的旧库(确定是否真的需要)当然这种方法虽然安全,但是如果数据量大,会比较耗时,哎,当时连这种方法都没有想 ...

  6. JSTL标签库学习3-fn

    fn的全称为functions, 就是提供一些方法,函数等. 主要是一些操作字符串的函数. fn:contains(str, str)显示用户浏览器,操作系统.可以从header中获取user-age ...

  7. MySql重复查询

    MYSQL查询重复记录的方法很多,下面就为您介绍几种最常用的MYSQL查询重复记录的方法,希望对您学习MYSQL查询重复记录方面能有所帮助. 1.查找表中多余的重复记录,重复记录是根据单个字段(peo ...

  8. maven 的聚合

  9. 吴裕雄 实战python编程(1)

    import sqlite3 conn = sqlite3.connect('E:\\test.sqlite') # 建立数据库联接cursor = conn.cursor() # 建立 cursor ...

  10. linux下的计算器

    (1)bc bc在默认的情况下是个交互式的指令.在bc工作环境下,可以使用以下计算符号:+ 加法 - 减法 * 乘法 / 除法 ^ 指数 % 余数如: 3+4;5*2;5^2;18/4      &l ...