《我想进大厂》之Redis夺命连环11问
这是面试题系列第三篇--redis专题 。
说说Redis基本数据类型有哪些吧
- 字符串:redis没有直接使用C语言传统的字符串表示 , 而是自己实现的叫做简单动态字符串SDS的抽象类型 。 C语言的字符串不记录自身的长度信息 , 而SDS则保存了长度信息 , 这样将获取字符串长度的时间由O(N)降低到了O(1) , 同时可以避免缓冲区溢出和减少修改字符串长度时所需的内存重分配次数 。
- 链表linkedlist:redis链表是一个双向无环链表结构 , 很多发布订阅、慢查询、监视器功能都是使用到了链表来实现 , 每个链表的节点由一个listNode结构来表示 , 每个节点都有指向前置节点和后置节点的指针 , 同时表头节点的前置和后置节点都指向NULL 。
- 字典hashtable:用于保存键值对的抽象数据结构 。 redis使用hash表作为底层实现 , 每个字典带有两个hash表 , 供平时使用和rehash时使用 , hash表使用链地址法来解决键冲突 , 被分配到同一个索引位置的多个键值对会形成一个单向链表 , 在对hash表进行扩容或者缩容的时候 , 为了服务的可用性 , rehash的过程不是一次性完成的 , 而是渐进式的 。
- 跳跃表skiplist:跳跃表是有序集合的底层实现之一 , redis中在实现有序集合键和集群节点的内部结构中都是用到了跳跃表 。 redis跳跃表由zskiplist和zskiplistNode组成 , zskiplist用于保存跳跃表信息(表头、表尾节点、长度等) , zskiplistNode用于表示表跳跃节点 , 每个跳跃表的层高都是1-32的随机数 , 在同一个跳跃表中 , 多个节点可以包含相同的分值 , 但是每个节点的成员对象必须是唯一的 , 节点按照分值大小排序 , 如果分值相同 , 则按照成员对象的大小排序 。
- 整数集合intset:用于保存整数值的集合抽象数据结构 , 不会出现重复元素 , 底层实现为数组 。
- 压缩列表ziplist:压缩列表是为节约内存而开发的顺序性数据结构 , 他可以包含多个节点 , 每个节点可以保存一个字节数组或者整数值 。
redis通过encoding属性设置对象的编码形式来提升灵活性和效率 , 基于不同的场景redis会自动做出优化 。 不同对象的编码如下:
- 字符串对象string:int整数、embstr编码的简单动态字符串、raw简单动态字符串
- 列表对象list:ziplist、linkedlist
- 哈希对象hash:ziplist、hashtable
- 集合对象set:intset、hashtable
- 有序集合对象zset:ziplist、skiplist
- 完全基于内存操作
- C语言实现 , 优化过的数据结构 , 基于几种基础的数据结构 , redis做了大量的优化 , 性能极高
- 使用单线程 , 无上下文的切换成本
- 基于非阻塞的IO多路复用机制
这样做的目的是因为redis的性能瓶颈在于网络IO而非CPU , 使用多线程能提升IO读写的效率 , 从而整体提高redis的性能 。
知道什么是热key吗?热key问题怎么解决?所谓热key问题就是 , 突然有几十万的请求去访问redis上的某个特定key , 那么这样会造成流量过于集中 , 达到物理网卡上限 , 从而导致这台redis的服务器宕机引发雪崩 。
文章插图
针对热key的解决方案:
- 提前把热key打散到不同的服务器 , 降低压力
- 加入二级缓存 , 提前加载热key数据到内存中 , 如果redis宕机 , 走内存查询
解决方案:
- 加锁更新 , 比如请求查询A , 发现缓存中没有 , 对A这个key加锁 , 同时去数据库查询数据 , 写入缓存 , 再返回给用户 , 这样后面的请求就可以从缓存中拿到数据了 。
- 摄像头|李彦宏《智能交通》与百度Apollo,还是小瞧它的胃口了!
- 5G|钮文新:欧美开撕5G内斗——华为让中国领先全球
- 华夏小康| 《令人心动的offer》强势回归,云视听极光带来沉浸式体验
- 米哈游|《原神》云游戏服务商完成B轮4亿元融资,米哈游再度增持
- 苹果|《常识》不改掉这10个坏习惯,小心你的手机很快死翘翘!
- 中国工程院院士|《智能交通》正式出版发行 系国内首部全面阐述智能交通“中国模式”专著
- 杜比|程序员的开源月刊《HelloGitHub》第 68 期
- 5g芯片|AMD 开源驱动让《我的世界》性能提升 30%
- 上路|李彦宏将发新书《智能交通:影响人类未来 10—40 年的重大变革》
- 交互设计|工信部印发《“十四五”信息化和工业化深度融合发展规划》