写点什么

Redis 潜在问题

作者:武师叔
  • 2022 年 8 月 15 日
    辽宁
  • 本文字数:1633 字

    阅读完需:约 5 分钟

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");                                             // 删除 keyredisTemplate.delete(collection);                                        // 批量删除 keyredisTemplate.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();   // 操作 listredisTemplate.opsForSet();   // 操作 setredisTemplate.opsForZSet();   // 操作有序 set
复制代码


发布于: 刚刚阅读数: 4
用户头像

武师叔

关注

每天丰富自己,去过自己想要的生活! 2022.04.28 加入

一个喜欢最新技术,研发的人工智能专业的大二学生,用自己的代码做一些有意义的事情! 目前大二结束有去大厂研发岗实习的计划,每天丰富自己的技术,去过自己想要的实习生活。

评论

发布
暂无评论
Redis 潜在问题_8月月更_武师叔_InfoQ写作社区