Redis为什么这么快


前言

FD是什么?
fd,即file descriptor,文件描述符。linux下,所有的操作都是对文件进行操作,而对文件的操作是利用文件描述符(file descriptor)来实现的


一、全部基于内存操作

完全基于内存,数据存在内存中,绝大部分请求是纯粹的内存操作,非常快速,跟传统的磁盘文件数据存储相比,避免了通过磁盘IO读取到内存这部分的开销。

二、数据结构简单,对数据操作也简单

Redis中的数据结构是专门进行设计的,每种数据结构都有一种或多种数据结构来支持。Redis正是依赖这些灵活的数据结构,来提升读取和写入的性能。

三、采用单线程去访问

省去了很多上下文切换的时间以及CPU消耗,不存在竞争条件,不用去考虑各种锁的问题,不存在加锁释放锁操作,也不会出现死锁而导致的性能消耗。

四、使用基于IO多路复用机制的线程模型,可以处理并发的链接。

Redis采用了epoll 模型进行IO多路复用。Java中也有类似的模型比如NIO,才epoll模型之前还有selector、poll这里不多讲解,epoll模型可以参考下图:
在这里插入图片描述

五、缓存时间戳

平常中使用时间戳常常需要一次系统调用去获取系统的毫秒时间戳,但是作为单线程的Redis无法承受,因为每次去系统调用是比较费时间的,所以它需要对于时间戳进行一次缓存,由一个定时任务进行每毫秒更新时间戳,从而获取时间戳都是直接从缓存就取出

六、渐进式ReHash

这里需要首先先讲一下Redis的Key和Value的数据结构组织
全局哈希表
为了实现从键到值得快速访问,Redis采用了一个哈希表来保存所有得键值对。一个哈希表其实就是一个数组,数组下标得每个元素被称为哈希桶。所以一个哈希表由多个哈希桶组成,每个哈希桶保存了键值对的元素数据。
哈希冲突
刚刚既然说了Redis是哈希表,那必然会有哈希冲突,Redis采用了链式哈希来解决哈希冲突,即一个哈希桶里面会有由多个元素用链表保存,它们之间用指针连接。但是如果数组长度一直不变化,元素哈希冲突越来越多,这个时候检索效率会大大降低,那么Redis就需要对数组长度进行扩容,但是问题来了,扩容后每个哈希桶的元素会分散在不同的位置,这里涉及到了元素的移动,那么必会造成阻塞IO。这个时候就需要我们渐进式ReHash了。
渐进式ReHash
为了解决这个问题,Redis默认使用了两张全局Hash表,哈希表1和哈希表2,最初的时候你插入数据默认使用哈希表1,此时的哈希表是没有分配空间的,随着数据增多,Redis便开始执行ReHash

1.给哈希表2分配更大的空间,比如是哈希表1的两倍大小

2.把哈希表1中的数据重新映射到哈希表2中

3.释放哈希表1的空间

上面第二步中数据重新映射涉及到了大量的数据拷贝,如果一次把数据全部进行迁移,那么会造成Redis的线程阻塞,无法服务其他的请求,此时的Redis就无法快速访问数据了,所以Redis加入了一个格外的操作。

处理第一个请求的时候,把哈希表1中的第 1 个索引的位置的全部元素拷贝到哈希表2中。

处理第二个请求的时候,把哈希表1中的第 2 个索引的位置的全部元素拷贝到哈希表2中。

如此循环直到数据全部拷贝完成,这样就可以解决一次大量的拷贝开销,分摊到多个处理请求过程中,避免的耗时的操作,从而保证了数据的快速访问。基本上保证了key找value的操作在O ( 1 ) 左右。
但是如果有海量的key值得话,这个ReHash过程会很长,每次ReHash的过程中还是会有一定卡顿时间,一些统计命令也会有卡顿,这里尽量保证key的数据在千万以下,否则建议使用分区Hash储存

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值