您当前的位置: 首页 >  缓存

white camel

暂无认证

  • 2浏览

    0关注

    442博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Redis——Redis集群原理、缓存预热、缓存击穿、缓存穿透、缓存雪崩的解决方案

white camel 发布时间:2020-08-04 13:21:08 ,浏览量:2

一、集群架构 1、概念

业务发展过程中遇到的峰值瓶颈

  • redis提供的服务OPS可以达到10万/秒,当前业务OPS已经达到10万/秒
  • 内存单机容量达到256G,当前业务需求内存容量1T

使用集群的方式可以快速解决上述问题

  • 集群 : 将同一种服务的多个节点放在一起共同对系统提供服务的过程称之为集群
  • 分布式 : 有多个不同服务集群共同对系统提供服务这个系统称之为分布式系统

集群就是使用网络将若干台计算机联通起来,并提供统一的管理方式,使其对外呈现单机的服务效果; 在这里插入图片描述

在这里插入图片描述

2、作用
  • 分散单台服务器的访问压力,实现负载均衡
  • 分散单台服务器的存储压力,实现可扩展性
  • 降低单台服务器宕机带来的业务灾难 在这里插入图片描述
3、Redis集群原理
  • 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽. 每一个redis节点, 都包含有自己的master, 以及slave
  • 集群中的节点的宕机是通过集群中超过半数的节点检测失效时才生效.
  • 客户端与redis节点直连,不需要中间proxy层. 客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
  • redis-cluster 把所有的物理节点映射到[0-16383] slot上, cluster 负责维护nodeslotvalue

在这里插入图片描述

  • 当客户端执行写(set)命令后, 会将set name zhangsan经过CRC16算法, 计算出其哈希槽的位置, 然后根据该位置存储到对应的Node节点 (redis集群中的某个节点) 内, 当执行读命令(get), 会根据槽的位置, 去指定节点内取数据; 不同key的哈希槽不同, 此时读写数据就会在不同的Node内进行操作; 实现了对Redis集群的操作;
  • 故障转移, 将宕机的master节点的 由 选举出来的slave来接管; 不会从新分配槽
  • 如果动态添加一个Node(redis节点), 此时要将其他Node的槽都分出来一些, 给新的Node; 保持对16384个槽进行均分; 将槽的value(对应key的值)也会分出去
二、Redis集群搭建
  • 判断一个是集群中的节点是否可用,是集群中的所用主节点选举过程,如果半数以上的节点认为当前节点挂掉,那么当前节点就是挂掉了,所以搭建redis集群时建议节点数最好为奇数,搭建集群至少需要三个主节点,三个从节点,至少需要6个节点。
1、准备工作 1、准备环境安装ruby以及redis集群依赖
  • yum install -y ruby rubygems
  • gem install redis-xxx.gem
2、在一台机器创建7个目录

在这里插入图片描述

3、每个目录复制一份配置文件

[root@localhost ~]# cp redis-4.0.10/redis.conf 7000/ [root@localhost ~]# cp redis-4.0.10/redis.conf 7001/ [root@localhost ~]# cp redis-4.0.10/redis.conf 7002/ [root@localhost ~]# cp redis-4.0.10/redis.conf 7003/ [root@localhost ~]# cp redis-4.0.10/redis.conf 7004/ [root@localhost ~]# cp redis-4.0.10/redis.conf 7005/ [root@localhost ~]# cp redis-4.0.10/redis.conf 7006/

在这里插入图片描述

4、修改不同目录配置文件(每一个Redis服务的配置都要改)
  • port 6379 … //修改端口
  • bind 0.0.0.0 //开启远程连接
  • cluster-enabled yes //开启集群模式
  • cluster-config-file nodes-port.conf //集群节点配置文件
  • cluster-node-timeout 5000 //集群节点超时时间
  • appendonly yes //开启AOF持久化
5、指定不同目录配置文件启动七个节点
  • [root@localhost bin]# ./redis-server /root/7000/redis.conf
  • [root@localhost bin]# ./redis-server /root/7001/redis.conf
  • [root@localhost bin]# ./redis-server /root/7002/redis.conf
  • [root@localhost bin]# ./redis-server /root/7003/redis.conf
  • [root@localhost bin]# ./redis-server /root/7004/redis.conf
  • [root@localhost bin]# ./redis-server /root/7005/redis.conf
  • [root@localhost bin]# ./redis-server /root/7006/redis.conf

在这里插入图片描述

6、查看进程
  • [root@localhost bin]# ps aux|grep redis

在这里插入图片描述

2、创建集群 1.复制集群操作脚本到bin目录中
  • [root@localhost bin]# cp /root/redis-4.0.10/src/redis-trib.rb .
2.创建集群
  • ./redis-trib.rb create --replicas 1 192.168.202.205:7000 192.168.202.205:7001 192.168.202.205:7002 192.168.202.205:7003 192.168.202.205:7004 192.168.202.205:7005

7000, 7001, 7002为主节点, 7003为7000的slave节点, 7004为7001的slave节点, 7005为7002的slave节点

在这里插入图片描述

3、集群创建成功出现如下提示

在这里插入图片描述

3、查看集群状态 1.查看集群状态 check [原始集群中任意节点] [无]
  • ./redis-trib.rb check 192.168.202.205:7000
4、操作集群

在这里插入图片描述 在这里插入图片描述 get name, 扔会去指定槽的master节点取数据 在这里插入图片描述

5、集群节点状态说明
  • 主节点 主节点存在hash slots,且主节点的hash slots 没有交叉 主节点不能删除, 因为删除后, hash slot就不完整了, 集群不可以操作 一个主节点可以有多个从节点 主节点宕机时多个副本之间自动选举主节点

  • 从节点 从节点没有hash slots 从节点可以删除 从节点不负责数据的写,只负责数据的同步

当主节点kill后, 会将该主节点对应的slave节点, 充当master节点, hash slot也会被拿过去;

6、集群节点的操作

在这里插入图片描述

三、Redis企业级解决方案

相关连接: Redis中缓存雪崩、缓存穿透等问题的解决方案

  • Redis详解(十二)------ 缓存穿透、缓存击穿、缓存雪崩
1、缓存预热
  • 缓存预热就是系统启动前,提前将相关的缓存数据直接加载到缓存系统。
    • 避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!
    • 用户直接查询事先被预热的缓存数据!
问题排查
  • 请求数量较高的时候, 需要缓存预热。 否则会先去查询数据库, 然后再将数据进行缓存
  • 主从之间数据吞吐量较大,数据同步操作频度较高
解决方案
  • 前置准备工作:

    • 日常例行统计数据访问记录,统计访问频度较高的热点数据
    • 利用LRU数据删除策略,构建数据留存队列 例如:storm与kafka配合
  • 准备工作:

    • 将统计结果中的数据分类,根据级别,redis优先加载级别较高的热点数据
    • 利用分布式多服务器同时进行数据读取,提速数据加载过程
    • 热点数据主从同时预热
  • 实施:

    • 使用脚本程序固定触发数据预热过程
    • 如果条件允许,使用了CDN(内容分发网络),效果会更好
  • 定时刷新缓存

总结
  • 缓存预热就是系统启动前,提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!
2、缓存雪崩
  • 缓存雪崩 是指 缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉。
缓存雪崩造成的后果: 数据库服务器崩溃(1)
  1. 系统平稳运行过程中,忽然数据库连接量激增
  2. 应用服务器无法及时处理请求
  3. 大量408,500错误页面出现
  4. 客户反复刷新页面获取数据
  5. 数据库崩溃
  6. 应用服务器崩溃
  7. 重启应用服务器无效
  8. Redis服务器崩溃
  9. Redis集群崩溃
  10. 重启数据库后再次被瞬间流量放倒
缓存雪崩原因
  • 在一个较短的时间内,缓存中较多的key集中过期
问题分析
  • 短时间范围内
  • 大量key集中过期
解决方案(道)
  1. 更多的页面静态化处理 (模板 + 动态数据)
  2. 构建 多级缓存架构 Nginx缓存+redis缓存+ehcache缓存
  3. 检测MySQL严重耗时业务进行优化 对数据库的瓶颈排查:例如超时查询、耗时较高事务等 --> 可以通过慢日志查询, 找到慢SQL, 然后通过explain执行计划分析慢SQL, 进而优化SQL
  4. 灾难预警机制, 监控redis服务器性能指标
    • CPU占用、CPU使用率
    • 内存容量
    • 查询平均响应时间
    • 线程数
  5. 限流、降级 短时间范围内牺牲一些客户体验,限制一部分请求访问,降低应用服务器压力,待业务低速运转后再逐步放开访问
解决方案(术)
  1. LRU与LFU切换 (Redis的内存淘汰策略)
  2. 数据有效期策略调整 (Redis的删除策略, 默认为 定期删除(随机找重点删一批) + 惰性删除)
    • 根据业务数据有效期进行分类错峰,A类90分钟,B类80分钟,C类70分钟
    • 过期时间使用固定时间+随机值的形式,稀释集中到期的key的数量
  3. 超热数据使用永久key
  4. 加锁 慎用, 效率低
解决方案 (总结)
  • 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
  • 一般并发量不是特别多的时候,使用最多的解决方案是加锁排队
  • 给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓存。
总结
  • 缓存雪崩就是瞬间过期数据量太大,导致对数据库服务器造成压力。如能够有效避免过期时间集中,可以有效解决雪崩现象的出现 (约40%),配合其他策略一起使用,并监控服务器的运行数据,根据运行记录做快速调整。

img

3、缓存击穿
  • 缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。
    • 缓存击穿指并发请求大量查询同一条数据, 造成数据库崩溃;
    • 缓存雪崩是不同数据都过期了(大面积缓存数据过期),很多数据都查不到从而查数据库。
数据库服务器崩溃(2)
  1. 系统平稳运行过程中
  2. 数据库请求某一个数据量 瞬间激增
  3. Redis服务器没有大量key过期, 只是一个热点Key过期, 然后大量请求该Key, 都请求到数据库上, 造成数据库崩溃
  4. Redis内存平稳,无波动
  5. Redis服务器CPU正常
缓存击穿的原因
  1. Redis中 某个key过期,该key访问量巨大
  2. 多个数据请求从服务器直接压到Redis后,均未命中
  3. Redis在短时间内发起了大量对数据库同一数据的访问
问题分析
  • 单个高热数据key过期
解决方案(术)
  • 设置热点数据永远不过期。
    • 预先设定热点数据过期时长(不过期/足够长时间不过期)
      • 以电商为例,每个商家根据店铺等级,指定若干款主打商品,在购物节期间,加大 此类信息key的 过期时长
      • 注意:购物节不仅仅指当天,以及后续若干天,访问峰值呈现逐渐降低的趋势
  • 加分布式锁(互斥锁) – 还可以防止超卖问题
    • 加分布式锁,防止被击穿,但是性能会造成瓶颈, 慎重 !
  • 现场调整热点Key的过期时间
    • 监控访问量,对自然流量激增的数据延长过期时间 或 设置为永久性key
  • 后台刷新数据
    • 启动定时任务,高峰期来临之前,刷新数据有效期,确保数据不过期
总结
  • 缓存击穿就是单个高热数据过期的瞬间, 数据访问量较大,未命中redis后,发起了大量对同一数据的数据库问,导致对数据库服务器造成压力。
  • 应对策略应该在业务数据分析预防方面进行,配合运行监控测试与即时调整策略,毕竟单个key的过期监控难度较高,配合雪崩处理策略即可
4、缓存穿透 (布隆过滤器解决)
  • 缓存穿透 是指缓存和数据库中都没有的数据,导致所有的请求都落到数据库上,造成数据库短时间内承受大量请求而崩掉。
  • 我们的数据库中的主键都是从0开始的,即使我们将数据库中的所有数据都放到了缓存中。当有人用id = -1来发生恶意请求时,因为redis中没有这个数据,就会直接访问数据库,这就称谓 缓存穿透
解决办法
  • 接口层增加校验,如用户鉴权校验,id做基础校验,id
关注
打赏
1661428283
查看更多评论
立即登录/注册

微信扫码登录

0.0400s