Redis 企业级解决方案(缓存预热 缓存雪崩 缓存击穿)(十二)

1. 缓存预热

  • 问题
    服务器启动后迅速宕机
  • 问题分析
  • 请求数量较高
  • 主从之间数据吞吐量较大,数据同步操作频度较高
  • 解决方案

    • 前置准备工作
      • 日常例行统计数据访问记录,统计访问频度较高的热点数据
      • 利用LRU数据删除策略,构建数据留存队列例如:storm和kfafa配合、
    • 准备工作
      • 将统计结果中的数据分类,根据级别,redis优先加载级别较高的热点数据
      • 利用分布式多服务器同时进行数据读取,提速数据加载过程
      • 热点数据主从同时预热
    • 实施
      • 使用脚本程序固定触发数据预热过程
      • 如果条件允许,使用了CDN(内容分发网络),效果会更好
  • 总结
    缓存预热就是系统启动前,提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题,将热点数据提前缓存,用户直接查询事先被预热的缓存数据。

2. 缓存雪崩

缓存雪崩就是当Redis服务器重启或者大量缓存数据在同一时期失效时,请求全部转发到数据库,数据库有可能会因为承受不住而宕机

  • 解决方案
  • 更多的页面静态化处理
  • 构建多级缓存架构 Nginx缓存+redis缓存+ehcache缓存
  • LRU 与LFU 切换
  • 数据有效期策略调整
    根据业务数据有效期进行分类错峰,A类90分钟,B类80分钟,C类70分钟
    过期时间使用固定时间+随机值的形式,稀释集中到期的key的数量
  • 超热数据使用永久可以
  • 定期维护(自动+人工),对即将过期数据做访问量分析,确认是否延时,配合访问量统计,做热点数据延时
  • 加锁(慎用)

3. 缓存穿透

缓存击穿访问了不存在的数据,跳过了合法数据的redis数据缓存阶段,每次访问数据库,导致对数据库服务器造成压力(一般这种情况出现多为黑客攻击)。

  • 解决方案
  • 缓存null
    对查询结果为null的数据进行缓存(长期使用,定期清理),设定短时限,例如30-60秒,最高5分钟
  • 白名单策略
    提前预热各种分类数据id对应的bitmaps,id作为bitmaps的offset,相当于设置了数据白名单。当加载正常数据时,放 行,加载异常数据时直接拦截(效率偏低)
    使用布隆过滤器(有关布隆过滤器的命中问题对当前状况可以忽略)
  • 实施监控
    实时监控redis命中率(业务正常范围时,通常会有一个波动值)与null数据的占比
    非活动时段波动:通常检测3-5倍,超过5倍纳入重点排查对象
    活动时段波动:通常检测10-50倍,超过50倍纳入重点排查对象
    根据倍数不同,启动不同的排查流程。然后使用黑名单进行防控(运营)

如有不足之处,欢迎指正,谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、基于nginx+lua完成商品详情页访问流量实时上报kafka的开发 ==================================== 在nginx这一层,接收到访问请求的时候,就把请求的流量上报发送给kafka 这样的话,storm才能去消费kafka中的实时的访问日志,然后去进行缓存热数据的统计 用得技术方案非常简单,从lua脚本直接创建一个kafka producer,发送数据到kafka ``` wget https://github.com/doujiang24/lua-resty-kafka/archive/master.zip yum install -y unzip unzip lua-resty-kafka-master.zip cp -rf /usr/local/lua-resty-kafka-master/lib/resty /usr/hello/lualib nginx -s reload local cjson = require("cjson") local producer = require("resty.kafka.producer") local broker_list = { { host = "192.168.31.187", port = 9092 }, { host = "192.168.31.19", port = 9092 }, { host = "192.168.31.227", port = 9092 } } local log_json = {} log_json["headers"] = ngx.req.get_headers() log_json["uri_args"] = ngx.req.get_uri_args() log_json["body"] = ngx.req.read_body() log_json["http_version"] = ngx.req.http_version() log_json["method"] =ngx.req.get_method() log_json["raw_reader"] = ngx.req.raw_header() log_json["body_data"] = ngx.req.get_body_data() local message = cjson.encode(log_json); local productId = ngx.req.get_uri_args()["productId"] local async_producer = producer:new(broker_list, { producer_type = "async" }) local ok, err = async_producer:send("access-log", productId, message) if not ok then ngx.log(ngx.ERR, "kafka send err:", err) return end ``` 两台机器上都这样做,才能统一上报流量到kafka ``` bin/kafka-topics.sh --zookeeper 192.168.31.187:2181,192.168.31.19:2181,192.168.31.227:2181 --topic access-log --replication-factor 1 --partitions 1 --create bin/kafka-console-consumer.sh --zookeeper 192.168.31.187:2181,192.168.31.19:2181,192.168.31.227:2181 --topic access-log --from-beginning ``` (1)kafka在187上的节点死掉了,可能是虚拟机的问题,杀掉进程,重新启动一下 nohup bin/kafka-server-start.sh config/server.properties & (2)需要在nginx.conf中,http部分,加入resolver 8.8.8.8; (3)需要在kafka中加入advertised.host.name = 192.168.31.187,重启三个kafka进程 (4)需要启动eshop-cache缓存服务,因为nginx中的本地缓存可能不在了 二、基于storm+kafka完成商品访问次数实时统计拓扑的开发 ==============

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值