`
uule
  • 浏览: 6330157 次
  • 性别: 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单线程的,因此避免...

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

    Redis是一款高性能的键值存储系统,它以其独特的单线程模型和高效的内存管理而闻名。在深入了解Redis的线程模型之前,我们先要明白一点:虽然Redis是单线程的,但它的性能并不低,反而在很多场景下表现出非常高的...

    redis面试题之单线程.zip

    为解决此问题,Redis提供了集群方案(Redis Cluster),将数据和请求分摊到多个节点上,每个节点仍保持单线程运行。 3.3 大量计算操作 对于耗时的计算任务,如排序或求交集,Redis提供了一些优化策略,如`KEYS`命令...

    redis为什么快.docx

    Redis 采取单线程设计,这看似限制了并行处理能力,但实际上由于内存操作的高效性,单线程可以快速地执行请求。此外,单线程模型简化了并发控制,避免了因多线程竞争资源导致的锁开销,保证了操作的原子性,使得...

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

    Redis,作为一种高性能的键值存储系统,以其独特的单线程模型和高效的内存操作而闻名。在Redis中,大部分操作都是基于内存的,这使得它在处理读取和写入操作时速度极快。Redis的数据结构设计也非常巧妙,包括简单...

    redis单线程快的原因和原理

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

    异步 redis client.rar

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

    cpp-在redis30上实现多线程implementmultithreadinginredis30

    Redis 是一个高性能的键值存储系统,以其单线程模型而闻名。然而,在 Redis 3.0 版本中,引入了多线程的概念来优化 I/O 处理,特别是针对网络读写操作,以此来进一步提升性能。下面将详细讨论如何在 Redis 3.0 中...

    redis单机安装完整例子

    它的高性能源于其内存存储和单线程模型。 二、安装Redis 1. 下载:首先从官方GitHub仓库或者官方网站下载最新版的Redis源码包,例如`redis-stable.tar.gz`。 2. 解压:将下载的压缩包解压到任意目录,例如`/usr/...

    redis面试复习.xmind

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

    redis-windows-redis7.0.5.zip

    2. **单线程模型**:Redis采用单线程处理客户端请求,避免了多线程间的上下文切换开销,提升了处理性能。 3. **数据结构优化**:Redis内置丰富的数据结构,如String、Hash、List、Set、Sorted Set,这些数据结构的...

    redis面试题及其答案.pdf

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

    复习精讲1

    本文将对 Redis 的知识点进行详细解释,包括为什么使用 Redis、使用 Redis 的缺点分析、单线程的 Redis 为什么这么快等。 1. 为什么使用 Redis 使用 Redis 主要是从两个角度考虑:性能和并发。Redis 可以将运行...

    Redis面试专题.pdf

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

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

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

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

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

Global site tag (gtag.js) - Google Analytics