Redis作者: 意大利人 Salvatore Sanfilippo(网名 Antirez) 开发。Antirez 不仅帅的不像实力派,也非常有趣。Antirez 今年已经四十岁了,依旧在孜孜不倦地写代码,为 Redis 的开源事业持续贡献力量。
Redis是一个开放源代码(BSD许可)内存中的数据结构存储,用作数据库、缓存和消息代理。它支持字符串、哈希、列表、集合、带范围查询的排序集合、位图、超日志和流的地理空间索引等数据结构。Redis具有内置的复制、lua脚本、lru回收、事务和不同级别的磁盘上持久性,并通过Redis Sentinel和Redis集群的自动分区提供高可用性。
1、Redis是用C语言实现的,一般来说C语言实现的程序“距离”操作系统更近,执行速度相对会更快。
2、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);正因为 Redis 是单线程,所以要小心使用 Redis 指令,对于那些时间复杂度为 O(n) 级别的指令,一定要谨慎使用,一不小心就可能会导致 Redis 卡顿。
3、数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗。
4、使用多路I/O复用模型,非阻塞IO,Redis 单线程处理大量的并发客户端连接的模型。
5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;协议简单采用RESP协议。
作者对于Redis源代码可以说是精打细磨,曾经有人评价Redis是少有的集性能和优雅于一身的开源代码。
第一层:客户端,大家熟知的如原生redis-cli、JAVA语言Jedis、Python语言redis-py等
第二层:通信,传输层基于TCP的resp协议
第三层:服务端,多路复用、事件循环、持久化等
每当一个套接字贮备好连接应答、写入、读取关闭等操作的时候就会产生一个文件事件。也就是说客户端服务器发送连接、读、写命令都属于文件事件。
Redis基于Reactor模式开发了自己的网络时间处理器,称为文件事件处理器。
文件事件处理器由四部分组成,分别是套接字,I/O多路复用程序,文件事件分派器,以及事件处理器。I/O多路复用程序,既可以让文件处理器以单线程方式运行,保持redis内部设计的简单性。同时又可以同时监听多个套接字。
I/O多路复用程序会将多个并发产生的文件事件放在一个队列中,通过队列有序、同步的、每次一个套接字的方式向文件事件分派器传送套接字。只有上一个套接字处理完毕后,I/O多路复用程序才会向文件事件分派器派发下一个套接字。
1、连接应答处理器
2、命令请求处理器
3、命令回复处理器
Redis的时间事件分为以下两类:
1、定时事件:让一段程序在指定的时间之后执行一次。比如说,让程序X在当前时间的10ms之后执行一次。
2、周期性事件:让一段程序每隔指定时间就执行一次。比如说:让程序Y每隔10ms执行一次。
服务器将所有的时间事件都放在一个无序的链表中,每当时间事件执行器运行时,它就遍历整个链表,查找所有已到达的时间事件,并调用相应的事件处理器。