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 ...
随机推荐
- ABAP-消息发布
FUNCTION ZSDI0009_DO_INFOMESSAGE. *"----------------------------------------------------------- ...
- jstl遍历list的jsp
jstl,核心标签库,使用,<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%& ...
- How to read very large text files fast
Question Does anyone know the fastest way to read large text files (10Mb) into a string.Readln is ju ...
- ubuntu 16.04 完整安装 phantomjs
摘自 stackoverflow sudo apt-get install nodejssudo apt-get install nodejs-legacysudo apt-get install n ...
- HTML鼠标悬浮显示隐藏 JS方法
CSS样式表: @charset "utf-8"; /* CSS Document */ .a { width:80px; height:40px; top:200px; left ...
- Spring WebMVC 4.1返回json时 406(Not Acceptable)
1.问题现象Tomcat7+Spring4.1.4,返回json字符串时发生406错误 The resource identified by this request is only capable ...
- 基于Woodstox的StAX 2 (Streaming API for XML)解析XML
StAX (Streaming API for XML)面向流的拉式解析XML,速度快.占用资源少,非常合适处理大数据量的xml文件. 详细教程和说明可以参见以下几篇文章: 使用 StAX 解析 XM ...
- Django之ORM使用以及模板语言
一.ORM版增删改查 1.ORM的语句 1.类名.objects.all() --> 返回一个列表 2.类名.objects.filter() --> 返回一 ...
- Codeforces Beta Round #9 (Div. 2 Only)
Codeforces Beta Round #9 (Div. 2 Only) http://codeforces.com/contest/9 A gcd水题 #include<bits/stdc ...
- [leetcode]416. Partition Equal Subset Sum分割数组的和相同子集
Given a non-empty array containing only positive integers, find if the array can be partitioned into ...