转自: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. Git----分支管理之bug分支04

    ---恢复内容开始--- 软件开发中,bug就像家常便饭一样,有了bug就需要修复,在Git中,由于分支是如此强大,所以,每个bug都可以通过一个临时分支来修复,修复后,合并分支,然后将临时分支删除. ...

  2. H5 缓存机制解析

    在web项目开发中,我们可能都曾碰到过这样一个棘手的问题: 线上项目需要更新一个有问题的资源(可能是图片,js,css,json数据等),这个资源已经发布了很长一段时间,为什么页面在浏览器里打开还是没 ...

  3. SRC是在本位置显示:source的缩写,源的意思 HREF是点击后连接的目标:HyperlinkReference,超链接引用

    SRC是在本位置显示:source的缩写,源的意思HREF是点击后连接的目标:HyperlinkReference,超链接引用

  4. Hibernate Annotation 设置字段的默认值

    很简单,不过有点莫名其妙的意思 @Column(name="powerLoad",columnDefinition="bit(1) default 1 ") p ...

  5. Filter接口编写过滤器

      Filter,过滤器,顾名思义,即是对数据等的过滤,预处理过程.为什么要引入过滤器呢?在平常访问网站的时候,有时候发一些敏感的信息,发出后显示时 就会将敏感信息用*等字符替代,这就是用过滤器对信息 ...

  6. 判断是否有TrueType字体

    function IsTrueTypeAvailable : bool;var {$IFDEF WIN32}  rs : TRasterizerStatus; {$ELSE}  rs : TRaste ...

  7. neo4j 常用命令查询,以及更新 节点 的 label 名 和 property 名

    常用命令查询 https://neo4j.com/docs/cypher-refcard/current/ 更新节点的 labels 有时候 发现节点的 label 名字起错了怎么修改呢?!一个节点是 ...

  8. Node.js的知识点框架整理

    背景:因为appium是基于Node.js的,所以想看一下Node.js.但是发现很多资料的顺序看起来有点颠倒.然后就一面看资料一面整理了一下大概的知识点框架,希望对自己对别人有用. 本文不包含nod ...

  9. 转-git 配置用户名和邮箱

    原址:http://www.cnblogs.com/fsong/p/5540840.html 在安装了git for windows之后,个人总是忘记配置git config的命令,以此记录一下: 配 ...

  10. hdoj1069 Monkey and Banana(DP--LIS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1069 思路: 由题意,显然一种block可能有6种形式,且一种形式最多使用一次,因此最多有30×6=1 ...