Redis为什么是单线程
转自: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为特殊的场景选择了合适的技术方案。
======
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为什么是单线程的更多相关文章
- Redis为什么是单线程、及高并发快的3大原因详解
Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了很多上下文切换线程的时间: 3.redis使用多路复用技术,可以处理并发的连接.非阻塞 ...
- 对Redis 单进程、单线程模型的理解(网摘)
1.基本原理 采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗) (1)为什么不采用多进程或多线程处理? 多线程处理可能涉及到锁 多线程处理会涉及到线程切换而 ...
- 高并发架构系列:Redis为什么是单线程、及高并发快的3大原因详解
Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了很多上下文切换线程的时间: 3.redis使用多路复用技术,可以处理并发的连接.非阻塞 ...
- Redis为什么是单线程的
一.前言 最近在学习Redis,这篇文章就来简单聊聊一道常考的面试题--Redis为什么是单线程的.废话不多说,直接开始吧. 二.正文 2.1 为什么需要多线程 首先,现在的CPU一般都是由多 ...
- Redis 到底是单线程还是多线程?我要吊打面试官!
最近在Java技术栈公众号发布的一篇文章,其中有一道题: Redis是多线程还是单线程?(回答单线程的请回吧,为什么请回,请往下看) 好些粉丝在后台问我:为什么请回,Redis不是单线程吗? 大家注意 ...
- Redis为什么是单线程,高并发快的3大原因详解
出处知乎:https://zhuanlan.zhihu.com/p/58038188 Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了 ...
- redis 为什么是单线程的?
一.Redis为什么是单线程的? 因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽.既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理 ...
- Redis 是单进程单线程的?
Redis 是单进程单线程的,redis 利用队列技术将并发访问变为串行访问,消 除了传统数据库串行控制的开销.
- Redis使用单进程单线程方式的优缺点分析
[转] http://www.syyong.com/db/Redis-why-the-use-of-single-process-and-single-threaded-way-so-fast.htm ...
随机推荐
- Redis基本操作-list
Redis的5种数据结构:string.list.hash.set和zset; Redis 所有的数据结构都是以唯一的 key 字符串作为名称,然后通过这个唯一 key 值来获取相应的 value 数 ...
- Egret 工具推荐
Egret 工具推荐--打造最好的开发环境--IDE篇http://bbs.egret.com/forum.php?mod=viewthread&tid=13581&fromuid=1 ...
- 关闭IPV6
[root@bgw-t ~]# cat > /etc/modprobe.d/ipv6.conf << EOF alias net-pf-10 off options ipv6 dis ...
- TCP/IP知识总结(TCP/IP协议族读书笔记四)
参考:http://blog.chinaunix.net/uid-26275986-id-4109679.html 继续!TCP的流量控制和拥塞控制. TCP相对UDP可靠的地方在于它的拥塞控制.流量 ...
- Haskell语言学习笔记(21)Array
Ix 数组下标类型 Prelude> :m +Data.Array Prelude Data.Array> data Colour = Red | Orange | Yellow | Gr ...
- commonCookie.js
/** * Created with JetBrains WebStorm. * NAME: commonCookie.js */(function(window,document){ var com ...
- hivepython 实现一行转多行
案例1: ==效果等同于一行转多行 数据表名称:zhangb.gid_tags 数据格式,每行是2个字段,(gid,tags) ,可能有脏数据,分隔符为“\t”, ANDROID-9de77225 ...
- drupal 用法小结,drupal select ,query ,distinct
https://api.drupal.org/api/drupal/includes%21actions.inc/function/actions_do/7.x addFileds : 这个更全点: ...
- Redis常用数据类型及命令
Redis数据类型 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). 注意: 命令的关键词,如set ...
- tf.cast()
一.函数 tf.cast() cast( x, dtype, name=None ) 将x的数据格式转化成dtype.例如,原来x的数据格式是bool, 那么将其转化成float以后,就能够将其转化成 ...