多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] ## Redis 为什么这么快? 1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于 HashMap,HashMap 的优势就是查找和操作的时间复杂度都是O(1); 2、数据结构简单,对数据操作也简单,Redis 中的数据结构是专门进行设计的; 3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗; 4、使用多路 I/O 复用模型,非阻塞 IO。 ![](https://img.kancloud.cn/18/97/1897e0471bba3e9dc31d5fee9ada4e57_1080x798.jpg) ## 单线程有什么好处? 1. 不会因为线程创建导致的性能消耗; 2. 避免上下文切换引起的 CPU 消耗,没有多线程切换的开销; 3. 避免了线程之间的竞争问题,比如添加锁、释放锁、死锁等,不需要考虑各种锁问题。 4. 代码更清晰,处理逻辑简单。 ## redis hash 字典 Redis 整体就是一个 哈希表来保存所有的键值对,无论数据类型是 5 种的任意一种。哈希表,本质就是一个数组,每个元素被叫做哈希桶,不管什么数据类型,每个桶里面的 entry 保存着实际具体值的指针。 ![](https://img.kancloud.cn/29/9a/299a2bc8d6f33bad90250965652057a5_644x451.jpg) Redis 全局哈希表 **rehash** 整个数据库就是一个全局哈希表,而哈希表的时间复杂度是 O(1),只需要计算每个键的哈希值,便知道对应的哈希桶位置,定位桶里面的 entry 找到对应数据,这个也是 Redis 快的原因之一。 那 Hash 冲突怎么办? 当写入 Redis 的数据越来越多的时候,哈希冲突不可避免,会出现不同的 key 计算出一样的哈希值。 Redis 通过链式哈希解决冲突:也就是同一个 桶里面的元素使用链表保存。但是当链表过长就会导致查找性能变差可能,所以 Redis 为了追求快,使用了两个全局哈希表。用于 rehash 操作,增加现有的哈希桶数量,减少哈希冲突。 开始默认使用 hash 表 1 保存键值对数据,哈希表 2 此刻没有分配空间。当数据越来多触发 rehash 操作,则执行以下操作: 1. 给 hash 表 2 分配更大的空间; 2. 将 hash 表 1 的数据重新映射拷贝到 hash 表 2 中; 3. 释放 hash 表 1 的空间。 值得注意的是,将 hash 表 1 的数据重新映射到 hash 表 2 的过程中并不是一次性的,这样会造成 Redis 阻塞,无法提供服务。 而是采用了渐进式 rehash,每次处理客户端请求的时候,先从 hash 表 1 中第一个索引开始,将这个位置的 所有数据拷贝到 hash 表 2 中,就这样将 rehash 分散到多次请求过程中,避免耗时阻塞。 ## 知识补充 https://mp.weixin.qq.com/s/z4VjDaDDbspFz1rIBwazIA