redis八股文

redis为什么快?

1.纯内存访问
2.单线程避免上下文切换
3.渐进式ReHash, 缓存时间戳
在这里插入图片描述

全局哈希表,
数组扩容的时候, 元素移动的过程就叫做rehash
在这里插入图片描述
在这里插入图片描述

把一次大量拷贝的开销, 分摊到多次处理请求的过程中, 避免了耗时操作,
保证了数据的快速访问。


redis合适的应用场景

redis常用数据类型:string, list,set,zset, hash
bitmap可以用于布隆过滤器。
1.缓存
2.计数器
3.分布式会话
4.排行榜
5.最新列表
6.分布式锁
7.消息队列


redis 6.0版本之前为什么一直不使用多线程?

1.使用redis过程中, cpu不是瓶颈, 受制于内存还有网络。
2.提高redis性能, Pipeline, 命令批量处理。每秒100万个请求。
3.单线程, 内部维护成本比较低。
4.如果多线程, 涉及到线程切换、加锁解锁,导致死锁问题。
5.惰性rehash,(渐进式Rehash)


redis6.0之后为啥引入多线程?

1.单线程就够了小数据量包, 数据-> 内存, 响应时间100纳秒
比较小数据包 8W-10W QPS, 这个是极限值。
2.大公司需要更大的qps, 解决方案就是多线程, io的多线程。
(内部执行命令还是单线程),
3.为啥不采用分布式架构?
很大的缺点:服务器数量多, 维护成本高,
2.redis里面有很多命令, 不适用于数据分区。
3.数据分区无法解决热点读和热点写问题。
4.分布式架构会有数据倾斜, 重新分配,扩容或者缩容, 更加复杂。
多线程任务分摊到redis的同步IO中进行读写的负载。


redis有哪些高级功能?

string, hash, set , zset, list
1.redis的慢查询会记录下来,
2.redis的pipeline功能, 管道的功能,
在这里插入图片描述

3.watch命令, 观察变量有没有被修改。
4.redis+lua脚本实现限流,
5.redis持久化 ,
rdb:
aof:


redis的高可用

主从复制:哨兵模式确保主故障后, 从节点选举, 从而达到高可用。

为什么要使用redis?

在这里插入图片描述

1.高性能

2.高并发

redis和memcached相对有哪些优势?
redis:
类型 支持内存, 非关系型数据库
支持string, list, set, zset, hash
支持事务(弱事务, 结合lua脚本实现比较完整的方案)
附加功能; 发布-订阅, 2.主从高可用(哨兵实现故障转移)
3.序列化支持, 4. lua脚本。
网络io模型:执行命令都是单线程, 网络操作上支持多线程
持久化支持:支持rdb 2.aof

memcached:
支持内存, key-value
支持文本, 二进制类型2种,
多线程服务支持。
网络io模型:多线程, 非阻塞io模式。
持久化支持:不支持


怎么理解redis中事务

redis提供了简单的事务功能, 将一组需要一起执行的命令放到multi和exec之间
multi命令代表事务开始, exec代表事务结束, discard表示事务回滚。
在这里插入图片描述


redis过期策略以及内存淘汰机制

redis所有数据结构都可以设置过期时间, 时间已到, 就会自动删除,
1.定期删除策略:
在这里插入图片描述
随机设置一个过期范围, 不能全部在同一时间过期。
在这里插入图片描述

2.惰性删除:
在这里插入图片描述

缓存淘汰算法:
在这里插入图片描述


缓存穿透如何避免?

在这里插入图片描述

可以使用布隆过滤器, bitmap,
一种概率的判断算法, 判断一个元素是否在一个集合中,
由bitmap数组和hash算法来实现。
误判问题:
通过hash计算在数组上不一定在集合上
本质是hash冲突
通过hash计算不在数组的一定不在集合

优化方案:
增大数组
增加hash函数。
在这里插入图片描述

使用布隆过滤器解决缓存穿透问题。


什么是缓存雪崩?如何避免?

1.redis故障, -引入集群解决
2.redis中大量key ttl 过期, --尽量把ttl岔开, 随机ttl值
3.加入限流机制
4.加多级缓存。


如何设计分布式锁?

可以使用SETNX 命令, 表示set if not exist
在这里插入图片描述

死锁问题避免方法就是在给这把锁一个失效时间。
分布式锁加入看门狗线程。
在这里插入图片描述

实现锁的续期。


redis怎么实现消息队列?

在这里插入图片描述
在这里插入图片描述

基于stream实现队列:


什么是bigKey?会有什么影响?

在这里插入图片描述

bigkey就是key对应的value占用内存空间比较大, 例如一个字符串类型的value
可以最大存到512MB,
一个列表类型value最多可以存储23-1个元素。

一般认为超过10KB就是bigKey.

bigKey危害:

redis如何解决key冲突问题?

在这里插入图片描述


怎么提高缓存命中率?

1.数据提前加载
2.增加缓存的存储空间, 提高缓存数据。
3.调整缓存的存储类型,
4.提升缓存更新频次


redis持久化有哪些方法?有什么区别?

RDB:
是Redis database 缩写,
将瞬间形象记录下来,
数据越大, 可能会造成阻塞,
在这里插入图片描述
在这里插入图片描述

AOF: 写入命令就会有持久化, 命令追加文件

混合方式:高并发场景使用。


为什么需要将所有数据放到内存?

在这里插入图片描述

因为速度要求,
内存淘汰机制, 确保不会oom


如何保证缓存与数据库双写一致性?

更新类:
先更新数据库或者db都是不好的
3.先删除缓存, 再更新数据库。
在这里插入图片描述
在这里插入图片描述

延时双删

4.先更新db, 再更新缓存。


redis集群方案?

redis cluster是redis分布式解决方案。
可以使用cluster达到负载均衡目的。

一般来说redis集群不会出现1000个节点以上。
在这里插入图片描述
在这里插入图片描述
集群中至少包含奇数个节点,
分槽的概念。

redis集群方案什么情况会导致整个集群不可用?


redis是什么?

是一个分布式缓存中间件, 基于内存实现的key-value的no-sql数据库。
所有数据都放到内存里面,

提供了5种数据类型
string list set hash zset map

主从复制+哨兵
redis cluster-集群实现高可用。


redis的哨兵机制和集群有什么区别

主从集群
在这里插入图片描述

redis主从集群可以实现读写分离。但是不提供容错和恢复的功能。
一旦master节点挂了, 不会选举出新的master.
导致后续的客户端写请求直接失败。
redis提供了哨兵机制, 提供主从集群模式自动恢复能力。
哨兵会监控状态, 自动选举出master
在线扩容问题没有解决

redis-cluster模式
在这里插入图片描述

redis-cluster里面实现了slot槽来实现分片模式, redis会根据key
去计算slot值,
引入了主从复制模式,
虽然解决了在线扩容提升读写性能
在这里插入图片描述

redis-cluster是多主多从的结构


redis是线程安全的么?

是单线程的,
6.0以后虽然是多线程, 但是是网络的
cpu不是瓶颈点。
加锁会带来性能上影响。


redis的aof重写过程?

是数据持久化的方式,
将每个指令增加到aof文件中,
将aof文件中相同指令进行压缩, 减少占用空间。
1.根据内存数据, 构建aof文件
重写的过程放到后台的子进程去完成。

redis内存淘汰算法和
当内存使用率达到上限的时候的一种行为。
1.random算法, 随机移出
2.ttl算法
3.lru算法
4.lfu算法,


redis主从复制的原理

值得是master和slave之间实现数据同步的一种机制。
全量复制和增量复制。
在这里插入图片描述

全量复制:
增量复制是master收到数据变更的时候, 会将变动传给slave
有一个offset, 根据偏移量来读取。


redis热key问题怎么解决?

1. 什么是Redis热点Key

Redis热点key指的是访问频率较高的key,当大量的请求集中在一个或少数几个热点key上时,会导致这些key所在的Redis节点的CPU、内存和网络带宽等资源被大量消耗,影响Redis集群的整体性能和稳定性。

2. 热点Key带来的问题

Redis节点负载过高:当某些key被频繁访问时,会导致Redis节点负载过高,从而影响Redis的性能和稳定性。
Redis集群负载不均:当某些key被频繁访问时,会导致所在节点负载过重,而其他节点负载较轻,从而使Redis集群负载不均衡。
Redis集群性能下降:当某些key的访问频率特别高时,会导致Redis节点的CPU、内存、网络等资源负载过重,从而影响Redis的性能,甚至导致Redis宕机。
数据不一致:当某些key成为热点key时,如果数据量较大或者更新频率较快,可能会导致数据不一致的问题,比如缓存中的数据和数据库中的数据不一致,不同节点的数据不一致。
缓存击穿:当某些key的访问频率特别高时,如果这些key的数据过期或被删除,而恰好有大量的请求同时访问这个key,会导致这些请求直接访问后端数据库,从而造成缓存击穿的问题。

3. 热点Key产生的原因

热点Key的产生通常与以下场景有关:
热点数据:某些数据具有较高的访问频率,例如热门商品、热门新闻、热门评论等。
业务高峰期:当处于业务高峰期的时候,某些数据会被频繁访问,例如双11秒杀、整点秒杀等。
代码逻辑问题:程序的代码逻辑导致部分Key被频繁访问,例如程序中的高频轮询或者存在代码死循环。
了解热点Key的概念和产生原因后,我们需要想一下如何检测和解决热点Key问题。

4. 如何检测热点Key
4.1 Redis监控工具

Redis提供了一些监控工具,如 Redis monitor 和 redis-stat,可以用来监控Redis实例的运行状态。通过这些工具,我们可以观察到访问频率较高的Key,以及它们对Redis性能的影响。

Redis monitor: 使用redis-cli的monitor命令,可以实时查看Redis实例的命令执行情况。通过分析输出的日志信息,可以找到访问频率较高的Key。
redis-stat: redis-stat是一个实时监控Redis实例的工具,它可以展示包括命令执行次数、内存使用情况等指标。通过观察这些指标,可以发现热点Key对Redis性能的影响。

4.2 慢查询日志

Redis的慢查询日志记录了执行时间较长的命令,通过分析慢查询日志,可以找到可能存在热点Key的操作。可以使用redis-cli的slowlog命令查看慢查询日志。

通过上述方法,可以检测到热点Key及其对Redis性能的影响。在找到热点Key后,我们需要采取相应的策略来解决热点Key问题。

5. 解决热点Key问题
5.1 数据分片

数据分片是通过将热点数据分散存储在多个Redis节点上,避免单个节点负载过高,是解决热点Key问题最常用的策略。

例如,在Redis Cluster模式下,数据自动按槽位分布在多个节点上,从而实现负载均衡。对于非Cluster模式,可以通过客户端或代理层实现一致性哈希等分片算法,将数据分布在多个Redis实例上。

5.2 读写分离

读写分离可以将读操作与写操作分开处理,降低单个节点的负载。在主从复制模式下,可以将读操作分发到从节点上,从而分担主节点的压力。此外,可以使用代理层如Redis Sentinel或Twemproxy实现自动故障转移和读写分离。

5.3 缓存预热

缓存预热是指在系统启动或重启后,主动将热点数据加载到缓存中。这样,当用户访问这些热点数据时,可以直接从缓存中获取,避免对后端数据库造成压力。缓存预热可以通过定时任务或应用程序启动时加载热点数据实现。

5.4 限流

限流是通过控制请求的速率来防止系统过载。在应用层实现限流,可以有效减轻热点Key对Redis的压力。常见的限流算法有漏桶算法和令牌桶算法。

5.5 熔断降级

熔断降级是在系统出现问题时,自动降低系统功能的一种策略。在应用层实现熔断降级,可以在Redis出现热点Key问题时,快速降低对Redis的访问压力。熔断降级可以通过开源工具如Hystrix实现。

通过上述策略,可以有效解决Redis的热点Key问题。然而,在实际应用中,需要根据具体业务场景和需求选择合适的策略。接下来,我们将通过实践案例来说明如何解决热点Key问题。

redis集群模式分类

####1.redis主从模式:
在这里插入图片描述
一个主机器可以挂载多个从节点机器。
主写, 从读, 如果主机器宕机了, 那么就丧失了写功能, 只能去读。
支持10w的qps.
缺点: 主节点挂机, 从节点没办法升级为主节点, 相当于这个集群已经挂掉了。
特点就是,主从节点的数据是全量数据, 没有拆分的, 数据同步方式是异步的。

2.哨兵模式:

监控主服务器宕机, 那么从服务中选出新的主节点。
哨兵使用rust算法支持从从节点列表中选举出一个主节点。

3.分片集群:

在这里插入图片描述
qps的确很多的时候, 就需要用到分片集群。
每个数据值存储在其中一个机器上。
哈希槽就是存储的一个节点, 每次存储的时候, 会算出一个hash值。
三个哈希槽的话, hash值就分别是1-5000, 5000-10000, 10000-15000
其中每个节点中数据又有主从节点。
相当于不是存储的全量数据, 对于访问量很大的业务场景适用。
redis自身实现的redis-cluster分片集群。


redis持久化机制:rdb和aof:

redis提供了不同级别的持久化的方式:
1.rdb持久化方式能够在指定时间间隔对数据进行快照存储
2.aof持久化记录每次对服务器写的操作, 当服务器重启的时候, 会重新执行这些命令来恢复原始
数据,Aof命令以redis协议追加保存每次写的操作到文件末尾, redis还能对aof文件进行后台重写。
使得aof文件的体积不至于过大。
3.如果只希望数据运行时候存在。可以不使用任何持久化方式。
4.可以同时开启两种持久化方式, 这种情况下, 当redis重启时候, 会优先载入aof文件来恢复原始
数据, 因为在通常情况下aof文件保存的数据集要比rdb数据集完整。

rdb优点:

是一个非常紧凑的文件, 保存了某个时间点的数据集, 非常适用于数据集的备份,
比如每小时保存一下过去24小时内的数据, 同时每天保存过去30天的数据, 这样即便出问题,
也可以根据需求恢复到不同版本的数据库。

rdb是一个紧凑的单一文件, 很方便传送到一个远端数据中心, 适用于容灾恢复。

rdb在保存文件时, 父进程唯一需要做的就是fork出一个子进程, 接下来工作就是由子进程完成。
父进程不需要再做其他IO操作, 所以rdb方式可以最大化redis性能。

与aof相比, 恢复大的数据集的时候, rdb方式会更快一些。

rdb缺点:

如果希望在redis宕机下丢失数据最少, rdb就不太适合, 虽然可以配置不同的save时间点,
例如每隔5分钟并且对数据集有100个写的操作, 是redis要完整的保存整个数据集是一个比较繁重的
工作, 通常会每间隔5分钟或者更久做一次保存, 万一在redis以外宕机, 那么可能丢失几分钟数据。

rdb需要经常fork出子进程来保存数据集到硬盘上, 当数据集比较大的时候fork的过程是非常耗时的。
可能会导致redis在一些毫秒级内不能响应客户端请求, 如果数据量巨大且cpu性能不是很好情况下,
这种情况会持续1秒, aof也需要fork, 但是可以调节重写日志文件频率来提高数据集持久度。

aof优点:

使用aof会让redis更加持久, 可以使用不同的sync策略, 无fsync, 每秒fsync,
每次写的fsync, 使用默认的每秒fsync策略,redis性能依然很好,
fsync是由后台线程进行处理的, 主线程会尽力处理客户端请求, 一旦出现故障,
最多丢失1秒数据。

aof文件是一个值进行追加的日志文件, 所以不需要写入seek, 即使由于某些原因(磁盘空间已满)
机器宕机等, 未执行完整的写入命令, 也可以通过使用redis-check-aof工具修复这些问题。

redis可以在aof文件空间体积变大的情况下自动在后台对aof进行重写,重写后新的
aof文件包含了恢复当前数据集所需的最小命令集,一旦新aof文件创建完毕, redis就会从
aof文件切换到新aof文件, 并开始对aof文件进行追加操作。

相同数据集来说, aof文件体积通常大于rdb文件体积。
根据所使用的fsync策略, aof的速度可能会慢于rdb, 一般情况下, 每秒fsync性能依然很高,
而关闭fsync可以让aof的速度和rdb一样快, 即使在高负载情况下也是如此,
不过在处理巨大的写入载入时, rdb可以更有保证的延迟时间。


redis的超时机制和淘汰机制

Redis是一种内存数据库,它具有超时机制和淘汰机制来管理数据的过期和腾出空间。

超时机制:Redis允许为每个键设置过期时间。当键到达过期时间时,Redis会自动将其删除。这可以通过使用EXPIRE、PEXPIRE等命令来设置键的过期时间。超时机制是通过在内部维护一个定时器来实现的,在键过期时进行删除操作。超时机制使得Redis可以用于缓存等应用场景,确保数据的及时更新。

淘汰机制:当Redis的内存使用达到上限时,需要腾出一些空间来容纳新的数据。Redis提供了多种淘汰策略来决定要删除哪些键:

LRU(Least Recently Used):最近最少使用算法,根据键最近被访问的时间来选择淘汰键。
LFU(Least Frequently Used):最不经常使用算法,根据键被访问的频率来选择淘汰键。
Random:随机选择要淘汰的键。
TTL(Time to Live):基于键的剩余生存时间来选择淘汰键。
这些淘汰策略可以通过配置文件或使用CONFIG SET命令进行设置。默认情况下,Redis使用LRU算法作为淘汰策略,但可以根据需求选择合适的策略。

总结起来,Redis的超时机制允许为键设置过期时间,在到达过期时间后自动删除。而淘汰机制用于管理内存使用,通过选择合适的淘汰策略来删除一些键以腾出空间。这些机制使得Redis能够灵活地管理数据的生命周期和内存使用。


redis分片集群的优缺点分别是什么?

Redis分片集群是将数据分散存储在多个Redis节点上的一种集群部署方式。每个节点负责存储部分数据,从而实现横向扩展和负载均衡。这种分片集群方式有以下优点和缺点:

优点:

  1. 高性能横向扩展:通过增加新的Redis节点,可以线性地提高系统的读写吞吐量,有效地应对高并发访问和大规模数据存储需求。

  2. 负载均衡:分片集群可以将负载分散到多个节点上,避免单个节点成为性能瓶颈,提高系统的稳定性和可用性。

  3. 数据分布:数据被分散存储在多个节点上,减少了单个节点的内存占用,降低了内存压力,使得每个节点都能处理更多的数据。

  4. 高可用性:通过数据的复制和主从切换,可以实现数据的高可用性,即使有节点宕机,也可以从备份节点快速恢复服务。

  5. 灵活性:可以根据实际需求动态地增加或减少节点,实现弹性扩缩容,以适应不同阶段的负载变化。

缺点:

  1. 复杂性:分片集群需要对数据进行分片和路由,涉及到数据拆分和合并、节点选择、数据迁移等复杂操作,增加了系统的维护和管理难度。

  2. 数据一致性:在分片集群中,数据被拆分存储在多个节点上,如果数据分布不均匀或节点故障导致数据丢失,可能会影响数据的一致性和完整性。

  3. 事务支持受限:Redis在分片模式下对事务的支持受到限制,跨节点的事务操作可能会导致一致性问题。

  4. 跨节点操作复杂:涉及跨节点操作的数据处理可能比单节点操作更复杂,例如在分片集群中实现原子性的全局操作可能较为困难。

  5. 部分节点故障:如果一个或多个节点宕机,分片集群的可用性可能会下降,特别是对于没有备份节点的分片。

总体而言,Redis分片集群在高性能、负载均衡和高可用性方面有着明显的优势,但在设计和维护时需要考虑复杂性和数据一致性等问题。适用于对读写性能要求较高、并且数据量较大的场景。如果应用场景对数据的一致性要求非常高,可能需要更复杂的解决方案,如Redis主从复制和哨兵模式。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孙仲谋111

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值