redis复习总结

redis缓存一致性解决方案?

保证更新DB和操作缓存之间的连续性

两个动作之间原则上是非原子性的,一个是更新DB,一个是更新redis。但是,通常我们使用一个妥协的方案,类似于分布式事务最终一致性的实现,这里也可以使用消息队列实现最终一致性的消息保证。

先更新DB数据,然后通过发送操作缓存的消息到消息队列,进行更新缓存操作,这里还需要的一个操作就是利用消息队列的重试机制,保证缓存能够更新成功,如果多次消费失败,可能是由于网络原因或者redis服务挂了,此处可以添加告警处理。
1.第一种方案:采用延时双删策略

在写库前后都进行redis.del(key)操作,并且设定合理的超时时间。

具体的步骤就是:

  • 先删除缓存;
  • 再写数据库;
  • 休眠500毫秒;
  • 再次删除缓存。

第二种方案:异步更新缓存(基于订阅binlog的同步机制)

技术整体思路:

MySQL binlog增量订阅消费+消息队列+增量数据更新到redis

  • 读Redis:热数据基本都在Redis
  • 写MySQL:增删改都是操作MySQL
  • 更新Redis数据:MySQ的数据操作binlog,来更新到Redis

redis分布式锁实现?

setnx+setex:存在设置超时时间失败的情况,导致死锁

引入Redisson框架依赖,进行加锁和释放锁

Rlock lock = redissson.getLock("myLock")

lock.lock();

lock.unlock;

加锁机制:某个客户端要加锁,如果该客户端面对的是一个redis cluster集群,他首先会根据hash节点选择一台机器,然后会发送一段lua脚本(胶水语言)到redis上,hset

reids哨兵选举机制?

  • 监控(Monitoring): Sentinel 会不断地定期检查你的主服务器和从服务器是否运作正常。
  • 提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
  • 自动故障迁移(Automaticfailover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中 一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客 户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主 服务器代替失效服务器。
  • 哨兵lerder选举流程

  • a)每个在线的哨兵节点都可以成为领导者,当它确认(比如哨兵3)主节点下线时,会向其它哨兵发is-master-down-by-addr命令,征求判断并要求将自己设置为领导者,由领导者处理故障转移;
    b)当其它哨兵收到此命令时,可以同意或者拒绝它成为领导者;
    c)如果哨兵3发现自己在选举的票数大于等于num(sentinels)/2+1时,将成为领导者,如果没有超过,继续选举…………

redis常用命令?

set,ex

redis数据类型底层实现原理?

zset

zset有序集合,元素不重复。一般可用于排行榜功能,跟普通的set比起来,每一个element都多了一个score。score可以重复,element不能重复。

zset的编码有ziplistskiplist两种。
底层分别使用ziplist(压缩链表)skiplist(跳表)实现

当zset满足以下两个条件的时候,使用ziplist:

  1. 保存的元素少于128个
  2. 保存的所有元素大小都小于64字节

不满足这两个条件则使用skiplist

(注意:这两个数值是可以通过redis.confzset-max-ziplist-entries 和 zset-max-ziplist-value选项 进行修改。)

当ziplist作为zset的底层存储结构时候,每个集合元素使用两个紧挨在一起的压缩列表节点来保存,第一个节点保存元素的成员,第二个元素保存元素的分值。

当skiplist作为zset底层的时候有序集合对象使用 zet 结构作为底层实现,一个 zset 结构同时包含一个字典和一个跳跃表

string

  • 使用整数值实现的字符串对象,使用的是8个字节的long类型进行存储。
  • 使用embstr编码的动态字符串实现的字符串对象,存储长度小于44字节的字符串
  • 动态字符串实现的字符串对象,存储长度大于44字节的字符串。

hash


redis中的两种持久化方式?

由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。redis提供两种方式进行持久化,一种是RDB持久化(原理是将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化),另外一种是AOF(append only file)持久化(原理是将Reids的操作日志以追加的方式写入文件)

在redis中,允许用户设置的最大使用内存大小是  512G。

RDB的优点

  1. RDB 是一个非常紧凑(compact)的文件,它保存了 Redis 在某个时间点上的数据集。 这种文件非常适合用于进行备份: 比如说,你可以在最近的 24 小时内,每小时备份一次 RDB 文件,并且在每个月的每一天,也备份一个 RDB 文件。 这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。

  2. RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快

redis的6种策略?

  1. volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
  2. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
  3. volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
  4. allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
  5. allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
  6. no-enviction(驱逐):禁止驱逐数据

Redis为何那么快-----底层原理浅析?

  1. 内存操作
  2. IO多路复用机制,减少了阻塞
  3. 单线程避免了线程切换的开销和竞争问题
  4. 最最根本的redis是用C语言写的,本来就直接跟操作系统交互,命令执行快得飞起

如果一个线程获得了分布式锁,但service还没执行完,这个时候分布式锁在redis中过期了,这种情况解决有什么思路?

分布式锁过期了,解决方案当然就是续期啦。那么应该怎么续期呢?

思路一:任务执行的时候,开辟一个守护线程,在守护线程中每隔一段时间重新设置过期时间。

思路二:通过Redisson中的看门狗来实现。

redis分布式锁实现原理?和普通锁区别在哪里?

缓存穿透、缓存击穿、缓存雪崩区别和解决方案 

缓存穿透

缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。

访问一个不存在的key,缓存不起作用,请求会穿透到DB,流量大时DB会挂掉。

  解决方案:

  1. 接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
  2. 从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻
  3. 采用布隆过滤器

缓存击穿

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力

 一个存在的key,在缓存过期的一刻,同时有大量的请求,这些请求都会击穿到DB,造成瞬时DB请求量大、压力骤增。

  解决方案:

设置热点数据永远不过期或者互斥锁。

缓存雪崩

缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是,        缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

 大量的key设置了相同的过期时间,导致在缓存在同一时刻全部失效,造成瞬时DB请求量大、压力骤增,引起雪崩。

解决方案

  1. 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。                         
  2. 如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。
  3. 设置热点数据永远不过期。

如果一个线程获得了分布式锁,但service还没执行完,这个时候分布式锁在redis中过期了,这种情况解决有什么思路?

思路一:任务执行的时候,开辟一个守护线程,在守护线程中每隔一段时间重新设置过期时间。

思路二:通过Redisson中的看门狗来实现。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值