`
uule
  • 浏览: 6310154 次
  • 性别: Icon_minigender_1
  • 来自: 一片神奇的土地
社区版块
存档分类
最新评论

单线程的redis为什么这么快

 
阅读更多

为什么说Redis是单线程的并且这么快

 

其它开源软件采用的模型

 

Nginx:多进程单线程模型 

Memcached:单进程多线程模型

Redis:单进程单线程

 

 

单线程的redis为什么这么快

主要是以下三点

(一)纯内存操作

数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);

 

(二)单线程操作避免了频繁的上下文切换

避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;

 

多线程处理可能涉及到锁 

多线程处理会涉及到线程切换而消耗CPU

 

多线程对同一个Key操作时,Redis服务是根据先到先作的原则,其他排队(可设置为直接丢弃),因为是单线程。

修改默认的超时时间,默认2秒。但是大部份的操作都在30ms以内。

  

(三)采用了非阻塞I/O多路复用机制

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

 

(四)数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;

 

 

我们使用单线程的方式是无法发挥多核CPU 性能,不过我们可以通过在单机开多个Redis 实例来完善!

警告:这里我们一直在强调的单线程,只是在处理我们的网络请求的时候只有一个线程来处理,一个正式的Redis Server运行的时候肯定是不止一个线程的,这里需要大家明确的注意一下!

例如Redis进行持久化的时候会以子进程或者子线程的方式执行(具体是子线程还是子进程待读者深入研究)

 

 

Redis为什么是单线程的?

因为CPU不是Redis的瓶颈。Redis的瓶颈最有可能是机器内存或者网络带宽。

既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。

关于redis的性能,官方网站也有,普通笔记本轻松处理每秒几十万的请求,参见:How fast is Redis?

 

如果万一CPU成为你的Redis瓶颈了,或者,你就是不想让服务器其他核闲置,那怎么办?

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

 

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

当然可以了,Redis都实现了。有一点概念需要澄清,并发并不是并行。

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

 

单线程处理的缺点?

无法发挥多核CPU性能,不过可以通过在单机开多个Redis实例来完善

    

单进程单线程的Redis如何能够高并发

采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗) 

 

Redis不存在线程安全问题? 

Redis采用了线程封闭的方式,把任务封闭在一个线程,自然避免了线程安全问题,不过对于需要依赖多个redis操作的复合操作来说,依然需要锁,而且有可能是分布式锁

 

 

redis的一些其他特点:

(1)Redis是单进程单线程的

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

 

(2)读写分离模型

通过增加Slave DB的数量,读的性能可以线性增长。为了避免Master DB的单点故障,集群一般都会采用两台Master DB做双机热备,所以整个集群的读和写的可用性都非常高。

读写分离架构的缺陷在于,不管是Master还是Slave,每个节点都必须保存完整的数据,如果在数据量很大的情况下,集群的扩展能力还是受限于单个节点的存储能力,而且对于Write-intensive类型的应用,读写分离架构并不适合。

 

(3)数据分片模型

为了解决读写分离模型的缺陷,可以将数据分片模型应用进来。

可以将每个节点看成都是独立的master,然后通过业务实现数据分片。

结合上面两种模型,可以将每个master设计成由一个master和多个slave组成的模型。

 

(4)Redis的回收策略

volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

 

allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰

allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

 

no-enviction(驱逐):禁止驱逐数据

 

注意这里的6种机制,volatile和allkeys规定了是对已设置过期时间的数据集淘汰数据还是从全部数据集淘汰数据,后面的lru、ttl以及random是三种不同的淘汰策略,再加上一种no-enviction永不回收的策略。

 

使用策略规则:

  1、如果数据呈现幂律分布,也就是一部分数据访问频率高,一部分数据访问频率低,则使用allkeys-lru

  2、如果数据呈现平等分布,也就是所有的数据访问频率都相同,则使用allkeys-random

 

 

redis常见性能问题和解决方案:

 

(1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件

(Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照;

AOF文件过大会影响Master重启的恢复速度)

 

(2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次

(3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内

(4) 尽量避免在压力很大的主库上增加从库

(5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3...

 

这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。

 

 

1. Redis服务端是个单线程的架构,不同的Client虽然看似可以同时保持连接,但发出去的命令是序列化执行的,这在通常的数据库理论下是最高级别的隔离(serialize)

2. 用MULTI/EXEC 来把多个命令组装成一次发送,达到原子性

3. 用WATCH提供的乐观锁功能,在你EXEC的那一刻,如果被WATCH的键发生过改动,则MULTI到EXEC之间的指令全部不执行,不需要rollback

4. 其他回答中提到的DISCARD指令只是用来撤销EXEC之前被暂存的指令,并不是回滚

 

分享到:
评论

相关推荐

    「Redis」Redis是单线程的,但Redis为什么这么快?

    「Redis」Redis是单线程的,但Redis为什么这么快?

    为什么说Redis是单线程的以及Redis为什么这么快!

    2.redis是单线程的,省去了很多上下文切换线程的时间; 3.redis使用多路复用技术,可以处理并发的连接; 简单解释下第二条:上下文切换就是cpu在多线程之间进行轮流执行(枪战cpu资源),而redis单线程的,因此避免...

    Redis经典面试题:redis是单线程架构还是多线程架构

    首先,Redis是单线程架构,因为对于许多请求Redis都能高效完成并返回较为明确的结果。 Redis大部分操作是基于内存完成的,因此,单个CPU内存的读取速度非常快。单线程可以处理大部分请求,而且并发性的表现足够强大...

    redis面试题之单线程.zip

    redis面试题 redis面试题之单线程

    redis单线程快的原因和原理

    (二)单线程操作,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗; (三)采用了非阻塞I...

    20_来聊聊redis的线程模型吧?为啥单线程还能有很高的效率?.zip

    https://mp.csdn.net/console/uploadResources?spm=1011.2124.3001.4171

    异步 redis client.rar

    Redis单线程为什么还能这么快? 因为Redis是基于内存的,所有的运算都是内存级别的,而且单线程避免了多线程的切换性能耗损问题。 Redis单线程如何处理那么多并发客户端连接? 这里就要扯到NIO多路复用模型了,由于...

    redis面试复习.xmind

    ### redis为什么快 ### 单线程好处(为什么使用单线程): ### 什么是非阻塞I/O多路复用机制 ### redis与memecache区别(我们直观能理解的部分) ### redis数据类型 (这里对每个数据类型做了一些我个人能理解到的解释,...

    redis面试题及其答案.pdf

    Redis主要有哪些功能? Redis支持哪几种数据类型? Redis是单进程单线程的? Redis为什么是单线程的? 使用Redis的优势? Redis集群方案应该怎么做?都有哪些方案? ...

    Redis面试专题.pdf

    为什么高并发下有时单线程的 redis 比多线程的memcached 效率要高? 2.redis 主从复制如何实现的?redis 的集群模式如何实现?redis 的 key 是如何寻址的? 3.使用 redis 如何设计分布式锁?说一下实现思路?使用 zk...

    Redis面试题50道(含答案)_.pdf

    45、Redis 是单线程的,如何提高多核 CPU 的利用率? 46、一个 Redis 实例最多能存放多少的 keys?List、Set、 Sorted Set 他们最多能存放多少元素? 47、Redis 常见性能问题和解决方案? 48、Redis 提供了哪几种...

    Redis查漏补缺_最易错过的技术要点大扫盲

    •单线程的Redis为什么这么快 •Redis的数据类型,以及每种数据类型的使用场景 •Redis的过期策略以及内存淘汰机制 •Redis和数据库双写一致性问题 •如何应对缓存穿透和缓存雪崩问题 •如何解决Redis的...

    每次面试都要被问:为什么采用单线程的 Redis 也会如此之快?.zip

    计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料 计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料 计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料 计算机技术、IT咨询、人工智能AI理论介绍,...

    redis2加强.doc

    c,使用了单线程架构,预防多线程可能产生的竞争问题 d:协议简单 2〉键值对的数据结构服务器 键简单 3〉丰富的功能:见上功能 4〉简单稳定:单线程 5〉持久化:发生断电或机器故障,数据可能会丢失,持久化到硬盘 6〉...

    Redis中最常用的String数据结构.docx

    如果面试官问你,单线程的Redis为什么那么快,你可能脱口而出,因为单线程,避免上下文切换;因为基于内存,比硬盘读写快很多;因为采用的是多路复用网络模型。不管你是否真的理解了,这个回答足以应付一半以上的...

    lixd#daily-notes#为什么Redis选择单线程1

    2. 引入多线程 3. 总结 4. 原文

    redisStudy.zip

    redis是单线程实现。 3.redis 提供的持久机制 redis 支持rdb和aof两种持久机制,redis4.0后支持混合持久化。rdb是定时的持久机制,宕机有可能会丢失最后一次持久化之后存在数据丢失。aof是基于操作日志追加的持久...

Global site tag (gtag.js) - Google Analytics