业务发展过程中遇到的峰值瓶颈
- redis提供的服务OPS可以达到10万/秒,当前业务OPS已经达到10万/秒
- 内存单机容量达到256G,当前业务需求内存容量1T
使用集群
的方式可以快速解决上述问题
集群 :
将同一种服务的多个节点放在一起共同对系统提供服务的过程称之为集群
。分布式 :
有多个不同服务集群
共同对系统提供服务
这个系统称之为分布式系统
集群就是使用网络将若干台计算机联通起来,并提供统一的管理方式,使其对外呈现单机的服务效果;
- 分散单台服务器的访问压力,实现负载均衡
- 分散单台服务器的存储压力,实现可扩展性
- 降低单台服务器宕机带来的业务灾难
- 所有的
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集群时建议节点数最好为奇数
,搭建集群至少需要三个主节点,三个从节点,至少需要6个节点。
- yum install -y ruby rubygems
- gem install redis-xxx.gem
[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/
- port 6379 … //修改端口
- bind 0.0.0.0 //开启远程连接
- cluster-enabled yes //开启集群模式
- cluster-config-file nodes-port.conf //集群节点配置文件
- cluster-node-timeout 5000 //集群节点超时时间
- appendonly yes //开启AOF持久化
- [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
- [root@localhost bin]# ps aux|grep redis
- [root@localhost bin]#
cp /root/redis-4.0.10/src/redis-trib.rb .
./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节点
./redis-trib.rb check 192.168.202.205:7000
get name, 扔会去指定槽的master节点取数据
-
主节点 主节点存在
hash slots
,且主节点的hash slots 没有交叉 主节点不能删除, 因为删除后, hash slot就不完整了, 集群不可以操作 一个主节点可以有多个从节点主节点宕机时多个副本之间自动选举主节点
-
从节点 从节点没有hash slots 从节点可以删除
从节点不负责数据的写,只负责数据的同步
当主节点kill后, 会将该主节点对应的slave节点, 充当master
节点, hash slot也会被拿过去;
相关连接: Redis中缓存雪崩、缓存穿透等问题的解决方案
- Redis详解(十二)------ 缓存穿透、缓存击穿、缓存雪崩
缓存预热
就是系统启动前,提前将相关的缓存数据直接加载到缓存系统。- 避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!
- 用户直接查询事先被预热的缓存数据!
- 请求数量较高的时候, 需要缓存预热。 否则会先去查询数据库, 然后再将数据进行缓存
- 主从之间数据吞吐量较大,数据同步操作频度较高
-
前置准备工作:
- 日常例行统计数据访问记录,
统计访问频度较高的热点数据
- 利用LRU数据删除策略,构建数据留存队列 例如:storm与kafka配合
- 日常例行统计数据访问记录,
-
准备工作:
- 将统计结果中的数据分类,根据级别,redis优先加载级别较高的热点数据
- 利用分布式多服务器同时进行数据读取,提速数据加载过程
- 热点数据主从同时预热
-
实施:
- 使用脚本程序固定触发数据预热过程
- 如果条件允许,使用了CDN(内容分发网络),效果会更好
-
定时刷新缓存
- 缓存预热就是系统启动前,提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!
缓存雪崩
是指 缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉。
- 系统平稳运行过程中,忽然数据库连接量激增
- 应用服务器无法及时处理请求
- 大量408,500错误页面出现
- 客户反复刷新页面获取数据
- 数据库崩溃
- 应用服务器崩溃
- 重启应用服务器无效
- Redis服务器崩溃
- Redis集群崩溃
- 重启数据库后再次被瞬间流量放倒
- 在一个
较短的时间内
,缓存中较多的key集中过期
- 短时间范围内
- 大量key集中过期
- 更多的页面静态化处理 (模板 + 动态数据)
- 构建 多级缓存架构
Nginx缓存+redis缓存+ehcache缓存
- 检测MySQL严重耗时业务进行优化 对数据库的瓶颈排查:例如超时查询、耗时较高事务等 --> 可以通过慢日志查询, 找到慢SQL, 然后通过explain执行计划分析慢SQL, 进而优化SQL
- 灾难预警机制, 监控redis服务器性能指标
- CPU占用、CPU使用率
- 内存容量
- 查询平均响应时间
- 线程数
限流、降级
短时间范围内牺牲一些客户体验,限制一部分请求访问,降低应用服务器压力,待业务低速运转后再逐步放开访问
- LRU与LFU切换 (Redis的内存淘汰策略)
数据有效期策略调整
(Redis的删除策略, 默认为 定期删除(随机找重点删一批) + 惰性删除)- 根据业务数据有效期进行分类错峰,A类90分钟,B类80分钟,C类70分钟
- 过期时间使用固定时间+随机值的形式,稀释集中到期的key的数量
- 超热数据使用永久key
- 加锁 慎用, 效率低
- 缓存数据的
过期时间设置随机
,防止同一时间大量数据过期现象发生。 - 一般并发量不是特别多的时候,使用最多的解决方案是
加锁排队
。 - 给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓存。
- 缓存雪崩就是瞬间过期数据量太大,导致对数据库服务器造成压力。如能够有效避免过期时间集中,可以有效解决雪崩现象的出现 (约40%),配合其他策略一起使用,并监控服务器的运行数据,根据运行记录做快速调整。
缓存击穿
是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。缓存击穿指并发请求大量查询同一条数据, 造成数据库崩溃;
缓存雪崩是不同数据都过期了(大面积缓存数据过期),很多数据都查不到从而查数据库。
- 系统平稳运行过程中
- 数据库请求某一个数据量 瞬间激增
Redis服务器没有大量key过期, 只是一个热点Key过期, 然后大量请求该Key, 都请求到数据库上, 造成数据库崩溃
- Redis内存平稳,无波动
- Redis服务器CPU正常
- Redis中
某个key过期,该key访问量巨大
- 多个数据请求从服务器直接压到Redis后,均未命中
- Redis在短时间内发起了大量对
数据库
中同一数据
的访问
- 单个高热数据key过期
设置热点数据永远不过期。
预先设定热点数据过期时长(不过期/足够长时间不过期)
- 以电商为例,每个商家根据店铺等级,指定若干款主打商品,在购物节期间,加大 此类信息key的 过期时长
- 注意:购物节不仅仅指当天,以及后续若干天,访问峰值呈现逐渐降低的趋势
加分布式锁(互斥锁)
– 还可以防止超卖问题- 加分布式锁,防止被击穿,但是性能会造成瓶颈, 慎重 !
- 现场调整热点Key的过期时间
- 监控访问量,对自然流量激增的数据延长过期时间 或 设置为永久性key
- 后台刷新数据
- 启动定时任务,高峰期来临之前,刷新数据有效期,确保数据不过期
- 缓存击穿就是单个高热数据过期的瞬间, 数据访问量较大,未命中redis后,发起了大量对同一数据的数据库问,导致对数据库服务器造成压力。
- 应对策略应该在
业务数据分析
与预防方面
进行,配合运行监控测试与即时调整策略,毕竟单个key的过期监控难度较高,配合雪崩处理策略即可
缓存穿透
是指缓存和数据库中都没有的数据,导致所有的请求都落到数据库上,造成数据库短时间内承受大量请求而崩掉。- 我们的数据库中的主键都是从0开始的,即使我们将数据库中的所有数据都放到了缓存中。当有人用
id = -1
来发生恶意请求时,因为redis中没有这个数据,就会直接访问数据库,这就称谓 缓存穿透
- 接口层增加校验,如用户鉴权校验,id做基础校验,id
关注打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?