东莞建站公司快荐全网天下特别好,网站 单页,新手可以自己建网站吗,岑巩网站建设这是我第一次尝试以长文的形式写一篇 Redis 的总结文章。这篇文章我想写很久了#xff0c;只是一直碍于我对 Redis 的掌握没有那么的好#xff0c;因此迟迟未动笔。这几天#xff0c;我一直在看各种不同类型的 Redis 文章#xff0c;通过阅读这些文章#xff0c;引发了我对…这是我第一次尝试以长文的形式写一篇 Redis 的总结文章。这篇文章我想写很久了只是一直碍于我对 Redis 的掌握没有那么的好因此迟迟未动笔。这几天我一直在看各种不同类型的 Redis 文章通过阅读这些文章引发了我对于 Redis 这个大知识点的很多思考。我看过的一篇又一篇的文章都帮助着将我脑子里我学过的 Redis 的零散知识点整合在一起从而构建一个 Redis 全局系统观帮助着我用一个全局的方式看待 Redis 这个存储系统。接下来我计划用文字的方式将我脑子里的 Redis 蓝图一一描绘出来。
Redis什么是 RedisRedis 就是一个键值对数据库。所以当别人跟你说 Redis 的时候你的脑子里应该立马想到键值对数据库。我一开始以为这就是 Redis其实这并不是这仅仅是 Redis 的其中一个模块而已。对于一个完整的 Redis应该是由6大模块组成的访问模块、索引模块、操作模块、存储模块、高可用集群模块、高可扩展集群模块。 访问模块
访问模块就是我们平时一定会接触的 Redis 的网络IO线程模型如图 Redis 是一个典型的 client-server 模型。首先客户端先找 server-socket 建立连接产生一个事件。IO多路复用器看到这么一个事件就把事件压入队列。文件事件分派器看到队列里有事件就把事件拿出来交给对应的事件处理器进行处理。处理过程是事件处理器会建立一个与客户端 socket 对应的新 socket。只要客户端 socket 与这个新 socket 通信比如说发起了一个请求新 socket 就会产生一个事件然后IO多路复用器就会看到这个事件......重复上面的步骤。
这就是 Redis 的访问模块。访问模块也就是我们说的网络IO单线程模型。我的理解就是如果我们想访问 Redis 里面的键值对数据库底层第一步要做的就是先进入这个键值对数据库进入的方式就是我上面说的网络IO单线程模型。 索引模块
OK回到刚才我刚刚不是说了通过访问模块我们已经访问到了键值对数据库了吗那你有没有想过这个键值对数据库是长什么样子的又或者说这些键值对在 Redis 中是怎么存放的那个画面你想过吗其实是用一张全局哈希表来存放所有键值对的。这个哈希表由多个哈希桶组成每个哈希桶存放一个或多个键值对。key 很好理解因为 key 存放的只是 String 类型但是 value 就不好理解了value 支持很多种数据类型String、列表、哈希、set、zset。这些数据类型中除了 String 类型之外其他的几种类型都是数据集合。不过我当时在学习的时候就想象不出这个画面我就想一个 value 能存这么多数据在我的理解里我只能理解 value 是 String 类型的这种情况value 是 String 类型的话value 是存一个数据的这很符合我的印象。后来我看到了一篇文章然后我恍然大悟原来 key-value 键值对存放的并不是实际的值而是指针这些指针指向数据集合就像这样 如果键值对越来越多越来越多的话我们就采用 rehash即哈希扩容。这里的哈希扩容是渐进式的没错就是你学过的那个渐进式哈希扩容每次对哈希表进行一次插入或者删除操作就转移一个桶的数据到新表中就像这样 操作模块
OK通过上面的文字和图片我们应该大致知道 Redis 这个键值对数据库里面大概长什么样了接下来我们来看看操作模块。操作模块其实就是对键值对的一些操作除了一些最基础的 put、get、delete 之外根据 value 中数据类型的不同会有不同的操作方法。比如说假如这个键值对的 value 的数据类型是列表 List那么针对这种数据类型就提供 push 进队和 pop 出队这些对应的操作就这么简单。 存储模块
这是 Redis 中最核心的模块了因为这里知识点最多但是又不是最难我花了好多时间去理解这个知识点理解了之后感觉有种高山看海海浪真美的感觉。
存储模块研究的就是 value 中的5种数据类型和底层的6种数据结构就像这个图 String ——动态字符串
String 这种数据类型真的是万金油名字虽然叫 String但是它还可以存文本数据.....感觉啥都能存。String 类型的底层数据结构是动态字符串动态字符串提供了丰富的 String 操作命令增减、排序、查找、计数.....比如我之前实习的公司它就用 String 来做计数器用来记录用户的刷新次数防止一个用户一直刷新。 List ——双向链表、压缩链表
List这种数据类型的底层是双向链表的话我们其实可以用 Redis 来做一个轻量的消息队列具体怎么实现我之前好像写过一篇文章能否把 Redis 当做消息队列来用呢-CSDN博客
而如果 List 的底层用压缩列表来实现的话就体现出 Redis 很快很省。因为压缩列表压缩嘛肯定省而且数据被压缩成连续的所以查找起来就很快。 Hash ——压缩列表、哈希表
Hash 这种数据类型的底层实现可以是压缩列表或者是哈希表。如果底层实现是哈希表的话那么 Redis 就可以用于缓存比如说缓存用户的基本信息。怎么缓存用户的基本信息就是 key 是用户IDvalue 是用户的基本信息。 Set ——哈希表、整数数组
Set 这种数据类型的特点就是无序且不重复。之所有有这种特点就是因为它底层的数据结构。哈希表是散列的是吧散列那肯定就无序啊而哈希表我们都学过不允许存重复的元素所以数据就不重复。即哈希表是无序不重复的因此Set也是无序不重复的。如果你用 Redis 来做消息队列的话那么这个 Set 可以帮助保持消息队列的幂等性即消息不被重复消费。假如你理解不了这个例子那换一个更加简单的你肯定可以理解的例子。有一个数组a[5][2,4,2,4,7,6]你用一下Set直接变成了[2,4,7,6],这你能理解了吧 ZSet —— 压缩列表、跳跃表
ZSet 和 Set 很像只不过比起 SetZSet 是有序的就这点不同其他的感觉大差不差。比如说a[5][2,4,2,4,7,6]你用一下 ZSet直接变成了[2,4,6,7]。所以Redis可以用于排行榜。
其实 Zset 本身并没有什么好讲的但是 ZSet 底层用跳跃表这种数据结构来实现跳跃表就可以好好讲讲了。假如我们用跳跃表这种数据结构来支持 ZSet 这种数据类型那么在对 ZSet 这个有序集合的插入删除查找都是非常快的。跳跃表的原理我口头说不清我觉得还是展示图片比较实在。我这里不谈跳跃表的插入删除操作就谈跳跃表的查找操作。 说实话其实我也不是很理解暂时有点乱。不过关键的一点就是通过上一层的元素来确定目标元素所在的区间。
我感觉跳跃表的查找就好像搭地铁一样快线慢线互相搭配从而最快达到目的地。 高可用集群模块
高可用集群模块其实就是主从复制哨兵机制还有 AOF 和 RDB 技术。事实上感觉面试的 AOF和 RDB 技术这两个问的多一点而主从复制哨兵机制问的并不算多也有可能是主从复制哨兵机制相对而言比较复杂吧。关于 Redis 实现高可用的思想和 kafka 消息队列很像特别是主从复制哨兵机制那一块感觉一模一样哈哈哈。 高可扩展集群模块
这个模块也没什么好讲的Redis 就是通过数据分片来实现高扩展的。这一块感觉面试也问的不多所以我也仅仅是做了简单的了解并没有深挖太多。 总结
以上就是我脑图中的 Redis 的6大模块。假如你想要对键值对进行操作首先你需要通过访问模块网络IO单线程模型然后你才可以进入到 Redis 的内部。在 Redis 内部键值对是怎么存放的呢其实是通过全局哈希表来存放所有键值对的我也配了图这就是索引模块。知道了 Redis 里面长什么样了就到了真正对键值对进行操作了操作模块其实就是一些简单的操作 put、get、delete 加上 value 中不同数据类型提供的一些不同的操作。最后是存储模块存储模块研究的问题是 value 中的值是用什么结构进行存储的我们研究了5种数据类型以及这5种数据类型背后的6种底层数据结构我也配了图顺便说了一下这5种数据类型的一些使用场景。
其实这篇文章还没写完但是 CSDN 的文章评分机制是如果写太长的话文章评分会降低然后影响推流所以我只好拆开来写了。