Redis为什么速度快
基于内存的数据库。完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);
多路I/O复用模型:对于服务端接收到的大量请求,redis使用I/O多路复用程序同时监听多个套接字,并且将这些事件push到同一个队列中逐步执行,最终再将结果返回给客户端。
高效的数据结构: sds (simple dynamic string) 简单动态字符串
O(1) 复杂度的长度计算:在 C 语言中,要计算一个字符串的长度,需要遍历整个字符串,时间复杂度为 O(n)。而 SDS 中的 len 属性记录了字符串的长度,因此可以在 O(1) 时间内获取字符串的长度。
二进制安全:C 语言中的普通字符串使用 ‘\0’ 字节作为字符串的结束符,因此不支持存储二进制数据和包含空字符的字符串。而 SDS 使用 buf 和 len 属性来表示字符串,因此可以存储任何二进制数据,同时也支持存储包含空字符的字符串。
减少缓冲区溢出的风险:在 C 语言中,如果使用 char 数组来存储字符串,当字符串的长度超过数组大小时,就会发生缓冲区溢出的错误。而 SDS 在扩展缓冲区时,会通过预留额外的空间来避免缓冲区溢出的风险。
支持快速增长和缩短:在 C 语言中,如果要对字符串进行增长或缩短操作,需要重新分配内存并复制数据。而 SDS 的 buf 属性可以支持快速增长和缩短,因为它是一个可修改大小的空间,不需要分配新的空间。
兼容部分 C 字符串库:SDS 一些 API 与标准 C 库中字符串操作函数(如 strlen、strcat)类似,因此可以兼容一些 C 字符串库的使用,同时也提高了代码的可读性和易维护性。
单线程模式:Redis基于Reactor模式开发了网络事件处理器,这个处理器被称为文件事件处理器。它的组成结构为4部分:多个套接字、IO多路复用程序、文件事件分派器、事件处理器。因为文件事件分派器队列的消费是单线程的,所以Redis才叫单线程模型。为什么redis会使用单线程?因为一般来说,redis比较少会有计算密集型的操作,所以cpu不会有瓶颈。redis的瓶颈,一般是在没存大小与网络IO。实际中我们为了使用cpu的多核,都是采用搭建多个redis实例来解决。在redis6.0以后的新版本中,网络IO处理模块已经使用了多线程,比如网络数据的读写与协议解析等等。但是,执行命令的模块,即文件事件分派器仍然是单线程,所以我们还是可以说redis是单线程模型。单线程模式可以使得redis变快,原因主要在于单线程在执行的过程中不需要进行上下文的切换,从而减少了耗时提高了处理速度。
Redis客户端对服务端的每次调用都经历了发送命令,执行命令,返回结果三个过程。其中执行命令阶段,由于Redis是单线程来处理命令的,所有每一条到达服务端的命令不会立刻执行,所有的命令都会进入一个队列中,然后逐个被执行。并且多个客户端发送的命令的执行顺序是不确定的。但是可以确定的是不会有两条命令被同时执行,不会产生并发问题,这就是Redis的单线程基本模型。

