Redis 潜在问题

举报
武师叔 发表于 2022/08/23 09:14:28 2022/08/23
【摘要】 Redis 潜在问题缓存故障Redis 缓存技术常用于高并发情况下,有效减轻服务器和数据库负载。如果 Redis 出现问题导致无法均衡负载,就可能导致服务崩溃。缓存预热当系统刚启动时,由于 Redis 尚未保存数据导致无法命中,数据库被频繁请求数据,由于过载导致数据库崩溃。数据库崩溃后, Redis 和应用服务器无法获取数据,请求积压会进一步导致 Redis 和服务器崩溃。缓存雪崩当流量激增...

Redis 潜在问题

缓存故障

Redis 缓存技术常用于高并发情况下,有效减轻服务器和数据库负载。如果 Redis 出现问题导致无法均衡负载,就可能导致服务崩溃。

  1. 缓存预热

当系统刚启动时,由于 Redis 尚未保存数据导致无法命中,数据库被频繁请求数据,由于过载导致数据库崩溃。

数据库崩溃后, Redis 和应用服务器无法获取数据,请求积压会进一步导致 Redis 和服务器崩溃。

  1. 缓存雪崩

当流量激增时,如果 Redis 大量 key 过期导致无法命中,数据库被频繁请求数据,由于过载导致数据库崩溃。

数据库崩溃后, Redis 和应用服务器无法获取数据,请求积压会进一步导致 Redis 和服务器崩溃。

  1. 缓存击穿

当流量激增时,如果 Redis 某个极高热度的 key 过期导致无法命中,数据库被频繁请求数据,由于过载导致数据库崩溃。

数据库崩溃后, Redis 和应用服务器无法获取数据,请求积压会进一步导致 Redis 和服务器崩溃。

  1. 缓存穿透

当流量激增时,如果 Redis 收到大量非法访问导致无法命中,数据库被频繁请求数据,由于过载导致数据库崩溃。

数据库崩溃后, Redis 和应用服务器无法获取数据,请求积压会进一步导致 Redis 和服务器崩溃。

一致性问题

如果在缓存中存储数据库数据备份,以提高查询效率,就一定会出现一致性问题,导致脏读。比如数据库中数据从 1 更新到 10 ,但缓存还未更新时读取,就会读取到 1。这个问题难以避免。

  1. 缓存就是缓存,必须要设过期时间。
  2. 实时性要求比较高的(比如充值),直接读数据库。
  3. 数据库并发高需要分库分表。

Redis 客户端

我们在实际使用 Redis 时往往要通过 Redis 客户端,以便在程序中直接操作 Redis 。常使用的 Redis 客户端有 Jedis、 以及功能更为高级的 Redisson、Lettuce 等。

RedisTemplate 类

Spring Boot 提供了 RedisTemplate 工具类直接对 Redis 进行操作,也提供了 StringRedisTemplate 类继承 RedisTemplate 类,两者方法完全一致。

  • RedisTemplate 类:存储数据时序列化成字节数组保存,在 Redis 中数据为字节码。读取数据时自动转化为对象。
  • StringRedisTemplate 类:存储数据直接以字符串形式保存,在 Redis 中数据直接可读。只适用于字符串类型的数据。

由于两种序列化方法不同导致的数据存储形式差异,两个类之间不能对另一方存储的 Redis 数据进行操作。

常用方法

/* 直接对 key 操作 */
redisTemplate.delete("key");                                             // 删除 key
redisTemplate.delete(collection);                                        // 批量删除 key
redisTemplate.expire("key",10,TimeUnit.MINUTES);                         // 设置 key 失效时间
Long expire = redisTemplate.getExpire("key");                            // 获取 key 失效时间
boolean flag = redisTemplate.hasKey("key");                              // 判断 key 是否存在

/* 操作字符串 */
redisTemplate.opsForValue().set("key", "value");                         // 设置键值对 
String str = (String)redisTemplate.opsForValue().get("key");             // 获取键值

/* 操作 hash */
redisTemplate.opsForHash().put("HashKey", "SmallKey", "HashValue");                  // 设置键值对
redisTemplate.boundHashOps("HashKey").putAll(hashMap);                               // 批量设置键值对
String value = (String) redisTemplate.opsForHash().get("HashKey", "SmallKey");       // 获取键值
Map entries = redisTemplate.opsForHash().entries("HashKey");                         // 获取全部键值对
redisTemplate.boundHashOps("HashKey").delete("SmallKey");                            // 删除键值对
Boolean isEmpty = redisTemplate.boundHashOps("HashKey").hasKey("SmallKey");          // 是否含有键值对


redisTemplate.opsForList();   // 操作 list
redisTemplate.opsForSet();    // 操作 set
redisTemplate.opsForZSet();   // 操作有序 set



【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。