redis避坑

目录

正确的选择数据类型

都使用string去存储数据存在哪些弊端 

命名策略

常用的数据类型及其适用场景

用了事务却没有发生回滚

redis事务

 redis事务的两类错误 

为什么redis不支持回滚

redis性能上不去,可能是有 big key

big key以及造成的危害

big key是如何产生的

如何发现BigKey

 删除bigkey

Redis怎么出现了内存耗尽

Redis服务器内存耗尽的场景

将key标记为Volatile(易失的)

Redis的过期删除策略

有了过期机制以后内存还是不够用

设置了过期Redis服务器内存还是不够用原因

Redis的内存淘汰策略

如何解决频繁的命令往返造成的性能瓶颈

redis客户端和服务端的交互模型 

redis的pipeline的交互模型

 Redis pipeline与原生批量命令对比

使用redis pipeline需要注意什么

配置好持节化机制

redis为什么需要持久化

RDB

 RDB持久化触发原理

手动触发

定时触发

AOF的持久化配置

 AOF重写

 从持久化中恢复数据

 企业级的恢复策略

缓存穿透隐患

通用的业务存储架构

缓存穿透的含义以及带来的影响

​ 怎么解决缓存穿透

出现缓存雪崩怎么办

为什么会出现缓存雪崩

缓存雪崩会带来什么问题

​ 怎么解决缓存雪崩 


正确的选择数据类型

都使用string去存储数据存在哪些弊端 

  • 浪费存储空间,key也是需要存储空间的
  • 管理维护麻烦,Redis中存在着大量的KV对象
  • key冲突比较高
  • 建议使用hash存储对象 

命名策略

业务名称+工程名+模块名+(有意义的)键名

 

常用的数据类型及其适用场景

  • string
    • 应用最广泛的数据类型,例如计数器,session等键值"独立"的数据
  • hash
    • 存储结构化(对象)的数据,KV共同构成一个对象的信息
  • list
    • 队列,栈,有界队列
  • set
    • 去重,无序的数据集合,在类似于社交的业务功能上有广泛应用,例如:共同关注,共同喜好,数据去重
  • sortedset
    • 带有权重的集合,在类似于排行榜业务上有广泛应用,且可以视线范围查找

用了事务却没有发生回滚

redis事务

 redis事务的两类错误 

为什么redis不支持回滚

  • 失败的命令是因为编程错误造成的,这些错误应该在开发的过程中被发现,所以不支持回滚
  • 如果检测到了事务命令的错误应该不加思索的使用discard放弃这个事务 

redis性能上不去,可能是有 big key

big key以及造成的危害

  • 数据量大的key,比如字符串的Value值非常大( > 10kB),哈希,列表,集合,有序集合元素多(元素个数>5000)
  • big key造成的危害
    • 内存不均:针对redis集群来说,不确定存在集群的哪一台机器上,或造成不同的机器使用内存不均的情况

    • 超时阻塞,redis操作big key比较耗时,阻塞redis的可能性就会变得很大

    • 网络流量阻塞,每次获取要产生的网络流量比较大

    • 过期删除,过期删除时间长,可能会阻塞

    • 迁移困难:备份和导入都会导致阻塞,迁移困难

big key是如何产生的

  • 社交类场景
    • 粉丝列表,对于明星或者大V来说,需要特殊的设计,否则,就成为了BigKey
  • 汇总统计类场景
    • 每天都会产生报表数据,报表数据汇总到一个key里面,日积月累就成为了BigKey
  • 日常缓存类场景
    • 对DB中的数据进行缓存,大表(存在大字段)很可能会产生BigKey

如何发现BigKey

  • redis-cli提供了 --bigkeys来查找bigkey:给出了每种数据结构的top 1 bigkey,同时也给出了每种数据类型键值个数以及平均大小
    • 如果想查询redis中大于10KB的所有key,--bigkeys就无能为力了

  •  redis4.0开始提供了memory usage命令可以计算每个键值对的字节数(Redis为了保存这个键值对一共需要消耗的内存,包括指针开销)

 删除bigkey

Redis怎么出现了内存耗尽

Redis服务器内存耗尽的场景

内存耗尽的结果是只能读而不能写

  1. 业务不断发展,缓存数据不断增多,需要消耗Redis内存
  2. 无效(过期)的数据没有及时清理,需要消耗Redis内存(优化点)
  3. 没有对"冷数据"(不经常访问的用户)进行降级需要消耗Redis内存(优化点:直接从redis中删除,当发送请求时从mysql中直接读然后再写到mysql中);

将key标记为Volatile(易失的)

  • ttl key 查看过期时间
  • expire key seconds 给key增加一个过期时间
  • rename beforekey afterkey 不会改变过期时间
  • presist key  将这个key过期时间移除,标记为持久的key

Redis的过期删除策略

  • 定时删除
    • 为每一个设置了过期时间的key都会创建一个定时器,一旦到达过期时间就会立即删除
  • 惰性删除
    • 当访问一个key时,才判断key是否过期,过期删除
  • 定期删除
    • 每个一段时间,扫描Redis中过期key字典,并删除部分过期的key
  • redis使用了定期+惰性删除

有了过期机制以后内存还是不够用

设置了过期Redis服务器内存还是不够用原因

  1. 业务缓存数据需求量大,占用大量的内存空间
  2. 过期的key虽然有很多,但是不能"及时失效",仍会有大量的key堆积在内存中,导致Redis内存耗尽
  • 有没有办法让Redis主动帮我们淘汰"一些数据"呢??

Redis的内存淘汰策略

  • Redis的内存淘汰策略,是指内存达到maxmemory极限时,使用某种算法来决定清理掉哪些数据,以保证新数据的写入

  • 最常用的内存淘汰策略

    • Volatile:只会针对带过期时间的key进行淘汰

      • volatile-lru:最近最久未被使用的key

      • volatile-random:随机的key

      • volatile-ttl:根据key的剩余时间,越小优先会被淘汰

    • allkeys:策略会针对所有的key进行淘汰
      • allkeys-lru:最近最久未被使用的key
      • allkeys-random:随机的key
    • noeviction:默认的淘汰策略,当redis满了之后就不能提供写服务,但是可以提供读服务
  • 内存淘汰策略的执行时机:Redis会在每一次处理命令的时候判断当前是否已经达到了内存的最大限制,如果达到限制,则使用对应的算法去处理需要删除的key
    • 配置Redis:redis.conf     maxmemory 10240000   maxmemory-policy noviction
  • 如何选择??
    • 如果拿redis做缓存,那应该使用allkeys下的淘汰策略
    • 如果你还想同时使用redis的持久化功能,那就是用volatile下的淘汰策略

如何解决频繁的命令往返造成的性能瓶颈

redis客户端和服务端的交互模型 

  • redis是基于一个request,一个response的同步请求服务
  • 数据包往返于两端的时间被称为RTT 

redis的pipeline的交互模型

  • 减少客户端与服务端通信的次数
  • pipeline是基于队列实现的,保证了先进先出

 

 调用redisTemplate.executePilelined方法.重写里面的RedisCallback<Object>里面的doInRedis方法,在该方法里面首选需要根据参数connection打开pipeline(connection.openPipeline),通过connection添加我们的命令.注意:不能关闭Pipeline,不然到最后我们得不到返回值,需要返回null

 Redis pipeline与原生批量命令对比

  • 原生批量命令是原子性,Pipeline是非原子性的 
  • 原生批量命令一次只能执行一种命令,Pipeline支持批量执行不同命令
  • 原生批量是服务端实现,Pipeline需要服务端和客户端共同完成
  • 需要注意的是:Redis事务具有隔离性,在执行过程中不会穿插其他客户端发送的命令

使用redis pipeline需要注意什么

  • 使用pipeline组装的命令个数不能太多,不然数据量过大

  • pipeline会按照缓冲的顺序执行,但是可能会穿插其他客户端发送来的命令,即时序性不能保证

  • pipeline执行中间某一个指令出现异常,将会继续执行后续的指令,即不能保证原子性 

配置好持节化机制

redis为什么需要持久化

  • 高并发场景只使用redis作为存储设备,需要保证数据不会丢失
  • 通常的应用场景虽然会同时把数据写入Mysql,但是直接从Mysql中恢复数据性能低下,且确实选择性(不知道之前的redis存储的数据,是选择哪些恢复还是全部恢复)

RDB

详细的介绍可以点击这里查看

 RDB持久化触发原理

手动触发

定时触发

AOF的持久化配置

 AOF重写

 从持久化中恢复数据

 企业级的恢复策略

 

缓存穿透隐患

通用的业务存储架构

缓存穿透的含义以及带来的影响

 怎么解决缓存穿透

出现缓存雪崩怎么办

为什么会出现缓存雪崩

缓存雪崩会带来什么问题

 怎么解决缓存雪崩 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于 Redis 的过期回调,你可能会遇到一些。以下是一些常见的问题和解决方法: 1. 过期回调不触发:如果设置了过期时间,并且配置了过期回调函数,但回调函数没有被触发,可能是由于以下原因: - Redis 的 keyspace notifications 没有开启。可以通过配置文件或者使用 `CONFIG SET notify-keyspace-events` 命令来进行设置。 - 过期键的回调事件被禁用。可以通过配置文件或者使用 `CONFIG SET notify-keyspace-events` 命令来进行设置。 2. 回调函数执行的时间限制:Redis 对于过期回调函数有一个执行时间限制,默认是 100 毫秒。如果回调函数执行时间超过此限制,可能会被中断。为了免此问题,可以将回调函数的逻辑简化,或者将复杂的处理逻辑转移到其他地方。 3. 回调函数的线程安全性:Redis 的过期回调函数是在主线程中运行的,所以要确保回调函数是线程安全的。需要考虑多线程并发访问共享资源时可能出现的竞争条件和数据一致性问题。 4. 回调函数的执行顺序:当多个键同时过期时,无法保证回调函数的执行顺序。如果需要按照某种顺序执行回调函数,可以在回调函数中添加额外的逻辑或者使用其他方法来进行控制。 5. 回调函数的效率:过期回调函数在 Redis 主线程中执行,可能会影响 Redis 的响应速度。如果回调函数执行时间过长或者频繁触发回调导致性能问题,可以考虑优化回调函数的逻辑或者使用其他解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值