Redis面试专栏

1.redis是单线程还是多线程?

redis6.0之前是单线程,网络IO和键值对的读写都是单线程的

redis6.0引入了多线性概念,网络IO会有多核处理,服务端处理还是单线程

2. redis单线程为什么还这么快?

  1. 命令执行基于内存操作
  2. 命令的执行是单线程的,没有线程切换的开销
  3. 基于IO复用机制提升IO的利用率(epoll)
  4. 高效的数据存储结构:全局hash表(一维数组+二维链表);

3.redis底层如何用跳表存储?

有序集合zset会采用跳表存储

会将zset先放在一个有序链表中,但是查找效率比较慢;优化的策略是建立索引层,每两个节点取一级索引

举个例子:

链表有8个数据,如果正常进行查询操作,查询8的元素,查询的次数是8次(1到8);但是建立二级索引,链表查询顺序为1->3->5->7->8,查询次数为5次;按此再建立三级索引,查询顺序为1->5->8,如果有几十万的大量数据,可以大大减少查询时间

4.redis的key没有设置过期时间,为什么被删除了?

  • redis key的淘汰策略:
  1. 针对设置过期时间的key的处理

    • volatile-ttl:根据过期时间进行删除,过期时间越长的越先删除

    • volatile-random:在设置过期时间的key中随机删除

    • volatile-lru:在设置过期时间的key中,采用LRU算法进行删除(LRU:最近最少使用)

    • volatile-lfu:在设置过期时间的key中,采用LFU算法进行删除(LFU:最近最不经常使用)

  2. 针对所有key的处理

    • allkeys-random:在所有key中随机删除

    • allkeys-lru:在所有key中,采用LRU算法进行删除

    • allkeys-lfu:在所有key中,采用LFU算法进行删除

  3. 不处理

    • no-eviction:不删除任何数据,拒绝写入操作,报错返回给客户端(OOM),此时redis只响应读操作

5.删除key的命令会阻塞redis吗?

会;

删除String类型的key时时间复杂度为O(1),当String类型key对应的value非常大时,可能会等待删除操作,从而阻塞

删除集合、列表、有序集合或哈希表类型的key,时间复杂度为O(M),M是以上数据结构内的元素个数;在删除这些结构时,当元素的个数很多是,可能会阻塞

6.redis主从、哨兵、集群架构的优缺点

  • 优点

    • 主从架构一主多从,主负责写,从节点负责读,可以实现水平扩容,支持读高并发

    • 哨兵模式解决了主从架构不能自动切换主从节点的问题

    • 集群架构针对海量数据+高并发+高可用的场景

  • 缺点

    • 主从架构的主节点挂掉后,不能自动

    • 每个节点存储的数据是一样的,浪费内存空间。

7.工作原理是什么?

  • 主从架构工作原理

    1. 主节点负责写,从节点负责读,当启动一个从节点时,会发送一个PSYNC命令给主节点

    2. 如果从节点是首次连接主节点,那么会触发一次全量复制,主节点会启动一个后台线程,生成一份RDB文件

    3. 主节点还会同时将新收到的写命令缓存到内存中;生成完RDB文件后,主节点会发送给从节点,从节点将RDB文件写入本地磁盘,再从本地磁盘加载到内存中

    4. 主节点将新收到的写命令发送到从节点进行同步

    5. 如果主从节点连接断开,会进行重连,重连后主节点仅会将部分缺失的数据同步给从节点

  • 哨兵模式工作原理

    1. 每个sentinel一每秒一次的频率向它所知道的主从节点以及其他sentinel实例发送一个PING命令

    2. 如果一个实例距最后一次有效回复PING命令的时间超过了指定值,这个实例就会被sentinel记录为主观下线

    3. 如果一个master实例被标记为主观下线,则在监视这个master的sentinel要以每秒一次的频率确认master是否真正进入主观下线状态

    4. 当足够数量的sentinel在指定时间内确定master确实进入了主观下线状态,则maste会被标记为客观下线;如果没有足够数量的sentinel同意master已经下线,则master客观下线的状态被解除

    5. sentinel节点会选举出sentinel leader,负责故障转移工作

    6. sentinel leader会推举出表现良好的从节点成为新的主节点

  • 集群模式工作原理

    1. 通过hash的方式,将数据分片,每个节点均分存储一定哈希槽区间的数据,默认分配16384个槽位

    2. 每份数据分片会存储在多个互为主从的多节点上

    3. 数据写入先写主节点,在同步到从节点

    4. 同一分片多个节点间的数据不保持一致性

    5. 读取数据时,客户端操作的key没有分配在该节点上时,redis会返回转向指令,指向正确的节点

    6. 扩容时需要把旧节点的数据迁移一部分到新节点

8.redis集群架构hash分片算法是什么?

  1. 每个节点均分存储一定哈希槽区间的数据,默认分配16384个槽位

  2. 通过槽位定位算法,对key使用crc16算法得到一个值,把这个值对16384取模得到槽位

9.randomkey会导致Redis阻塞吗?

会,如果randomkey挑选的key都是失效的key,则会存在阻塞问题;

  1. 如果在master节点执行randomkey,redis会采用惰性删除过期key策略,但是每次randomkey都获取到了失效key,还是会使redis效率变慢

  2. 如果在salve节点执行randomkey,salve节点删除失效key需要等待master节点返回删除命令,如果失效的key较多,redis来不及删除,则randomkey会进入死循环,导致redis阻塞

10.redis的持久化策略

Redis支持两种方式的持久化,一种是RDB的方式,一种是AOF的方式。前者会根据指定的规则定时间将内存中的数据存储在硬盘上,而后者在每次执行完命令后将命令记录下来。一般将两者结合使用。

  • RDB方式:RDB是redis的默认持久化方式,持久化时会将内存中的数据写入磁盘中,在指定的目录下生成一个dump.rdb文件,当redis重启时会去加载dump.rdb文件恢复数据。
  • RDB持久化过程:
  1. 创建一个子进程
  2. 父进程继续接受并处理客户端的请求,子进程开始将内存中的数据写入磁盘
  3. 当子进程写完所有数据后,会用临时文件替换旧的RDB文件
  4. ☆当redis重启时会读取rdb快照文件,将数据从磁盘载入内存,此时如果redis异常退出,则会丢失最近一次持久化的数据
  • 触发RDB快照的方式:

    ①手动触发:

       主要是SAVE和BGSAVE命令;SAVE命令触发的rdb快照会阻塞客户端发来的请求,而           BGSAVE命令触发rdb快照是异步操作,快照的同时还能响应客户端请求(一般使用               BGSAVE命令)。 

注意:LASTSAVE 命令用于查看 BGSAVE 命令是否执行成功。

    ②被动触发:

  1. 在redis配置文件中配置自动快照(SAVE 300 10:表示300秒内至少有10个key被修改则进行快照)

  1. 如果从节点执行全量复制操作,主节点自动执行BGSAVE生成rdb文件发送给从节点
  2. 默认情况下执行shutdown命令,如果没有开启AOF,则会自动执行BGSAVE
  3. 执行debug reload命令重新加载redis时,会自动触发SAVE操作
  • AOF方式:用独立的日志方式记录每次写命令,redis重启时会重新执行AOF文件中的命令达到数据恢复目的;默认redis是不开启AOF持久化的,可以使用appendonly参数开启(appendonly yes);开启后每执行一条写命令,redis会把该命令写进aof_buf缓冲区,AOF缓冲区会根据对应的策略向磁盘做同步操作
  • 同步时机:默认是30秒执行一次同步,为了防止缓冲区数据丢失,可以用appendsync 参数设置同步时机
  1. appendsync always:每次写入aof文件都会执行同步,最安全但是最慢,不建议配置
  2. appendsync everysec:将aof_buf缓冲区中的所有内容写入到AOF文件,如果上次同步AOF文件的时间距离现在超过一秒钟,那么再次对AOF文件进行同步,并且这个同步操作是由一个线程专门负责执行的(默认)
  3. appendsync no :将aof_buf缓冲区中的所有内容写入到AOF文件,但并不对AOF文件进行同步,何时同步由操作系统来决定
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值