Redis 在面试过程中比较常见的面试题
一、Redis 有几种数据类型和各自的使用场景?
-
数据类型有五种:
1. 字符串(string)类型,内部结构一个带长度信息的字节数组
2. 散列哈希(hash),底层数据格式(两个Hashtable,只有其中一个才有值)
3. 列表(list),按插入的顺序排序的字符串集合,基本是链表(quicklist(当数据量多的时候才会变成),ziplist(压缩列表))
4. 集合(set) ,无序但是不能重复
5. 有序集合(sorted set,也称zset),有序不能重复 -
使用场景
string : key - value ,结构方式,存储一一对接使用比较多,可以注意访问统计,单个字符串不得超过512MB;
hash : 存储用户性别、年龄等跟用户ID绑定存储
list: 消息队列,数据对象
set:统计,共同好友等
zset:排行榜、取前几名、权重的消息队列
二、Redis 的过期策略、内存淘汰机制了解吗?
-
Redis的过期策略:定期删除和惰性删除
定期删除:
给Redis的key 设置有一个过期时间,到期后,key删除。大批量的数据在同一时间内过期失效,会导致缓存穿透或者是缓存雪崩等系列问题。
惰性删除:
数据到达过期时间,但是不立即做处理。等下次访问该数据时,在判断过期与否,没则返回数据,否则返回不存在并删除数据。
节约CPU性能,过期之后再删除,缺点是:内存压力大,长期占用内存。 -
内存淘汰机制
淘汰机制分为6种,默认方式是:noeviction
1.noeviction 默认内存淘汰机制,当达到内存最大值后,对于写请求不在提供服务,直接返回错误(DEL请求和部分特殊请求除外)
2. allkeys-lru : 尝试回收最少使用的键(LRU),使得新添加的数据有空间存放
3. volatile-lru: 尝试回收最少使用的键(LRU),但仅限在过去集合的键,使得有空间存在新的键
4. allkeys-random: 回收随机的键使得新添加的数据有空间存放
5. volatile-random:回收随机的键,但是仅限于在过期集合的键
6. volatile-ttl: 回收在过期集合的键,并且优先回收存活时间(TTL)简短的键,释放空间。 -
回收进程工作机制
1.客户端运行新的指令,添加了新的数据
2.Redis检查内存情况,如果大于maxmemory的限制,则根据定好的策略进行回收
3.一个新的命令执行等等
4.不断地穿越内存限制的边界,通过不断到达边界然后不断回收到边界以下。
三、Redis 的持久化了解吗?
-
redis 提供了不同级别的持久化方式
1. RDB()快照方式,能够在指定的时间间隔对数据进行快照存储
2. AOF()文件记录,记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以Redis协议追加保存每次写的操作到文件末尾。Redis可以对AOF文件进行后台重写,使得AOF文件的体积不至于过大 -
持久化配置
1. RDB快照持久化配置(默认持久化方式,可自行将Redis配置文件(xxx.config)打开配置)
save 900 1 在900s(15m)之后, 如果至少1个key发生变化,则dump内存快照
save 300 10 在300s(5m)之后, 如果至少10个key发生变化,则dump内存快照
save 60 10000 在60s(1m)之后 , 如果至少10000个key发生变化,则dump内存快照2. AOF 文件持久化配置
appendfsync always 每次有数据修改发生时都会写入AOF文件
appendfsync everysec 每秒同步一次
appendfsync no 不同步,高效但是数据不会被持久化3. RDB 和 AOF 两者的优缺点
- RDB:
优点:
1. RDB 是非常紧凑的文件,保存了某个时间点的数据集,非常适用数据的备份。
2. RDB 是紧凑单一文件,方便传输到一个数据中心,很实用于灾难恢复。其中一个出现问题,利用备份文件快速恢复发生灾难数据
3. RDB保存文件是,父进程唯一做的是fork出一个子进程,后面的工作由子进程去完成,父进程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能
4. AOF 相比,恢复大的数据集时,RDB快照方式会更快一些
缺点:
1. 如果希望Redis 意外停止工作清下丢失的数据最少的话,不适用RDB;save 的时间是间隔的,某个时间段在可能因为断电导致数据丢失
2. RDB 经常fork子进程进行保存数据到磁盘,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致一些毫秒级内不能响应。- AOF:
优点:
1. AOF 方式,可以让Redis更持久,可以使用不同的fsync策略,无fsync,每秒fsync,每次写的时候fsync,使用默认的每秒fsync策略,Redis的性能依然很好,出现故障,你最多会丢失1秒的数据
2. AOF 文件是一个进行追加的日志文件,所以不需要写入seek,即使由于某些原因(磁盘空间已满,写的过程中宕机等等)未执行完整的写入命令,可以使用Redis-check-aof
工具修复这些文件
3. Redis 可以在AOF 文件体积变的很大的时候,自动地在后台对AOF进行重写;重写后的新AOF文件包含了恢复当前数据集所需的最小命令集合。过程是绝对安全的,因为Redis在创建新的AOF
文件的过程中,会继续追加现有的AOF文件,即使停机,现有的AOF文件也不会丢失。新的AOF文件创建完后,Redis
就会从旧的AOF切换到新的AOF,并对新的AOF 文件追加操作。
4. AOF 文件有序的保存了对数据库执行的所有写入操作,写入按照Redis的协议保存,因此AOF文件容易被人读懂,对文件解析也轻松。导出AOF同样简单(export指令)
缺点:
1. 对于相同的数据集来说,AOF 文件的体积通常比RDB快照方式的体积大的多
2. 根据fsync的使用策略,AOF 的速度可能会慢于RDB
4. 选择方式:
1. 如果想要达到PostgreSql 的数据安全性,可以使用两种方式
2. 对数据安全,可以承受数分钟以内的数据丢失,那么可以只是用RDB 的save 方式策略
四、Redis 的集群方式了解吗?
高可用集群方式; 主从复制、哨兵模式(sentinel)、Redis cluster(节点)
-
主从复制
逻辑流程:
1.从服务器向主服务器发起sync 或者psync命令
2. 主服务器执行BGsave 命令,生成.rdb文件,并使用缓存区记录从现在的所有写命令
3. rdb.文件生成后,主服务器会将其发送给从服务器
4. 从服务器载入rdb文件,将自己的数据库状态同步更新为主服务器执行的bgsave 命令时的状态
5. 主服务器将缓存区的所有命令发送从服务器将执行这些命令,数据库状态同步为主服务器的最新的状态 -
哨兵模式
哨兵的主要三大作用:监控、通知、故障转移-
监控
同步各个节点的状态信息
获取各个哨兵的状态(是否在线)
获取master的状态属性
获取从节点的状态信息 -
通知
哨兵在检查master时报告master的状态信息,并将结果通知到其他哨兵
-
故障转移
3.1 在哨兵检查到master 宕机,将结果通知其他哨兵,并将状态修改为s-down
3.2 哨兵同步的数据信息中,master宕机了,其他哨兵都会再次向master 发消息,去确认是否跟同步的消息是正确的,如果正确,则会将master的状态修改为o-down
3.3 此时哨兵需要选择一个负责将故障转移的哨兵,哨兵内部竞选,当票数超过一半了,那就是这哨兵当选
3.4 当选哨兵,则需要负责挑选新的master;过程条件是:选择在线的slave ,响应快的、与master的交互的时间最近的、优先级、偏移量,runID要小的。
3.5 将新的master更换信息,slave 节点的master更换最新的数据信息,各个主从节点和哨兵都更新最新的数据,如此往返。老的master上线后,也只能以从节点的方式登入。
-
-
节点(Redis cluster)
Redis 在3.0后加入了cluster模式,它采用的是去无心节点方式实现,集群将会通过分片方式保存数据库的键值对。
1.节点:一个Redis集群中会有多个节点组成,节点相互连接、保存自己和其他节点的信息,使用gossip 协议交换相互的状态、以及保存新加入的节点信息。
2.数据分析
数据库被分为16384个哈希槽,每一个键都属于16384个槽中的一个,集群的每个节点可以有0个或者16384个
3.设置槽指派
命令: 127.0.0.1:6380> ClUSTER addslot 1 2 3 4 5
,将1,2,3,4,5号槽指定本地端口6380的节点负责。