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 ...
随机推荐
- Simple2D-26 Simple2D 最后的工作,开发结束
开始的时候打算将 Simple2D 做成一个库的,但现在没有那个功夫了. 要渲染顶点数据,就必须将渲染函数放置到 glClear( ) 函数和 SwapBuffers( ) 函数之间,但又不希望开发时 ...
- linux 中特殊符号用法详解
# 井号 (comments)#管理员 $普通用户 脚本中 #!/bin/bash #!/bin/sh井号也常出现在一行的开头,或者位于完整指令之后,这类情况表示符号后面的是注解文字,不会被执行 ...
- 【转载】 Java并发编程:深入剖析ThreadLocal
原文链接:http://www.cnblogs.com/dolphin0520/p/3920407.html感谢作者的辛苦总结! Java并发编程:深入剖析ThreadLocal 想必很多朋友对Thr ...
- (转载)session token机制
http://blog.chinaunix.net/uid-26642709-id-3061264.html 使用session token时,必须用struts2表标签库,不能用html 通过ses ...
- Haskell语言学习笔记(46)Parsec(3)
Applicative Parsing 使用 Applicative 式的 Parser. 包括使用 (<$>), (<*>), (<$), (<*), (*> ...
- scala -- 柯里化
柯里化 柯里化是把接受多个参数的函数,变成接受一个单一参数的函数.并且返回接受剩余参数和返回结果的新函数. 就是一个逐次消元的过程. 当把函数的元全消掉,就得到了值. 值就是零元函数. 二元函数 f( ...
- 吴裕雄 数据挖掘与分析案例实战(7)——岭回归与LASSO回归模型
# 导入第三方模块import pandas as pdimport numpy as npimport matplotlib.pyplot as pltfrom sklearn import mod ...
- SQL获取分组后取某字段最大一条记录(求每个类别中最大的值的列表)
获取分组后取某字段最大一条记录 方法一:(效率最高) select * from test as a where typeindex = (select max(b.typeindex) from t ...
- Loadrunner通过吞吐量计算每个用户需要的带宽
Loadrunner通过吞吐量计算每个用户需要的带宽 运行一个场景,点击Analysis进行分析,使用分析报告中的Average Throughput(bytes/second)进行计算. 计算公式: ...
- 第八章 高级搜索树 (a2)伸展树:双层伸展