Redis
Hash 类型的底层数据结构
- hash 底层的结构是 ziplist 和 hashtable
- 默认情况下:
- 当 ziplist 中 entry 的数量超过 512 的时候,会转成 hashtable
- 单个元素的值超过 64 字节的时候,会转成 hashtable
- 在 Redis 中 hashtable 就是字典 dict
- ziplist 是一种特殊编码的双链表,被设计成非常节省内存,它存储字符串和整型值,其中整数被编码为实际整数,而不是一系列字符
基础
什么是 Redis
- Redis 是一种基于键值对的 NoSQL 数据库
- Redis 的 value 支持字符串、哈希、列表、集合、有序集合、位图等多种数据结构
- Redis 将所有的数据都存放在内存中,读写性能很高
- Redis 将内存的数据利用快照和日志的形式保存到硬盘,确保断电时内存数据不会丢失
Redis 的基本操作
- 设置和获取键值对:SET key value、 GET key
- 删除键值对:DEL key
- 检查键是否存在:EXISTS key
- 设置键的过期时间:EXPIRE key second
- 获取键的剩余过期时间:TTL key
Redis 可以用来干什么
- 缓存
- 计数器
- 排行榜
- 消息队列
- 分布式锁
Redis 有哪些数据结构
- String 字符串
- hash 哈希
- list 列表
- set 集合
- sorted set 有序集合
Redis 应用场景
- String:缓存、计数、共享 session、限速
- hash:缓存用户信息、缓存对象
- list:消息队列、文章列表
- set:标签、共同关注
- sorted set:用户点赞统计、用户排序
在缓存场景中的应用:
- LRU 缓存:Redis 可以很容易地实现 LRU(Least Recently Used,最近最少使用)缓存策略
- 超时设置:可以对每个缓存项设置 TTL(Time to Live,生存时间)
- 分布式缓存:多个 Redis 实例可以组成一个分布式缓存系统
- 布隆过滤器:Redis 从版本 4.0 开始,通过 RedisBloom 插件支持布隆过滤器,以减少对存储层的不必要访问
布隆过滤器
- 布隆过滤器(Bloom Filter)是一种数据结构,专门用于高效地检查一个元素是否属于一个集合
- 布隆过滤器(Bloom Filter)在缓存系统中主要用于减少对底层数据存储(如数据库或磁盘)的不必要访问,从而提高系统的性能
- 具体来说,在一个缓存系统中,布隆过滤器可以用作一个“前置屏障”,用于判断一个特定的数据项是否存在于缓存或底层存储中
Reids 为什么这么快
- 完全基于内存操作
- Redis 是 C 语言实现的
- 使用单线程,避免线程切换的开销
- 基于非阻塞的 IO 多路复用机制(事件驱动,收发消息不会阻塞线程)
Redis6.0 使用多线程是怎么回事?
- 多线程处理数据的读写和协议解析,提高 IO 读写的效率
- Redis 执行命令还是单线程
持久化
Redis 持久化⽅式有哪些?有什么区别?
Redis 持久化方案分为 RDB 和 AOF 两种
RDB
- RDB 持久化是把当前进程数据生成快照保存到硬盘的过程
- 触发 RDB 持久化的过程:手动触发和自动触发
- RDB 文件是一个压缩的二进制文件,通过 RDB 文件可以还原某个时刻数据库的状态
AOF
- AOF 持久化是以独立日志的方式记录每次写命令
- 重启时再次重新执行 AOF 文件中的命令达到恢复数据的目的
- AOF 的主要作用是解决了数据持久化的实时性
RDB 和 AOF 各自有什么优缺点?
RDB
- 优点:
- 压缩的二进制文件,适合备份、全量复制的场景
- 恢复数据快
- 缺点:
- 实时性低,RDB 是间隔一段时间进行持久化,做不到实时持久化
- 存在兼容问题,老版 Redis 无法兼容新版本的 RDB
AOF
- 优点:
- 实时性好
- 缺点:
- AOF 文件大,恢复速度慢
- 数据集大时,启动效率低
RDB 和 AOF 如何选择?
- 如果想保证很好的数据安全性,同时使用两种持久化功能
- 可以接收数分钟内的数据丢失,可以只使用 RDB 持久化
Redis 的数据恢复?
- 当 Redis 发生故障,可以从 RDB 或 AOF 中恢复数据
- 将 RDB 或者 AOF 文件拷本到 Redis 的数据目录下
- 如果使用 AOF 恢复,配置文件开启 AOF,然后启动 Redis-Server
Redis 4.0 的混合持久化了解吗?
- 重启 Redis 时,很少使用 RDB 恢复内存状态,因为会丢失大量数据
- 通常使用 AOF 日志,但是使用 AOF 日志的性能太慢,启动需要很长时间
- 因此 Redis4.0 为了解决这个问题,使用混合持久化
- 将 RDB 文件的内容和增量的 AOF 日志文件存放在一起
- 在 Redis 重启时,可以先加载 RDB 的内容,然后再加载增量 AOF 日志,就可以完全替代之前的 AOF 全量文件,提高重启的效率
高可用
主从复制了解吗?
- 主从复制:将一台 Reids 服务器的数据,复制到其他的 Reids 服务器
- 前者称为主节点,后者称为从节点
- 数据的复制是单向的,只能由主节点到从节点
- Reids 主从复制支持主从同步和从从同步两种
主从复制的作用
- 实现数据的热备份
- 提供快速的故障恢复功能
- 负载均衡
- 高可用基石
Redis 主从有几种常见的拓扑结构?
- 一主一从
- 一主多从:星形拓扑结构,使得应用端可以利用多个从节点实现读写分离
- 树形主从结构:从节点不但可以复制主节点数据,还能作为其他从节点的主节点继续向下复制
Redis 的主从复制原理了解吗?
- 保存主节点信息
- 主从建立连接
- 发送 ping 命令,检测主从间套接字是否可用
- 权限验证
- 同步数据集,主节点把持有的数据发送给从节点
- 命令持续复制,主节点持续把写命令发送给从节点,保证主从数据一致
说说主从数据同步的方式?
主从数据同步分为全量复制和部分复制
- 全量复制:
- 一般用于初次复制场景,把主节点全部数据一次性发送给从节点
- 当数据量较大时,会对主从节点和网络造成很大开销
- 部分复制:
- 针对全量复制开销过大做出的优化
- 当从节点正在复制主节点时,如果出现网络断开,或者命令丢失等异常,从节点会向主节点要求补发丢失的命令数据
- 如果主节点的复制缓冲区存在这部分数据,则直接发送给从节点,保证主从数据一致
主从复制存在哪些问题呢?
- 主节点发生故障时,需要手动将从节点升级为主节点
- 主节点的写能力受到单机的限制
- 主节点的存储能力受到单机的限制
Redis Sentinel(哨兵)了解吗?
- 主从复制存在问题时,不能完成自动故障转移,使用哨兵完成
- Redis Sentinel 分为两部分:哨兵节点和数据节点
- 哨兵系统由多个哨兵节点组成,哨兵节点是特殊的 Redis 节点,不存储数据,对数据节点进行监控和自动故障转移
Redis Sentinel(哨兵)实现原理知道吗?
- 定时监控
- 主观下线
- 客观下线
- 领导者 Sentinel 选举
- 选出一个 Sentinel 作为领导者进行故障转移的工作
- 使用 Raft 算法实现领导者选举
- 故障转移:
- Sentinel 领导者节点会对选出的从节点执行命令,使其成为主节点
- 对其他从节点执行命令,使其成为新主节点的从节点
- 并将原来的主节点更新为从节点,并保持关注,恢复后命令它复制新的主节点
Reids 应用
Redis 支持事务吗?
- 支持简单的事务
- 所有的指令缓存在服务器的事务队列中,收到执行指令,才开始执行整个事务队列,执行完毕后一次性返回所有指令的运行结构
- Redis 事务不支持回滚,因为不支持回滚可以保证简单快速的特性