自学内容网 自学内容网

Redis面试笔记

1.什么是Redis

简单来说 redis 就是一个数据库,不过与传统数据库不同的是 redis 的数据是存在内存中的,所以读写速度非常快,因此 redis 被广泛应用于缓存方向。另外,redis 也经常用来做分布式锁。redis 提供了多种数据类型来支持不同的业务场景。除此之外,redis 支持事务 、数据持久化、LUA脚本、LRU驱动事件、多种集群方案。

2.redis 和 memcached 的区别

对比点redismemcached
存储方式不同数据不仅可以存放在内存中,通过持久化可以存放到硬盘中数据存在内存中,断点消失,数据不能超过内存大小
数据类型不同复杂的数据类型 字符串,哈希,列表。集合,有序集合等数据类型支持相对简单 文本 二进制
底层模型不同构建了 vm 机制 1gb只有 1mb

3.Redis 的数据过期淘汰策略

Redis 中数据过期策略采用定期删除+惰性删除策略

定期删除策略 Redis 启用一个定时器定时监视所有的 key,判断key是否过期,过期的话就删除。这种策略可以保证过期的 key 最终都会被删除,但是也存在严重的缺点:每次都遍历内存中所有的数据,非常消耗 CPU 资源,并且当 key 已过期,但是定时器还处于未唤起状态,这段时间内 key 仍然可以用

惰性删除策略 在获取 key 时,先判断 key 是否过期,如果过期则删除。这种方式存在一个缺点:如果这个 key 一直未被使用,那么它一直在内存中,其实它已经过期了,会浪费大量的空间。

定期删除+惰性删除策略 这两种策略天然的互补,结合起来之后,定时删除策略就发生了一些改变,不在是每次扫描全部的 key 了,而是随机抽取一部分 key 进行检查,这样就降低了对 CPU 资源的损耗,惰性删除策略互补了为检查到的key,基本上满足了所有要求。但是有时候就是那么的巧,既没有被定时器抽取到,又没有被使用,这些数据又如何从内存中消失?没关系,还有内存淘汰机制,当内存不够用时,内存淘汰机制就会上场

Redis 内存淘汰机制有以下几种策略:

  • noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。(Redis 默认策略)

  • allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 Key。(推荐使用)

  • allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 Key。

  • volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 Key。这种情况一般是把 Redis 既当缓存,又做持久化存储的时候才用。

  • volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 Key。

  • volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 Key 优先移除。

    修改内存淘汰机制只需要在 redis.conf 配置文件中配置 maxmemory-policy 参数即可。

4.Redis 都有哪些应用场景

  • 缓存:这应该是 Redis 最主要的功能了,也是大型网站必备机制,合理地使用缓存不仅可以加 快数据的访问速度,而且能够有效地降低后端数据源的压力。

  • 共享Session:对于一些依赖 session 功能的服务来说,如果需要从单机变成集群的话,可以选择 redis 来统一管理 session。

  • 消息队列系统:消息队列系统可以说是一个大型网站的必备基础组件,因为其具有业务 解耦、非实时业务削峰等特性。Redis提供了发布订阅功能和阻塞队列的功 能,虽然和专业的消息队列比还不够足够强大,但是对于一般的消息队列功 能基本可以满足。比如在分布式爬虫系统中,使用 redis 来统一管理 url队列。

  • 分布式锁:在分布式服务中。可以利用Redis的setnx功能来编写分布式的锁,虽然这个可能不是太常用。 当然还有诸如排行榜、点赞功能都可以使用 Redis 来实现,但是 Redis 也不是什么都可以做,比如数据量特别大时,不适合 Redis,我们知道 Redis 是基于内存的,虽然内存很便宜,但是如果你每天的数据量特别大,比如几亿条的用户行为日志数据,用 Redis 来存储的话,成本相当的高。

5.为什么要做Redis分区

redis分区就是将数据分布到不同的redis实例中,因此对于每个redis实例所存储的内容仅仅是所有内容的一个子集

分区可以让Redis管理更大的内存,Redis将可以使用所有机器的内存。如果没有分区,你最多只能使用一台机器的内存。

分区使Redis的计算能力通过简单地增加计算机得到成倍提升,Redis的网络带宽也会随着计算机和网卡的增加而成倍增长。

6.什么是缓存雪崩?怎么解决?

由于缓存层承载着大量请求,有效地 保护了存储层,但是如果缓存层由于某些原因不能提供服务,当大量缓存key失效时,大量的请求访问直接请求数据库,导致数据库服务器无法抗住请求或挂掉的情况,在这些情况下,所有的请求都会直接请求到数据库,可能会造成数据库宕机的情况。

预防缓存雪崩时,建议遵守以下几个原则

  • 缓存时间不一致 合理规划缓存的失效时间,可以给缓存时间加一个随机数,防止统一时间过期;

  • 数据库压力评估 合理评估数据库的负载压力,这有利于在合理范围内部分缓存失,数据库也可以正常访问;

  • 限流降级策略 对数据库进行过载保护或应用层限流,这种情况下一般是在网站处于大流量、高并发时,服务器整体不能承受时,可以采用的一种限流保护措施;

  • Redis 高可用架构 最后还可以考虑多级缓存设计,实现缓存的高可用。

7.什么是缓存穿透?怎么解决?

缓存穿透是指查询一个根本不存在的数据,缓存中和数据库中都不存在,这样的数据不在缓存中,会导致请求全部落到数据库上,有可能出现数据库宕机的情况。

造成这种情况的原因有 系统设计不合理、缓存数据更新不及时,或爬虫等恶意攻击

预防和解决缓存穿透问题,可以考虑以下两种方法

  • 缓存空对象: 将空值缓存起来,但是这样就有一个问题,大量无效的空值将占用空间,非常浪费。空值的过期时间的把控,避免数据库中有数据后出现数据不一致

  • 布隆过滤器拦截: 将所有可能的查询key 先映射到布隆过滤器中,查询时先判断key是否存在布隆过滤器中,存在才继续向下执行,如果不存在,则直接返回。布隆过滤器有一定的误判,所以需要你的业务允许一定的容错性。

8.缓存击穿

缓存击穿是指当缓存中某个热点数据过期了,在该热点数据重新载入缓存之前,有大量的查询请求穿过缓存,直接查询数据库。这种情况会导致数据库压力瞬间骤增,造成大量请求阻塞,甚至直接挂掉。

缓存击穿解决方案

  • 设置key永不过期 在设置热点key的时候,不给key设置过期时间即可。不过还有另外一种方式也可以达到key不过期的目的,就是正常给key设置过期时间,不过在后台同时启一个定时任务去定时地更新这个缓存。

  • 使用分布式锁 保证同一时刻只能有一个查询请求重新加载热点数据到缓存中,这样,其他的线程只需等待该线程运行完毕,即可重新从Redis中获取数据。锁的对象就是key,这样,当大量查询同一个key的请求并发进来时,只能有一个请求获取到锁,然后获取到锁的线程查询数据库,然后将结果放入到缓存中,然后释放锁,此时,其他处于锁等待的请求即可继续执行,由于此时缓存中已经有了数据,所以直接从缓存中获取到数据返回,并不会查询数据库。

9.Redis 分布式锁

分布式锁是控制分布式系统之间同步访问共享资源的一种方式。在单机或者单进程环境下,多线程并发的情况下,使用锁来保证一个代码块在同一时间内只能由一个线程执行

分布式锁的作用是当多个进程不在同一个系统中,用分布式锁可以控制多个进程对资源的访问。

分布式锁实现方式

  • 可以使用 Memcached 实现分布式锁:Memcached 提供了原子性操作命令 add,线程获取到锁。key 已存在的情况下,则 add 失败,获取锁也失败

  • 使用 Redis 实现分布式锁:Redis 的 setnx 命令为原子性操作命令。只有在 key 不存在的情况下,才能 set 成功。和 Memcached 的 add 方法比较类似

  • 使用 ZooKeeper 分布式锁:利用 ZooKeeper 的顺序临时节点,来实现分布式锁和等待队列

  • Chubby 实现分布式锁:Chubby 底层利用了 Paxos 一致性算法,实现粗粒度分布式锁服务。

分布式锁实现需要注意的事项

  • 互斥性:任意时刻,只有一个资源能够获取到锁

  • 容灾性:在未成功释放锁的的情况下,一定时限内能够恢复锁的正常功能;

  • 统一性:加锁和解锁保证同一资源来进行操作。

10.Redis 如何做内存优化

尽量使用 Redis 的散列表,把相关的信息放到散列表里面存储,而不是把每个字段单独存储,这样可以有效的减少内存使用。比如将 Web 系统的用户对象,应该放到散列表里面再整体存储到 Redis,而不是把用户的姓名、年龄、密码、邮箱等字段分别设置 key 进行存储。

11.请问Redis的数据类型有哪些,底层怎么实现

  • 字符串:整数值、embstr编码的简单动态字符串、简单动态字符串(SDS)

  • 列表:压缩列表、双端链表

  • 哈希:压缩列表、字典

  • 集合:整数集合、字典

  • 有序集合:压缩列表、跳跃表和字典

12.redis消息队列先进先出需要注意什

通常使用一个list来实现队列操作,这样有一个小限制,所以的任务统一都是先进先出,如果想优先处理某个任务就不太好处理了,这就需要让队列有优先级的概念,我们就可以优先处理高级别的任务,实现方式有以下几种方式:

  • 单一列表实现:队列正常的操作是 左进右出(lpush,rpop)为了先处理高优先级任务,在遇到高级别任务时,可以直接插队,直接放入队列头部(rpush),这样,从队列头部(右侧)获取任务时,取到的就是高优先级的任务(rpop)

  • 使用两个队列,一个普通队列,一个高级队列,针对任务的级别放入不同的队列,获取任务时也很简单,redis的BRPOP命令可以按顺序从多个队列中取值,BRPOP会按照给出的 key 顺序查看,并在找到的第一个非空 list 的尾部弹出一个元素,redis> BRPOP list1 list2 0

list1 做为高优先级任务队列, list2 做为普通任务队列

这样就实现了先处理高优先级任务,当没有高优先级任务时,就去获取普通任务

方式1最简单,但实际应用比较局限

方式2是推荐用法,实际应用最为合适

13.单线程的 Redis 为什么这么快

Redis 有多快?官方给出的答案是读写速度 10万/秒,如果说这是在单线程情况下跑出来的成绩,你会不会惊讶?为什么单线程的 Redis 速度这么快?原因有以下几点:

  • 纯内存操作:Redis 是完全基于内存的,所以读写效率非常的高,当然 Redis 存在持久化操作,在持久化操作是都是 fork 子进程和利用 Linux 系统的页缓存技术来完成,并不会影响 Redis 的性能。

  • 单线程操作:单线程并不是坏事,单线程可以避免频繁的上下文切换,频繁的上下文切换也会影响性能的。

  • 合理高效的数据结构 采用了非阻塞 I/O 多路复用机制:多路I/O复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。

14.为什么Redis需要把所有数据放到内存中

Redis为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以redis具有快速和数据持久化的特征。如果不将数据放在内存中,磁盘I/O速度为严重影响redis的性能

15.怎么理解Redis事务

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

16.如何保证缓存与数据库双写时的数据一致性

当一个数据需要更新时,因为不可能做到同时更新数据库和缓存,那么此时读取数据的时候就一定会发生数据不一致问题,而数据不一致问题在金融交易领域的系统中是肯定不允许的。

解决办法:读的时候先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。更新的时候,先更新数据库,然后再删除缓存。

  • 先删除缓存再更新数据库 进行更新操作时 先删除缓存,然后更新数据库,后续的请求再次读取时,会从数据库读取后再将新数 据更新到缓存。 存在的问题:删除缓存数据之后,更新数据库完成之前,这个时间段内如果有新的读请求过来,就会从 数据库读取旧数据重新写到缓存中,再次造成不一致,并且后续读的都是旧数据

  • 先更新数据库再删除缓存 进行更新操作时,先更新MySQL,成功之后,删除缓存,后续读取请求时再将新数据回写缓存。 存在的问题:更新MySQL和删除缓存这段时间内,请求读取的还是缓存的旧数据,不过等数据库更新完 成,就会恢复一致,影响相对比较小

  • 异步更新缓存 数据库的更新操作完成后不直接操作缓存,而是把这个操作命令封装成消息扔到消息队列中,然后由 Redis自己去消费更新数据,消息队列可以保证数据操作顺序一致性,确保缓存系统的数据正常

17.Redis 持久化有几种方式

Redis 的持久化有两种方式,或者说有两种策略:

  • RDB(Redis Database):指定的时间间隔能对你的数据进行快照存储。默认,快照是一种点对点的数据备份方式,可以通过配置自动定时进行快照生成,或手动执行SAVE或BGSAVE命令生成快照。

  • AOF(Append Only File):每一个收到的写命令都通过write函数追加到文件中。需要设置开启,AOF文件记录了Redis服务器接收到的所有写操作,包括写操作的参数和结果,不包含读操作

18.Redis 常见的性能问题有哪些?该如何解决

  • Master 最好不要做任何持久化工作,如RDB 内存快照和 AOF 日志文件;

  • 如果数据比较重要,某个 Slave 开启 AOF 备份数据,策略设置为每秒同步一次;

  • 为了主从复制的速度和连接的稳定性,Master 和 Slave 最好在同一个局域网内;

  • 尽量避免在压力很大的主库上增加从库;

  • 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3….;这样的结构方便解决单点故障问题,实现 Slave 对 Master 的替换。如果 Master 挂了,可以立刻启用 Slave1 做 Master,其他不变。

19.为什么Redis的操作是原子性的,怎么保证原子性的

对于Redis而言,命令的原子性指的是:一个操作的不可以再分,操作要么执行,要么不执行。 Redis的操作之所以是原子性的,是因为Redis是单线程的。 Redis本身提供的所有API都是原子操作,Redis中的事务其实是要保证批量操作的原子性。 多个命令在并发中也是原子性的吗? 不一定, 将get和set改成单命令操作,incr 。使用Redis的事务,或者使用Redis+Lua==的方式实现.

20.Redis的性能调优技巧有哪些

  • 使用合适的数据结构:选择适当的数据结构来存储和操作数据,以提高读写性能。

  • 使用批量操作和管道技术:通过批量操作和管道技术可以减少网络开销和降低延迟,提高性能。

  • 设置合理的最大内存限制:根据系统的实际内存情况,设置合理的最大内存限制,避免过度使用内存导致性能问题。

  • 合理配置持久化策略:根据实际需求选择适当的持久化方式,并设置合理的持久化频率,平衡数据持久化和性能之间的关系。

  • 合理使用缓存过期时间:根据业务需求和数据特性,设置合理的缓存过期时间,避免缓存数据过期或占用过多的内存。

  • 避免过度使用阻塞操作:尽量避免使用阻塞操作,如阻塞的命令和阻塞的事件通知,以充分利用Redis的异步特性和高并发能力。

21.如何保证Redis的高可用性?

  • 主从复制:通过配置Redis主从复制,当主节点故障时,可以自动切换到从节点作为新的主节点,提高系统的可用性。

  • 哨兵模式:使用Redis的哨兵模式可以监控主节点的状态,并在主节点故障时自动进行故障转移,选举新的主节点。

  • Redis Cluster集群:通过Redis Cluster可以将数据分布在多个节点上,并在节点故障时进行自动重新分片和故障转移,保证系统的高可用性和扩展性。

22.Redis的数据一致性如何保证

  • 主从复制:当Redis的主节点更新数据时,会将更新操作传播给从节点,从节点通过复制主节点的数据来保持一致性。

  • 哨兵模式:Redis的哨兵模式用于监控主节点的状态,并在主节点故障时自动将一个从节点升级为新的主节点,以保持数据的可用性和一致性。

  • Redis Cluster集群:Redis Cluster是一种分布式解决方案,通过数据分片和复制来实现数据的分布式存储和高可用性

23.Redis与传统数据库的区别是什么

  • 存储方式:Redis将数据存储在内存中,而传统数据库通常将数据存储在磁盘上。

  • 数据模型:Redis是键值存储数据库,而传统数据库使用表格和行的结构来存储数据。

  • 查询语言:传统数据库使用SQL查询语言进行数据查询,而Redis使用自身的命令和数据结构来操作数据。

  • 数据持久化:传统数据库通常使用日志和事务来保证数据的持久化和一致性,而Redis可以选择将数据持久化到硬盘上。

  • 性能和延迟:由于数据存储在内存中,Redis具有更高的读写性能和低延迟,适合处理高并发的场景

24.Redis常见的应用场景包括

  • 缓存:作为缓存存储系统,Redis可以将热门数据存储在内存中,加快数据访问速度,减轻后端数据库的负载。

  • 会话存储:Redis可以用作会话存储,存储用户会话信息,并支持分布式会话管理。

  • 消息队列:Redis的发布/订阅功能和列表数据结构可以实现简单的消息队列,用于异步通信和解耦应用组件。

  • 计数器和排行榜:Redis的原子操作和有序集合可以用于实现计数器和排行榜功能。

  • 实时数据分析:Redis的高性能和丰富的数据结构使其适用于实时数据分析和计算。

  • 地理空间索引:Redis支持地理位置数据和相关的空间查询,可用于构建地理位置服务

25.Redis的主要特点是什么

  • 内存存储:Redis将数据存储在内存中,使得数据访问速度极快。

  • 数据结构丰富:Redis支持多种数据结构,如字符串、哈希表、列表、集合和有序集合,使得应用可以灵活地处理不同类型的数据。

  • 持久化支持:Redis支持将内存中的数据持久化到硬盘上,以便在重启后恢复数据。

  • 高性能:Redis具有快速的读写性能和低延迟,适合处理高并发的场景

  • 分布式支持:Redis可以通过主从复制和分片等机制实现数据的分布式存储和高可用性

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

淘汰策略 + redis的内存限制来实现

因为内存的空间是有限的,所以 Redis 淘汰机制主要为了解决在某个时间点,Redis 中存在很多过期键,定期删除策略随机抽查时没有抽查到,并且也没有走惰性删除策略时,大量过期键占用内存的问题。如果内存只能存 20w 数据,而我们需要存储 2000w 的数据时,自然就需要对多出来的数据进行删除或覆盖,保证内存中存储的数据都是热数据。所以当 Redis 内存数据集的大小上升到一定数量时,就会执行数据淘汰策略

Redis 内存淘汰机制有以下几种策略:

  • noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。(Redis 默认策略)

  • allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 Key。(推荐使用

  • allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 Key。

  • volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 Key。这种情况一般是把 Redis 既当缓存,又做持久化存储的时候才用。

  • volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 Key。

  • volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 Key 优先移除。

    修改内存淘汰机制只需要在 redis.conf 配置文件中配置 maxmemory-policy 参数即可。

27.假如 Redis 里面有 1 亿个 key,其中有 10w 个 key 是以某个固定的已知的前缀开头的,如果将它们全部找出来?

使用 keys 命令和 scan 命令,但是会发现使用 scan 更好

  • keys命令 阻塞无分页,直接使用 keys 命令查询,但是如果是在生产环境下使用会出现一个问题,keys 命令是遍历查询的,查询的时间复杂度为 O(n),数据量越大查询时间越长。而且 Redis 是单线程,keys 指令会导致线程阻塞一段时间,会导致线上 Redis 停顿一段时间,直到 keys 执行完毕才能恢复。这在生产环境是不允许的。除此之外,需要注意的是,这个命令没有分页功能,会一次性查询出所有符合条件的 key 值,会发现查询结果非常大,输出的信息非常多。所以不推荐使用这个命令。

  • scan 命令 可以实现和 keys 一样的匹配功能,但是 scan 命令在执行的过程不会阻塞线程,并且查找的数据可能存在重复,需要客户端操作去重。因为 scan 是通过游标方式查询的,所以不会导致 Redis 出现假死的问题。Redis 查询过程中会把游标返回给客户端,单次返回空值且游标不为 0,则说明遍历还没结束,客户端继续遍历查询。scan 在检索的过程中,被删除的元素是不会被查询出来的,但是如果在迭代过程中有元素被修改,scan 不能保证查询出对应元素。相对来说,scan 指令查找花费的时间会比 keys 指令长。

28.如果有大量的 key 需要设置同一时间过期,一般需要注意什么?

轻则卡顿 重则崩溃

如果有大量的 key 在同一时间过期,那么可能同一秒都从数据库获取数据,给数据库造成很大的压力,导致数据库崩溃,系统出现 502 问题。也有可能同时失效,那一刻不用都访问数据库,压力不够大的话,那么 Redis 会出现短暂的卡顿问题。

所以为了预防这种问题的发生,最好给数据的过期时间加一个随机值,让过期时间更加分散。

29.Redis 哨兵和集群的区别是什么

哨兵的数据存储是每个实例一份,集群的数据存储是分布式存放,每个实例只存放分配到的数据

Redis 的哨兵作用是管理多个 Redis 服务器,提供了监控、提醒以及自动的故障转移的功能。哨兵可以保证当主服务器挂了后,可以从从服务器选择一台当主服务器,把别的从服务器转移到读新的主机。Redis 哨兵的主要功能有:

  • 集群监控:对 Redis 集群的主从进程进行监控,判断是否正常工作

  • 消息通知:如果存在 Redis 实例有故障,那么哨兵可以发送报警消息通知管理员。

  • 故障转移:如果主机(master)节点挂了,那么可以自动转移到从(slave)节点上。

  • 配置中心:当存在故障时,对故障进行转移后,配置中心会通知客户端新的主机(master)地址。

Redis 的集群的功能是为了解决单机 Redis 容量有限的问题,将数据按一定的规则分配到多台机器,对内存的每秒访问不受限于单台服务器,可受益于分布式集群高扩展性

30.Redis 的哨兵有什么功能

  • 集群监控:对 Redis 集群的主从进程进行监控,判断是否正常工作

  • 消息通知:如果存在 Redis 实例有故障,那么哨兵可以发送报警消息通知管理员。

  • 故障转移:如果主机(master)节点挂了,那么可以自动转移到从(slave)节点上。

  • 配置中心:当存在故障时,对故障进行转移后,配置中心会通知客户端新的主机(master)地址。

31.请介绍几个可能导致 Redis 阻塞的原因

内部原因

  • 如果 Redis 主机的 CPU 负载过高,也会导致系统崩溃;

  • 数据持久化占用资源过多;

  • 对 Redis 的 API 或指令使用不合理,导致 Redis 出现阻塞问题。比如说keys命令

外部原因

外部原因主要是服务器的原因,例如服务器的 CPU 线程在切换过程中竞争过大,内存出现问题、网络问题,服务器宕机等。

32.Redis 的同步机制了解么

Redis 可以使用主从同步、从从同步。异步复制,第一次同步时,主节点做一次 bgsave,并同时将后续修改操作记录到内存 buffer,待完成后将 RDB 文件全量同步到复制节点,复制节点接受完成后将 RDB 镜像加载到内存。 加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。

33.如何处理 Redis 集群中 big key 和 hot key?

对于 big key 先分析业务存在大键值是否合理,如果不合理我们可以把它们拆分为多个小的存储。或者看是否可以使用别的存储介质存储这种 big key 解决占用内存空间大的问题。

对于 hot key 我们可以在其他机器上复制这个 key 的备份,让请求进来的时候,去随机的到各台机器上访问缓存。所以剩下的问题就是如何做到让请求平均的分布到各台机器上。

34.怎么去发现 Redis 阻塞异常情况

使用 Redis 自身监控系统 使用 Redis 自身监控系统,可以对 CPU、内存、磁盘、命令耗时等阻塞问题进行监控,当监控系统发现各个监控指标存在异常的时候,发送报警

  • 慢日志 slowlog get

  • 客户端通过执行MONITOR、info memory info stats

  • 监控延迟 - latency

使用应用服务监控 当 Redis 存在阻塞时,应用响应时间就会延长,应用可以感知发现问题,并发送报警给管理人员。

  • Grafana 是一个开箱即用的可视化工具,具有功能齐全的度量仪表盘和图形编辑器,有灵活丰富的图形化选项,可以混合多种风格,支持多个数据源特点。

  • Prometheus是一个开源的服务监控系统,它通过HTTP协议从远程的机器收集数据并存储在本地的时序数据库上

  • redis_exporter为Prometheus提供了redis指标的导出,配合Prometheus以及grafana进行可视化及监控

35.你知道有哪些 Redis 分区实现方案

  • 客户端分区方案:优点是分区逻辑可控,缺点是需要自己处理数据路由、高可用、故障转移等问题,比如在redis2.8之前通常的做法是获取某个key的hashcode,然后取余分布到不同节点,不过这种做法无法很好的支持动态伸缩性需求,一旦节点的增或者删操作,都会导致key无法在redis中命中

  • 代理方案:优点是简化客户端分布式逻辑和升级维护便利,缺点是加重架构部署复杂度和性能损耗,比如twemproxy、Codis等第三方

  • 官方专有的集群方案:Redis Cluster,它非常优雅地解决了 Redis 集群方面的问题,部署方便简单,因此理解应用好 Redis Cluster 将极大地解放我们使用分布式 Redis 的工作量,实现了一种混合形式的查询路由,但并不是直接将请求从一个 Redis 节点转发到另一个 Redis 节点,而是在客户端的帮助下直接 redirected 到正确的 Redis 节点

36.Redis 集群之间的复制方式是

需要知道 Redis 的复制方式前,需要知道主从复制(Master-Slave Replication)的工作原理,具体为:

  • Slave 从节点服务启动并连接到 Master 之后,它将主动发送一个 SYNC 命令;

  • Master 服务主节点收到同步命令后将启动后台存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕后,Master 将传送整个数据库文件到 Slave,以完成一次完全同步;

  • Slave 从节点服务在接收到数据库文件数据之后将其存盘并加载到内存中;

  • 此后,Master 主节点继续将所有已经收集到的修改命令,和新的修改命令依次传送给 Slaves,Slave 将在本次执行这些数据修改命令,从而达到最终的数据同步。

    整个执行的过程都是使用异步复制的方式进行复制。

37.分布式 Redis 是前期做还是后期规模上来了再做好,为什么?

为防止以后扩容增加难度,最好的办法就是一开始就使用分布式。即便只有一台服务器,也可以一开始就让 Redis 以分布式的方式运行,使用分区,在同一台服务器上启动多个实例。

刚开始操作时比较麻烦,但是当数据不断增长,需要更多的 Redis 服务器时,只需要将 Redis 实例从一台服务迁移到另外一台服务器即可,而不用考虑重新分区的问题。一旦添加了另一台服务器,只需要将一半的 Redis 实例从第一台机器迁移到第二台机器。


原文地址:https://blog.csdn.net/ddf128/article/details/142499310

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!