Redis 面试题整理 —— 数据类型、单线程、持久化、高可用

Redis 的数据类型

Redis 的五大基本数据类型

  1. String 字符串
  2. Hash 散列
  3. List 列表
  4. Set 集合:无序不重复
  5. Zset 有序集合

在 Redis 中,可以把 List 当作栈、队列、阻塞队列使用

Hash 等同于一个 Map 集合,以 Key-Value 的形式存在;可以存储变更的数据和对象

五大基本数据类型的使用与底层实现

Redis 的三种特殊数据类型

  1. geospatial 地理位置,底层使用 Zset 实现
  2. Hyperloglog ,占用内存固定,有一定的容错率;可以用于网页UV
  3. Bitmaps 位图,操作二进制位进行记录,只有0、1两个状态

三种特殊数据类型的使用

Redis 的单线程

Redis 是单线程还是多线程?

Redis 不同版本之间采用的线程模型是不一样的,在 Redis4.0 版本之前使用的是单线程模型,在 4.0 版本之后增加了多线程的支持

在 4.0 之前说 Redis 是单线程,也只是说它的网络 I/O 线程以及 SetGet 操作是由一个线程完成的

但是 Redis 的持久化、集群同步还是使用其他线程来完成。4.0 之后添加了多线程的支持,主要是体现在大数据的异步删除功能上,例如 unlink keyflushdb asyncflushall async

Redis 为什么选择单线程?

单线程的特点:

  1. 单线程使用简单,不存在锁竞争,可以在无锁的情况下完成所有的操作
  2. 不会因为死锁和线程切换而带来性能和时间上的额外开销
  3. 但是单线程也不能完全发挥出多核 CPU 的性能

Redis 使用单线程但是速度快的原因:

  1. Redis 的大部分操作都是在内存中完成的,内存中的执行效率本身就很快,并且 Redis 也采用了高效的数据结构,比如哈希表和跳表
  2. 使用单线程避免了多线程的竞争,省去了多线程切换带来的时间和性能开销,并且不会出现死锁
  3. 采用 I/O 多路复用机制处理大量客户端的 Socket 请求,因为是基于非阻塞的 I/O 模型,所以可以高效地进行网络通信,I/O 的读写流程也不再阻塞

Redis 持久化

Redis 持久化之 RDB 与 AOF 使用分析

与 memcached 一样,为了保证效率,Redis 的数据都缓存在内存中

为了保证 Redis 数据不丢失,就要把数据从内存存储到磁盘上,以便在服务器重启后,还能够从磁盘中恢复原有数据,这就是 Redis 的数据持久化

Redis 会周期性地把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并在此基础上实现了主从同步

Redis 持久化的三种方式

o AOF 日志(Append Only File,文件追加方式):

以日志形式记录服务器所处理的 所有的写和删除操作命令(不会记录查询操作),并以文本的形式追加到文件中。

o RDB 快照(Redis DataBase):

在指定时间间隔内,生成数据集的时间点快照(Point-in-time Snapshot),将内存的数据以二进制的方式写入磁盘。

RDB 的执行频率对 Redis 非常重要,因为这会影响快照数据的完整性以及 Redis 的稳定性

o 混合持久化方式:

Redis 4.0 新增了混合持久化的方式,集成了 RDB 和 AOF 的优点。

把数据以 RDB 的方式写入文件,再将后续的操作命令以 AOF 的格式存入文件,既保证了 Redis 重启速度,又降低数据丢失风险。

RDB 生成快照的过程

Redis 提供了两个命令来生成 RDB 快照文件,分别是 savebgsavesave 命令在主线程中执行,会导致阻塞。而 bgsave 命令则会创建一个子进程,用于写入 RDB 文件的操作,写入成功后再替换之前的文件,避免了对主线程的阻塞,这也是 Redis RDB 的默认配置

save 是同步的,会阻塞客户端命令;如果使用 bgsave,RDB 做快照的时候数据集是可以修改的

bgsave 的子线程操作:

  1. 如果主线程执行读操作,则主线程和 bgsave 子线程互不影响
  2. 如果主线程执行写操作,则被修改的数据会复制一份副本,然后 bgsave 子进程会把该副本数据写入 RDB 文件,在这个过程中,主线程仍然可以直接修改原来的数据

Redis 的后写日志

Redis 采用先执行命令,再把数据写入日志的方式

因为 Redis 在写入日志前,不会对命令进行语法检查,所以只能记录执行成功的命令,避免出现记录错误命令的情况;而且在命令执行后再写日志,也不会阻塞当前的写操作

后写日志的风险:

  • 数据可能会丢失
    如果 Redis 刚执行完命令,此时发生故障宕机,会导致这条命令存在丢失的风险

  • 可能阻塞其他操作
    AOF 日志其实也是在主线程中执行的,所以当 Redis 日志文件写入磁盘时,还是会阻塞后续的操作无法执行

RDB 与 AOF 比较

  • 安全性

    由于 AOF 的记录可以精确到秒级追加,甚至逐条追加;而 RDB 只能全量复制;所以 AOF 的安全性更高

  • 性能

    RDB 是 Redis 性能最大化的体现,不用每秒监控是否有数据写入,当达到触发条件后,就自动 fork() 一个子进程进行全量更新

  • 容灾恢复

    RDB 可以更快地恢复数据,而 AOF 需要读取再写入,相对较慢

Redis 高可用

Redis 实现高可用主要有三种方式:

  1. 主从复制
    将一台 Redis 服务器,同步数据到多台从 Redis 服务器上,即一主多从的模式,这个跟MySQL主从复制的原理一样

  2. 哨兵模式
    使用 Redis 主从服务的时候,会有一个问题,就是当 Redis 的主服务器出现故障宕机时,需要手动进行恢复,为了解决这个问题,Redis 增加了哨兵模式(因为哨兵模式做到了监控主从服务器,并且提供自动容灾恢复的功能

  3. Redis 集群
    Redis Cluster 是一种 分布式去中心化 的运行模式,是在 Redis 3.0 版本中推出的 Redis 集群方案,它将数据分布在不同的服务器上,以此来 降低系统对单主节点的依赖,从而 提高 Redis 服务的读写性能

Redis 为什么需要集群模式

哨兵模式归根结底还是主从模式,在主从模式下我们可以通过增加 slave 节点来扩展读并发能力,但是没办法扩展写能力和存储能力,存储能力只能是 master 节点能够承载的上限。所以 为了扩展写能力和存储能力,我们就需要引入集群模式

Redis Cluster 在存储时候是通过 类一致性哈希算法 实现节点选择的

主从复制的特点

数据复制是单向的,只能从主节点到从节点

master 以写为主,slave 以读为主

默认情况下,每台 Redis 都是主节点,一个主节点可以有多个从节点(或者没有);但是一个从节点只能有一个主节点

主从复制的作用:

  1. 数据冗余:实现了数据的热备份,持久化之外的一种数据冗余方式
  2. 故障恢复:服务的冗余,当主节点出现问题时,可以由从节点提供服务,快速地故障恢复
  3. 负载均匀:读写分离,写 → 连接主节点;读 → 连接从节点
  4. 高可用的基石

热备份:
数据库处于正常运行状态下的备份

冷备份:
离线备份,数据库关闭且数据库不能更新的状态下进行的数据库完整备份

你可能感兴趣的:(Java,开发,大数据,redis,数据库)