redis架构及为什么快
基于内存实现
Redis的操作都是基于内存的,CPU不是 Redis性能瓶颈,,Redis的瓶颈是机器内存和网络带宽。
在计算机的世界中,CPU的速度是远大于内存的速度的,同时内存的速度也是远大于硬盘的速度。redis的操作都是基于内存的,绝大部分请求是纯粹的内存操作,非常迅速。
单线程操作
使用单线程可以省去多线程时CPU上下文会切换的时间,也不用去考虑各种锁的问题,不存在加锁释放锁操作,没有死锁问题导致的性能消耗。对于内存系统来说,多次读写都是在一个CPU上,没有上下文切换效率就是最高的!既然单线程容易实现,而且 CPU 不会成为瓶颈,那就顺理成章的采用单线程的方案了
Redis 单线程指的是网络请求模块使用了一个线程,即一个线程处理所有网络请求,其他模块该使用多线程,仍会使用了多个线程。
I/O 多路复用
redis使用IO多路复用
Redis服务器是一个事件驱动程序,服务器需要处理以下两类事件:
文件事件:Redis服务端通过套接字与客户端(或其他Redis服务器)进行连接,而文件事件就是服务器对套接字操作的抽象。服务器与客户端(或者其他服务器)的通信会产生相应的文件事件,而服务器则通过监听并处理这些事件来完成一系列网络通信操作。
时间事件:Redis服务器中的一些操作(如serverCron)函数需要在给定的时间点执行,而时间事件就是服务器对这类定时操作的抽象。
文件事件处理器
Redis基于 Reactor 模式开发了自己的网络事件处理器:这个处理器被称为文件事件处理器:
1.文件事件处理器使用 I/O 多路复用程序来同时监听多个套接字,并根据套接字目前执行的任务来为套接字关联不同的事件处理器。
2.当被监听的套接字准备好执行连接应答(accept)、读取(read)、写入(write)、关闭(close)等操作时,与操作相对应的文件事件就会产生,这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。
下图展示了文件事件处理器的四个组成部分:套接字、I/O多路复用程序、文件事件分派器(dispatcher)、事件处理器。
文件事件是对套接字操作的抽象,每当一个套接字准备好执行连接应答、写入、读取、关闭等操作时,就会产生一个文件事件。因为一个服务器通常会连接多个套接字,所以多个文件事件有可能会并发地出现。I/O 多路复用程序负责监听多个套接字,并向文件事件分派器传送那些产生了事件的套接字。
Redis 的 I/O多路复用程序总是会将所有产生事件的套接字都放到一个队列里面,然后通过这个队列,以有序、同步、每次一个套接字的方式向文件事件分派器传送套接字。当上一个套接字产生的事件被处理完毕之后,I/O 多路复用程序才会继续向文件事件分派器传送下一个套接字。
Redis为文件事件处理器编写了多个处理器,这些事件处理器分别用于实现不同的网络通信需求:
1.为了对连接服务器的各个客户端进行应答,服务器要为监听套接字关联连接应答处理器;
2.为了接受客户端传来的命令请求,服务器要为客户端套接字关联命令请求处理器 ;
3.为了向客户端返回命令的执行结果,服务器要为客户端套接字关联命令回复处理器 ;
4.当主服务器和从服务器进行复制操作时,主从服务器都需要关联特别为复制功能编写的复制处理器。
- 连接应答处理器:用于处理客户端的连接请求;
- 命令请求处理器:用于执行客户端传递过来的命令,比如常见的set、lpush等;
- 命令回复处理器:用于返回客户端命令的执行结果,比如set、get等命令的结果;
事件种类:
AE_READABLE:与两个事件处理器结合使用。
当客户端连接服务器端时,服务器端会将连接应答处理器与socket的AE_READABLE事件关联起来;
当客户端向服务端发送命令的时候,服务器端将命令请求处理器与AE_READABLE事件关联起来;
AE_WRITABLE:当服务端有数据需要回传给客户端时,服务端将命令回复处理器与socket的AE_WRITABLE事件关联起来。
Redis的自定义协议
Redis客户端使用RESP(Redis的序列化协议)协议与Redis的服务器端进行通信。 它实现简单,解析快速并且人类可读。
RESP 支持以下数据类型:简单字符串、错误、整数、批量字符串和数组。
RESP 在 Redis 中用作请求-响应协议的方式如下:
客户端将命令作为批量字符串的 RESP 数组发送到 Redis 服务器。
服务器根据命令实现以其中一种 RESP 类型进行回复。
在 RESP 中,某些数据的类型取决于第一个字节:
对于简单字符串,回复的第一个字节是“+”
对于错误,回复的第一个字节是“-”
对于整数,回复的第一个字节是“:”
对于批量字符串,回复的第一个字节是“$”
对于数组,回复的第一个字节是“*”
此外,RESP 能够使用稍后指定的批量字符串或数组的特殊变体来表示 Null 值。在 RESP 中,协议的不同部分总是以“\r\n”(CRLF)终止。
redis为什么快
1.基于内存
2.高效的数据结构
3.高效的线程模型
4.redis自定义的协议