Redis:基于内存的高性能数据库,可以加载热点数据、时效性数据
redis有五种数据类型:
字符串类型 string
列表类型 list
散列集合 hash
集合类型 set
有序集合类型 zset/sorted_set
数据删除策略
1.定时删除
创建一个定时器,当key设置有过期时间,且过期时间到达时,由定时器任务立即执行对键的删除操作
优点:节约内存
缺点:cpu压力很大,无论cpu负载量多高,均占用cpu,会影响吞吐量
总结:用处理器性能换取存储空间
2.惰性删除
数据到达期间,不做处理,等下次访问该数据时删除
优点:节约cpu性能
缺点:内存占用大
3.定期删除
心跳机制:进入命令传播阶段,master与slave间需要进行信息交换,使用心跳机制进行维护,实现双方保持在线
哨兵模式
主机宕机后,关闭master和所有的slave,找一个slave作为master,修改其他slave的配置连接新的主服务器,启动新的master与slave。全量复制*N+部分复制*N
缓存预热:缓存预热就是系统启动前,提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题,用户直接查询事先被预热的缓存数据
缓存雪崩
问题:数据库服务器崩溃
问题排查:在一个较短时间内,缓存中较多的key集中过期
数据库同时接收到大量的请求
解决方案:更多的页面静态化处理
构建多级缓存架构:Nginx缓存+redis缓存+ehcache缓存
检测Mysql严重耗时业务进行优化
灾难预警机制、限流
缓存雪崩:缓存雪崩就是瞬间过期数据量太大,导致对数据库服务器造成压力。如果能够有效避免过期时间集中,可用有效解决雪崩现象的出现(约40%)。配合其他策略一起使用,并监控服务器的运行数据,根据运行记录做出快速调整
缓存击穿
数据库服务器崩溃
1.系统在平稳运行过程中,数据库连接量瞬间激增
2.redis服务器无大量key过期
3.redis服务器cpu正常
4.数据库崩溃
问题排查
1.redis中的某个key过期,该key访问量巨大
2.多个数据请求从服务器直接压大redis后,均未命中
3.redis在短时间内发起大量对数据库中同一数据的访问
解决:监控访问量,对激增的数据延长或设为永久
缓存击穿就是单个高热数据过期的瞬间,数据访问量较大,未命中redis后,发起了大量对同一数据的数据库访问,导致对数据库服务器造成压力。应对策略应该在业务数据分析与预防方面进行,配合运行监控测试与及时调整战略,毕竟单个key的过期监控难度较高,配合雪崩处理策略即可
缓存穿透
数据库服务器崩溃
问题排查
1.redis中出现大面积未命中
2.出现非正常URL访问
问题分析
获取的数据在数据库中也不存在,数据库查询未得到对应数据
redis获取到null数据未进行持久化,直接返回
下次此类数据到达重复上述过程
出现黑客攻击服务器
解决方案
实时监控redis命中率与null数据的占比
缓存击穿访问了不存在的数据,跳过了合法数据的redis数据缓存阶段,每次访问数据库,导致对数据库服务器造成压力。通常此类数据的出现量是一个较低的值,当出现此类情况以毒攻毒,并及时报警。应对策略应该在临时预案防范方面做文章
redisTemplate操作Redis
string类型
通过ValueOperations设置值
ValueOperations ops = redisTemplate.opsForValue();
ops.set("StringKey", "StringVaule");
ops.set("StringValue","StringVaule",1, TimeUnit.MINUTES);
通过ValueOperations获取值
ValueOperations ops = redisTemplate.opsForValue();
String str3 = (String) ops.get("StringKey");
hash
通过ValueOperations设置值
HashOperations hashOps = redisTemplate.opsForHash();
hashOps.put("HashKey", "SmallKey", "HashVaue");
通过ValueOperations获取值
HashOperations hashOps = redisTemplate.opsForHash();
Set keys3 = hashOps.keys("HashKey");
redisTemplate.expire("HashKey",1,TimeUnit.MINUTES);
set
通过ValueOperations设置值
SetOperations setOps = redisTemplate.opsForSet();
setOps.add("setKey", "SetValue1", "setValue2", "setValue3");
redisTemplate.expire("setKey",1,TimeUnit.MINUTES);
通过ValueOperations获取值
SetOperations setOps = redisTemplate.opsForSet();
Set set3 = setOps.members("setKey");
list
通过ValueOperations设置值
ListOperations opsList = redisTemplate.opsForList();
opsList.leftPush("listKey", "listLeftValue5");
opsList.rightPush("listKey", "listRightValue6");
redisTemplate.expire("listKey",1,TimeUnit.MINUTES);