技术面试整理

服务配置管理

redis篇

1. 什么是redis?

​ redis是一种开源的基于内存的数据库,对数据的读写都在内存中完成,读写速度非常快。常用于缓存,消息队列,分布式锁等场景。redis常用的数据类型有string(字符串)、list(列表)、set(集合)、zset(有序集合)、hash(哈希),并且对数据类型的操作都是原子性的。除此之外redis还支持事务、数据的持久化、lua脚本、多种集群方案、发布/订阅模式、内存淘汰机制、过期删除等

2.redis和memcached的区别?

redis与memcached共同点:

  1. 都是基于内存的数据库,一般都用做缓存
  2. 都有过期策略
  3. 性能都非常高

redis与memcached的区别:

  1. redis支持的数据类型更丰富(string、list、set、zset、hash),memcached支持简单的key-value数据类型
  2. redis支持数据持久化,重启的时候可以再次加载进行使用;memcached不支持持久化,memcached重启或挂掉之后数据丢失。
  3. redis支持集群模式部署,memcached没有集群功能,需要客户端来实现数据的分片写入。
  4. redis支持发布/订阅,lua脚本,事务等功能,而这些memcached都不支持。

3. 为什么redis作为mysql的缓存?

主要原因是redis具备高性能和高并发两种特性。

  1. redis高性能

    用户第一次访问数据库的数据,这个过程会比较慢,因为是从硬盘中获取。将该用户数据加载到内存中第二次访问的时候可以直接从缓存中获取,也称为缓存命中,操作缓存就是直接操作内存,速度相当快。mysqL数据在更改后,同步改变redis中缓存中的数据即可,不过在这个过程中redis和mysql会存在数据一致性问题。

  2. redis高并发

    单台redis的QPS(每秒处理完请求的次数)是mysql的10倍,官方单机redis的QPS可破10W。mysql的单机QPS很难达到1W。直接访问redis能够承受的请求远远高于mysql

4.redis是单线程吗?

redis的单线程指的是“接收客户端请求->解析请求->进行数据读写操作->发送数据给客户端”这个过程是由一个线程来完成。这就是我们通常所说的redis的单线程原因。

​ redis2.6版本会启动2个后台线程,分别处理关闭文件、AOF刷盘这两个任务。

​ redis4.0版本后增加了一个新的后台线程,用来异步释放redis的内存,也就是lazyfree线程。会把一部分删除的操作交给这个后台线程来执行,优势是不会造成redis的主线程卡顿,当我们要删除一个大的key时,尽量不要使用del命令。del删除时主线程来执行的,这样容易导致主线程卡顿。之所以redis为 AOF刷盘,关闭文件、释放内存单独设置线程是因为这些操作都很耗时都交给主线程来执行,redis主线程很容易发生阻塞,影响redis的性能。

5.redis为什么在6.0版本后又引入了多线程?

	首先我们应该要了解为什么redis设计使用单线程,首先CPU并不是制约redis性能的瓶颈,更过情况下redis受到内存大小和网络I/O的限制,所以redis的核心网络模型使用单线程。使用单线程可维护性高,多线程模型增加了系统的复杂度,同时也会存在线程的上下文切换、加解锁、死锁造成的性能损耗。redis6.0版本之后采用了多个I/O线程来处理网络请求,这是为了提高网络I/O的并行度,但是对于命令的执行,redis仍然采用单线程来处理。

6.redis如何实现数据的不丢失?

​ redis共有三种数据持久化的方式:

1. AOF日志:没执行一条写命令,就把该命令以追加的方式追加到一个AOF文件里。

2. RDB快照:将某一时刻的内存数据,以二进制的方式写入rdb文件
3. 混合持久化:redis4.0版本后新增的方式,集成了AOF和RDB的优点

7.AOF日志如何实现?

​ redis在执行完一条写命令后,就会把该命令以追加的方式写到一个文件里,redis重启后,会读取该文件的记录,然后逐一执行命令恢复数据。

​ AOF提供了三种写盘策略:

1. always: 每次写操作执行完后,立即将AOF数据记录到磁盘

2. everysec:每次写操作命令执行完后,先将命令写入到AOF文件的内核缓冲区,然后每隔一秒将缓冲区内容写入到磁盘。
3. NO:表每次执行完写操作命令后,先将命令写入到AOF的内核缓冲区,再由操作系统调度控制将缓冲区数据写回磁盘

AOF的重写机制:

redis为了避免AOF文件越写越大,提供了AOF重写机制,当 AOF 文件的大小超过所设定的阈值后,Redis 就会启用 AOF 重写机制,AOF重写机制是在重写时,读取数据库中的所有键值对,然后将每一个键值对用一条命令记录到「新的 AOF 文件」,等到全部记录完后,就将新的 AOF 文件替换掉现有的 AOF 文件。

8.RDB快照是如何实现的?

​ RDB快照记录的是某一时刻的内存数据,redis提供了两个命令来生成RDB快照,分别是save和gbsave。区别就在于是否在redis主线程执行。

  1. 执行save命令,会在主线程生成RDB文件,由于和执行命令在同一个线程,所以如果写RDB文件时间太长,会阻塞主线程。

  2. 执行bgsave命令,会创建一个子进程来生成RDB文件,这样可以避免主进程的阻塞。

redis通过以下配置文件选项来实现每隔一段时间自动执行一次bgsave命令:

​ save 900 1 #900秒内对数据库进行了至少一次修改

​ save 300 10 # 300秒内对数据库进行了至少十次修改

​ save 60 10000 # 60秒内,对数据库进程了至少10000次修改

9.为什么会有混合持久化?

​ RDB的有点是数据恢复速度,但是快照的频率不好把我,AOF的优点是丢失数据少,但是数据恢复不快。redis4.0版本后新提出了混合持久化的策略。

混合持久化是发生在AOF日志重写过程中,AOF文件的前半部分数据是RDB格式的全量数据,后半部分是AOF格式的增量数据。

​ 优点:开头为RDB的格式,使得redis可以更快的启动,同时结合AOF的优点,又最大限度的减少数据的丢失

​ 缺点:AOF文件添加了RDB格式内容,使得可读性变差,并且开启混合持久化,兼容性也变差,混合持久化文件无法再4.0版本以前使用

10.redis如何实现服务高可用?

​ redis有三种方式保证服务的高可用:主从复制、哨兵模式、集群模式

​ 主从模式

​ 主从复制是将将一台主redis服务器同步数据到多台从redis服务器,即一主多从,主从服务器之间采用【读写分离】方式

​ 哨兵模式

​ redis主从模式存在一个问题,当主服务器出现宕机故障时需要手动进行恢复。为解决这个问题,redis增加了哨兵模式,哨兵可以提供主从服务之间的监控检查,并且可以实现主从节点故障的自动转移

​ 集群模式

​ redis cluster方案采用哈希槽来处理数据和节点之间的映射,一个集群共有16384个哈希槽。每个键值对都会根据它的key被映射到一个哈希槽中。

11.如何避免缓存雪崩、缓存击穿、缓存穿透?

​ 缓存雪崩:大量数据在同一时间过期,如果此时有大量用户请求都无法在redis中处理,于是全部请求都直接访问数据库,从而导致数据库的压力骤增,严重的会造成数据库宕机,从而形成一系列连锁反应,造成整个系统崩溃

​ 对于缓存雪崩问题,可以采用两种方案解决:

	1. 将缓存失效时间打散:设计在原有过期时间上增加一个随机值,这样每个缓存的过期时间都不重复,可有效降低缓存同一时间过期

 		2. 设置缓存不过期:可以通过后台服务来更新缓存数据,从而避免因为缓存失效造成的缓存雪崩

缓存击穿:在秒杀活动等业务场景中会有几个数据被频繁的访问,这类数据称为热点数据,如果缓存中某个热点数据过期,此时大量用户访问该热点数据无法在缓存中读取,而直接去访问数据库,数据库很容易被高并发请求冲垮,这就是缓存击穿

应对缓存击穿可以采取前面说到两种方案:

  1. 互斥锁方案:保证同一时间只有一个业务线程请求缓存,未能获取互斥锁的请求,要么等待锁释放后重新读取缓存,要么就返回空值或者默认值。
  2. 不给热点数据设置过期时间,由后台异步更新缓存,或者在热点数据准备要过期前,提前通知后台线程更新缓存以及重新设置过期时间;

12.使用redis有哪些优势?

1. 速度快,因为数据在内存中,读写速度都很快

2. 支持的数据类型丰富,常用的5种数据类型:string、list、set、zset、hash。
3. 支持事务,操作都是原子性,原子性就是对数据的修改要么都执行,要么都不执行。
4. 丰富的特性,可用于缓存、消息队列、按key设置过期、过期自动删除

13.redis常见的性能问题及解决方案?

  1. master最好不要使用内存快照,如果master执行内存快照,可能会导致redis主线程阻塞,当快照比较大时对性能影响非常大。
  2. 如果数据比较重要,某个slave开启AOF备份数据,设置每秒一次写盘
  3. 为了主从复制的速度和连接的稳定性,Master和slave节点最好再同一网段
  4. 尽量避免在压力很大的主库上增加从

14.redis过期键的删除策略?

  1. 定时删除:设置键的过期时间,在键的过期时间到时对键进行删除
  2. 惰性删除:每次请求键时都检查取得的键是否过期,如果过期就删除键并反馈null,如果没有过期就返回键
  3. 定期删除:每隔一段时间对数据库进行一次检查,删除里面过期的键。

15.redis集群原理是什么?怎么实现Redis的高可用?

  1. redis sentinal 着眼于高可用,在master宕机时自动将slave提升为master,继续提供服务。
  2. redis cluster 着眼于扩展,在单个redis内存不足时,使用cluster进行分片
  3. Redis 实现高可用有三种部署模式:主从模式,哨兵模式,集群模式

16.redis集群方案在什么情况下将导致整个集群不可用?

有A,B,C三个节点的集群,在没有slave的情况下,如果某一个节点宕机,那么整个集群就因为缺少分片而不可用

17.redis如何设置密码及验证密码?

设置密码:config set reruirepass 123456

授权密码:auth 123456

18.简述redis哈希槽的概念?

redis没有使用一致性hash,而是引入了哈希槽的概念,redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置在哪个槽,集群的每个节点负责一部分hash槽

19.redis集群间是如何复制的?

异步复制

20.怎么理解redis事务?

事务是一个单独的隔离操作:事务中所有的命令都是序列化、按顺序地执行。事务在执行的过程中不会被其他客户端发送过来的命令请求打断。事务是一个原子操作:事务中的命令要么全部执行,要么全部都不执行。

21.Redis 集群脑裂产生数据丢失的现象是怎样的呢?

由于网络问题,集群节点之间失去联系,主从数据不同步;重新平衡选举,产生两个主服务。等网络恢复后旧主节点会降级为从节点,在与新主节点同步复制的时候,由于会从节点清空自己的缓冲区,所以导致之前客户端写入的数据丢失

22.如何防止redis集群脑裂造成数据丢失?

当主节点发现从节点下线或者通信超时的总数量小于阈值时,那么禁止主节点进行写数据,直接把错误返回给客户端。

在 Redis 的配置文件中有两个参数我们可以设置:

  • min-slaves-to-write x,主节点必须要有至少 x 个从节点连接,如果小于这个数,主节点会禁止写数据。
  • min-slaves-max-lag x,主从数据复制和同步的延迟不能超过 x 秒,如果超过,主节点会禁止写数据。

配置项组合后的要求是,主库连接的从库中至少有 N 个从库,和主库进行数据复制时的 ACK 消息延迟不能超过 T 秒,否则,主库就不会再接收客户端的写请求了。

23.MySQL 里有 2000w 数据,Redis 中只存 20w 的数据,如何保证 Redis 中的数据都是热点数据?

redis的内存数据集大小到一定程度后就会启动数据淘汰策略

24.redis的内存淘汰策略有哪些?

  • volatile-random:随机淘汰设置了过期时间的任意键值;
  • volatile-ttl:优先淘汰更早过期的键值。
  • volatile-lru(Redis3.0 之前,默认的内存淘汰策略):淘汰所有设置了过期时间的键值中,最久未使用的键值;
  • volatile-lfu(Redis 4.0 后新增的内存淘汰策略):淘汰所有设置了过期时间的键值中,最少使用的键值;

在所有数据范围内进行淘汰:

  • allkeys-random:随机淘汰任意键值;
  • allkeys-lru:淘汰整个键值中最久未使用的键值;
  • allkeys-lfu(Redis 4.0 后新增的内存淘汰策略):淘汰整个键值中最少使用的键值。

25.说说Redis的常用应用场景

  • 缓存 (热点数据)
  • 排行榜(电商月销榜、打赏排行榜、投票排行榜)
  • 计数器应用(视频播放量、浏览量)
  • 共享Session
  • 分布式锁 (秒杀、下单减库存)
  • 社交网络(赞/踩、粉丝、共同好友/喜好、推送、下拉刷新等)
  • 消息队列
  • 位操作

26.如何保证缓存和数据库数据一致性?

  • 缓存延时双删
  • 删除缓存重试机制
  • 读取binlog异步删除缓存

27.redis的内存优化策略?

为了优化内存使用,推荐使用哈希表作为数据结构。哈希表可以有效地减少内存占用,此外,合理设计数据结构和键值对也能减少内存的使用。

28.查看redis使用情况及状态信息的命令

INFO命令可以提供关于Redis服务器的各种统计信息和服务器状态。

posted on 2024-10-24 09:56  杨小杨~  阅读(6)  评论(0编辑  收藏  举报

导航