redis进阶

事务

redis事务就是一个命令执行的队列,将一系列预定义命令包装成一个整体(一个队列),当执行时,一次性按照添加顺序依次执行,中间不会被打断或者干扰。

一个队列中,一次性,顺序性,排他性的执行一系列命令

基本操作

  • 开启事务:  multi   设定事务开启的位置,此指令执行后,后续所有指令均加入到事务中
  • 执行事务:exec  设定事务的结束位置,同时执行事务,与multi成对出现,成对使用
  • 取消事务:discard  停止当前事务的定义,发生在nulit之后,exec之前

加入事务的命令暂时进入到任务队列中,并没有立即执行,只有执行exec命令才开始执行

1.redis 不支持回滚“Redis 在事务失败时不进行回滚,而是继续执行余下的命令”, 所以 Redis 的内部可以保持简单且快速。
2.如果在一个事务中的**命令**出现错误,那么**所有的命令**都不会执行;
3.如果在一个事务中出现**运行错误**,那么**正确的命令**会被执行。
注:redis的discard只是结束本次事务,正确命令造成的影响仍然存在.

分布式锁

1.监控数据是否发生变化  ---- 补货

  • 对key添加监视锁,在执行exec前如果key发生了变化,终止事务执行
    • watch  key1  [key2]......
  • 取消对所有key的监视
    • unwatch

2.分布式锁 ---- 超卖

  • 使用setnx设置一个公共锁      setnx lock-key val
    • 无值返回true设置成功,有值返回false设置失败
    •  返回成功的,拥有控制权,进行下一步具体业务操作
    • 返回失败,不具有控制权,排队或者等待
  • delete  lock-key :删除key -- 不删会导致死锁
  • expire lock-key  second:为key设置一个超时时间,单位为second,超过这个时间锁会自动释放,避免死锁。
  • pexpire lock-key  milliseconds    毫秒
    • 由于操作通常是微秒或毫秒级,因此该锁定时间不宜设置过大,具体时间需要业务测试后确定
      • 锁时间设定推荐:最大耗时*120% + 平均网络延迟*110%
      • 如果业务最大耗时:网络平均延迟,通常为2个数量级,取其中单个耗时较长即可
  • NX 互斥
    • 确保只有一个线程获取锁 
    • 非阻塞:尝试一次,成功返回true,失败返回false
    • set  lock  thread1  NX EX 10    添加锁thread1  ,NX互斥,EX设置超时时间

 

删除策略

数据状态

redis是一种内存级数据库,所有数据均存放在内存中,内存中的数据可以通过ttl指令获取其状态

  • XX:具有时效性的数据
  • -1:永久有效的数据
  • -2:已经过期的数据或 被删除的数据 或 未定义的数据

删除策略

在内存占用与cpu之间寻找一种平衡,顾此失彼都会造成整体reids性能下降,甚至引发服务器宕机或内存泄露

定时删除

创建一个定时器,当key设置有过期时间,到达过期时间,立即执行对键的删除操作

  • 优点:节约内存,到时就删除,快速释放掉不必要的内存占用
  • 缺点:CPU压力很大,无论CPU此时负载量多高,均占用CPU,会影响redis服务器响应时间和指令吞吐量
  • 总结:用处理器性能换取存储空间(拿时间换空间)

惰性删除

只有当访问一个key时,才会判断该key是否过期,,过期就删除。极端情况下可能会出现大量的过期key没有被再次访问,从而不会被清除,占用大量的内存。

  • 优点:节约CPU性能,发现必须删除的时候才韶除
  • 缺点:内存压力很大,出现长期占用内存的数据
  • 总结:用存储空间换取处理器性能〔拿时间换空间)

定期删除

 周期性轮询redis库中时效性数据,采用随机抽取的策略,利用过期数据占比的方式控制删除频度

  • redis启动服务器初始化时,读取配置文件 server.hz的值,默认为10
  • 每秒执行server.hz次 serverCron()-----> databasesCron()---->activeExpireCycle()
  • activeExpireCycle()对每一个expires[*]逐一进行检测,每次执行250ms/server.hz
  • 对某一个expires[*]检测时,随机挑选W个key检测
    • 如果key超时,删除key
    • 如果一轮中删除的key的数量>W*25%,循环该过程
    • 如果一轮中删除的key的数量<=W*25%,检查下一个expires[*],0-15循环
    • W取值=ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP属性值
  • 参数值current_db用于记录activeExpireCycle()进入哪个expires[*]执行
  • 如果activeExpireCycle()执行时间到期,下次current_db继续向下执行

特点1: CPU性能占用设置有峰值,检测频度可自定义设置

特点2:内存压力不是很大,长期占用内存的冷数据会被持续清理

总结:周期性抽查存储空间(随机抽查,重点抽查)

逐出算法

在 redis 添加数据时,会进行检测内存是否不足(freeMemorylfNeeded())。内存不足的情况下,就需要临时删除一些数据,为新的数据腾出内存空间。这种方法被称为 “逐出算法”

逐出算法并不能保证百分百清理出足够的可使用的内存空间,如果不成功则反复执行。在对所有数据都尝试后,内存还是不足则抛出异常。

相关配置

  • maxmemory 最大可使用内存 
    • 占用物理内存的比例,默认值为0,表示不受限制,生产环境中根据需求设定,通常设置在50%以上
  • maxmemory-samples: 每次选取待删除数据的数量。

    • 选取数据时并不会全库扫描,导致严重的性能消耗,降低读写性能。因此采取随机获取数据的方式作为待检测删除数据
  • maxmemory-policy: 删除策略,也就是逐出算法。

    • 达到最大内存后对被挑选出来的数据进行删除策略

逐出策略

  • 时效性易失数据

    • volatile-lru: 删除最近时间内最少使用的时效性数据,也就是最久没有使用的数据。

    • volatile-lfu: 删除使用使用次数最少的时效性数据

    • volatile-ttl: 删除时效性马上过期数据

    • volatile-random: 随机删除时效性数据

  • 全库数据

    • allkeys-lru: 删除全库中最近时间内最少使用的数据,也就是最久没有使用的数据。

    • allkeys-lfu: 删除全库中使用次数最少的数据

    • allkeys-random: 随机删除全库中的数据

  • 不处理

    • noeviction:禁止自动删除数据。也就是 4.0 中的默认策略。拒绝所有写入操作并返回客户端错误信息“(error)OOM command not allowed when used memory”,此时redis只响应读操作。

淘汰算法LRU和LFU区别

LRU:最近最少使用,淘汰很久没有访问过的数据,以最近一次访问时间作为参考

LFU:最不经常使用,淘汰最近一段时间被访问次数最少的数据,以次数作为参考

绝大多数情况下,我们使用LRU策略,当存在大量热点缓存数据时,LFU可能更好 

主从复制

三高:高可用,高并发,高性能

高可用:可用性= 全年时间-宕机时间/ 全年时间*100%

业界可用性目标5个9,即99.999%,即服务器年宕机时长低于315秒,约5.25分钟

主从复制就是将master中的数据及时,有效的复制到slave中。一个master可以拥有多个slave,一个slave只对应一个master

作用

读写分离:master写,slave读,提高服务器的读写负载能力

负载均衡:基于主从结构,配合读写分离,由slave分担master负载,并根据需求的变化,改变slave的数量,通过多个从节点分担数据读取负载,大大提高Redis服务器并发量和数据吞吐量

故障恢复:当master出现问题时,由slave提高服务,实现快速的故障恢复

数据冗余:实现数据热备份,是持久化之外的一种数据冗余方式

高可用基石:基于主从复制,构建哨兵模式与集群,实现Redis的高可用方案

流程

建立连接

数据同步

命令传播

 

posted @ 2023-02-05 18:06  早日月薪五万  阅读(17)  评论(0编辑  收藏  举报