redis为什么快

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

redis为什么这么快呢,主要是1.存储于内存2.数据结构3.开发了自己的文件事件处理器(包含了IO多路复用)


一、存储于内存

这个不需要多说,速度cpu>内存>硬盘,所以redis的操作都是基于内存的,绝大部分请求是纯粹的内存操作,非常迅速。

二、数据结构

1.String,2.List,3.hash,4.set,5.zset

下图是数据类型于底层数据结构的对应关系(List 3.2之前:ziplist/linkedlist 3.2之后:quicklist)数据类型于底层数据结构的对应关系

1.动态字符串

redis对他进行了修改,去除了\0用一个 len 字段记录当前字符串的长度,省略了遍历字符串获取长度,又保证了二进制安全,C 中字符串遇到 ‘\0’ 会结束,那 ‘\0’ 之后的数据就读取不上了。但在 redis中,是根据 len 长度来判断字符串结束的。
C 语言中涉及到修改字符串的时候会重新分配内存。修改地越频繁,内存分配也就越频繁。而内存分配是会消耗性能的,那么性能下降在所难免。而redis是会频繁修改字符串的,原来的内存分配就不合适,
所以redis就对内存进行了预分配,提前分配一段空白的内存给字符串。

2.linkedlist

redis对链表(linkedlist)的改造就是多了参数 len拥有存长度,头节点里有 head 和 tail 两个参数,分别指向头节点和尾节点。 同时链表迭代时从两端都可以进行。

3.ziplist

如果在一个链表节点中存储一个小数据,比如一个字节。那么对应的就要保存头节点,前后指针等额外的数据。这样就浪费了空间,同时由于反复申请与释放也容易导致内存碎片化。这样内存的使用效率就太低了。所以专门设计了压缩列表它是经过特殊编码,专门为了提升内存使用效率设计的。所有的操作都是通过指针与解码出来的偏移量进行的。并且压缩列表的内存是连续分配的,遍历的速度很快。

4.quicklist

而快速列表(quicklist)就是链表节点下面挂载着压缩列表(ziplist)

5.字典

Redis 作为 K-V 型数据库,所有的键值都是用字典来存储的。

日常学习中使用的字典你应该不会陌生,想查找某个词通过某个字就可以直接定位到,速度非常快。这里所说的字典原理上是一样的,通过某个 key 可以直接获取到对应的value。

字典又称为哈希表,这点没什么可说的。哈希表的特性大家都很清楚,能够在 O(1) 时间复杂度内取出和插入关联的值

5.跳跃表 zskiplist

作为 Redis 中特有的数据结构-跳跃表,其在链表的基础上增加了多级索引来提升查找效率。

这是跳跃表的简单原理图,每一层都有一条有序的链表,最底层的链表包含了所有的元素。这样跳跃表就可以支持在 O(logN) 的时间复杂度里查找到对应的节点。

下面这张是跳表真实的存储结构,和其它数据结构一样,都在头节点里记录了相应的信息,减少了一些不必要的系统开销。
在这里插入图片描述

三、开发了自己的文件事件处理器(包含了IO多路复用)

Redis基于Reactor模式开发了自己的网络事件处理器,称之为文件事件处理器(File Event Hanlder)。文件事件处理器由Socket、IO多路复用程序、文件事件分派器(dispather),事件处理器(handler)四部分组成。文件事件处理器的模型如下所示:
在这里插入图片描述

1.i/o多路复用

i/o多路复用应用上讲就是阻塞i/o配合select、poll和epoll阻塞,和阻塞io的区别就在于,阻塞io线程是对于recvftom函数只能阻塞一个,而多路复用io是阻塞select、poll和epoll函数,对于这些函数一个线程可以对多个IO端口进行监听,当有读写事件产生时会分发到具体的线程进行处理,IO复用只需要阻塞在select,poll或者epoll,可以同时处理和管理多个连接。实现了:
I/O :网络 I/O
多路:多个 TCP 连接
复用:共用一个线程或进程

这个多路复用的缺点就是连接数过少时这种模型将退化成阻塞 IO 模型。并且还多了一次系统调用:一次 select、poll或者epoll 一次 recvfrom。连接请求模型如下图:
在这里插入图片描述

2.文件事件分派器

为什么说redis单线程,说的就是这个文件事件分派器单线程处理请求,当被监听的socket准备好执行accept、read、write、close等操作时,与这些操作相对应的文件事件就会产生。IO多路复用程序会把所有产生事件的socket压入一个队列中,然后有序地每次仅一个socket的方式传送给文件事件分派器,而单线程避免上下文切换又快速了一些,又不需要实现复杂的锁机制。

还有redis6.0之后为了突破网络模块瓶颈,通过使用多线程处理读/写客户端数据,进而分担主IO线程的压力。值得注意的是,命令处理仍然是单线程执行。


总结

redis的快速是通过了精心的设计,又避免了其他数据库的弊端

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值