Redis性能分析
一、Redis是什么?
内存数据库,纯内存操作
Key-Value数据库,NoSQL数据库
C语言编写,性能极高
Redis支持数据持久化
需要大量内存(网络带宽),CPU不是瓶颈
单线程-----避免 切换与锁 --使用多路复用
二、Redis和Mysql区别
1、redis缓存服务器,数据存储在内存 mysql磁盘操作
2、高频数据,热点数据,高并发
二、压测报错分析
1、测试端问题
一般在jmeter的jmeter.log中体现:
OOM(内存溢出/内存不足):修改Jmeter堆内存大小,在Jmeter的bin/jmeter.bat,配置服务器内存的70%左右
端口数问题(如too many open files/adress alreadyin use):修改 win+R ,regedit打开注册表编辑器 查找计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters,下面右键新建DWDRD(32位)/值,重新命名为MaxUserPort 选择十进制,填写65535确定 然后重启Jmeter
2、 服务端报错
500 docker部署的:docker logs -f miaosha(服务名称) | grep error
3、Redis的redis-benchmark工具(抛开业务,可以测试redis可以接受/处理多少请求)
Redis性能基准测试可以通过使用自带的redis-benchmark工具,执行命令进行。使用起来简单,可以模拟N个机器(-c)从发送M个请求(-n)
三、Redis-benchmark测试工具(脱离业务,可以看到Redis的接收和处理请求数)
redis-benchmark -h 127.0.0.1 -p 6379 -t set,get -n 10000 -q -a sq
127.0.0.1 redis服务器 sq Redis密码
四、Grafana监控redis性能
1、下载redis_exporter镜像
docker pull ovliver006/redis_exporter
2、创建并运行redis_exporter容器
docker run -itd --name redis-exporter -p 9121:9121 \
oliver006/redis_exporter \
--redis.password=sq \
--redis.addr redis:172.17.0.1:6379 \
--include-system-metrics=true
3、更改prometheus配置/opt/prometheus/prometheus.yml
-job_name:'redis_exporter'
static_configs:
-targets:['172.17.0.1:9121']
然后重启prometheus: docker restart prometheus
4、Grafana中导入模板(编号763)
五、Redis击穿、雪崩现象
1、什么是缓存穿透?
缓存穿透是指一个根本不存在的数据,缓存层和储存层都不会命中,但是出于容错的考虑,如果从存储层差不到数据则不写入缓存层。缓存穿透将导致不存在的数据每次请求都要到存储层去查询,失去了缓存保护后端的存储的意义。
2、造成缓存穿透的基本有两个:
(1)业务本身代码或数据出现问题
(2)一些恶意攻击、爬虫等造成大量空命中
3、如何解决缓存穿透?
(1)缓存空对象
缓存空对象会出现两个问题:
第一、空值做了缓存,意味着缓存层中存了更多的键,需要更多的内存空间(如果攻击,问题更严重),比较有效的办法是针对这类数据设置一个较短的过期时间,让其自动剔除。
第二、缓存层和存储层的数据会有一段时间窗口的不一致,可能会造成业务有一定影响。例如过期时间设置为5分钟,如果此时存储层添加了这个数据,那此段时间就会出现缓存层和存储层的数据不一致,此时可以利用消息系统或其他方式消除掉缓存层中的空对象。
(2)布隆过滤器拦截
如下图所示,在访问缓存层和存储之前,将存在的Key用布隆过滤器提取保护起来,做第一层拦截。如果布隆过滤器任务该用户ID不存在,那么将不会访问存储层,这一定程度上保护了存储层。redis原生并不自带布隆过滤器,需要专门下载并自行编译和加载 https://oss.redislabs.com/redisbloom/
2、什么是缓存雪崩?
数据未开加载到缓存中,或者缓存同一时间大面积失效,从而导致所有的请求都去查数据库,导致数据CPU和内存负载过高,甚至宕机。(比如给缓存中的key设置了统一的过期时间,而在过期时间点,有大量的请求进来,这个时候redis中没有用户请求的资源,所以所有的请求会全部涌到数据库,如果数据库有报警监控的话,可能会报警,然后数据库就挂掉。如果这个时候把数据库重新启动,redis上还是没有缓存这些内容,数据库还是会被再一次击垮)
可以从以下几个方面防止缓存雪崩:
(1)保证缓存层服务高可可靠性
和飞机都有多个引擎一样,如果缓存层设计成高可用的,即使个别节点、个别机器、甚至机房宕机,依然可以提供服务,例如Redis Sentinel和Redis Cluster都实现了高可用。
(2)Redis备份和快速预热
Redis备份保证Master出现问题切换为slave迅速能够承担线上实际流量,快速预热保证缓存即使被写入缓存,防止缓存雪崩。
(3)依赖隔离组件为后端限流并降级
无论是缓存层还是存储层都会有出错的概率,可以将它们视同为资源,作为并发量较大的系统,例如有一个资源不可用,可能会造成线程全部hang在这个资源上,造成系统不可用。降级在高并发系统中是非常正常的:比如推荐服务中,如果个性化推荐服务不可用,可以降级补充热点数据,不至于造成前端页面是开天窗。
(4)提前演练
在项目上线前,演练缓存层宕机后,应用以及后端的负载情况以及可能出现的问题,在此基础上做一些预案设定。
(5)缓存预热
缓存预热就是系统上线前,将相关的缓存数据直接加载到缓存系统。这样就可以避免上线后在用户请求的时候,先查询数据库,然后再将数据缓存的问题。用户直接查询事先被预热的缓存数据。