Redis单线程设计的但为什么这么快

基础概念

        redis与传统数据库存储区别:

  • Redis是NOSQL,即非关系型数据库,没有表结构,也是缓存数据库,即将数据存储在内存中,内存的读取速度快,能够大大的提高运行效率(redis也可以持久化保存到磁盘);
  • 传统数据库数据保存在磁盘里;

        单线程的优点:

  • 避免多线程上下文切换导致的性能损耗;
  • 避免多线程访问共享资源加锁导致的性能损耗;

        单线程处理的劣势:

  • 耗时的命令会导致并发的下降,不只是读并发,写并发也会下降;
  • 无法发挥多核 CPU 性能,不过可以通过在单机开多个 Redis 实例来完善;

官方说法

         翻译:

        CPU并不是您使用Redis的瓶颈,因为通常Redis要么受内存限制,要么受网络限制。例如,使用在一般Linux系统上运行的流水线Redis每秒可以发送一百万个请求,因此,如果您的应用程序主要使用O(N)或O(log(N))命令,则几乎不会使用过多的CPU 。
        但是,为了最大程度地利用CPU,您可以在同一服务器上启动多个Redis实例,并将它们视为不同的服务器。在某个时候,单个实例可能还不够,因此,如果您要使用多个CPU,则可以开始考虑更早地分片的某种方法。
       在Redis 4.0中,我们开始使Redis具有更多线程。目前,这仅限于在后台删除对象,以及阻止通过Redis模块实现的命令。对于将来的版本,计划是使Redis越来越线程化。既然redis的瓶颈不是cpu,那么在单线程可以实现的情况下,自然就使用单线程了。

        个人理解:

  1. 它是纯存内存操作(内存操作并非磁盘操作);
  2. 核心是基于非阻塞的IO多路复用机制;
  3. 单线程的设计避免了多线程上下文切换的资源开销;
  4. 简单且解析性能高的序列化协议RESP(Redis Serialization Protocol);

        解析:

1、首先,内存与磁盘的区别,内存是临时保存数据(断电即消失),具有高速读写能力,但无法持久保存数据;磁盘为持久化保存数据(断电不消失)读写速度相对于内存慢很多;

2、非阻塞IO的多路复用机制:

        非阻塞IO:意味着在读写的时候不必阻塞,读写可以瞬间完成后就可以去干别的事情了,能读/写多少是多少。

        多路复用机制:(多路)指的是多个socket网络连接,(复用)指的是复用一个线程。多路复用主要有三种技术(函数):select,poll,epoll。epoll是最新的、也是目前最好的多路复用技术。

        知乎上有这样一段描述:我们拿到了一堆文件描述符(不管是网络相关的、还是磁盘文件相关等等,任何文件描述符都可以), 通过调用某个函数(select,poll,epoll)告诉内核:“这个函数你先不要返回,你替我监视着这些描述符,当这堆文件描述符中有可以进行I/O读写操作的时候你再返回”。当调用的这个函数返回后,我们就能知道哪些文件描述符可以进行I/O操作了。

3、单线程的设计避免了多线程上下文切换的资源开销;

        采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU。但是如果CPU成为Redis瓶颈,或者不想让服务器其他CUP核闲置,那怎么办?可以考虑多起几个Redis进程,Redis是key-value数据库,不是关系数据库,数据之间没有约束。只要客户端分清哪些key放在哪个Redis进程上就可以了。

4、简单且解析性能高的序列化协议RESP(Redis Serialization Protocol):

        RESP是一种肉眼可读的文本协议,异常简单性能也不错。协议将结构数据定义为5种最小单元类型,单元结束统一跟回车换行符(\r\n)

  • 单行字符串:以 "+" 开头,用 +hello\r\n表示。
  • 多行字符串:以"redis\r\nhello\r\n表示。当然多行字符串也可以表示单行字符串。
  • 多行字符串:以NULL值用表示,长度写成 "-1" 例如:-1\r\n这样的。
  • 空字符:用多行字符串标示,长度为 "0" :$0\r\n\r\n
  • 整数值: 以 ":" 开头 ,用 :1024\r\n表示。
  • 错误信息: 以 "-" 开头,-WRONGTYPE Operation against a key holding the wrong kind of value
  • 数组:以 "*" 开头,后跟数组长度。数组 [1,2,3]表示为:*3\r\n:1\r\n:2\r\n:3\r\n

总结

        Redis是纯内存数据库,一般都是简单的存取操作,线程占用的时间很多,时间的花费主要集中在IO上,所以读取速度快;

        IO,Redis使用的是非阻塞IO、IO多路复用,使用了单线程来轮询描述符,将数据库的开、关、读、写都转换成了事件,减少了线程切换时上下文的切换和竞争;

        Redis采用了单线程的模型,保证了每个操作的原子性,也减少了线程的上下文切换和竞争;

        Redis避免了多线程的锁的消耗;

        redis的数据结构以及序列化协议使它适合读写。

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值