Redis学习笔记(四):Redis事务、锁(Watch,setnx)、删除策略、核心配置、高级数据类型(Bitmap、HyperLogLog、GEO)

Redis 事务

事务简介

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

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

事务的基本操作

1、开启事务 :设定事务的开启位置,此指令执行后,后续的所有指令均加入到事务中

 multi 

2、执行事务 :设定事务的结束位置,同时执行事务。与multi成对出现,成对使用

exec

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

3、取消事务 :终止当前事务的定义,发生在multi之后,exec之前

discard

事务的工作流程

在这里插入图片描述

事务的注意事项

定义事务的过程中,出现下面的问题

1、语法错误: 指命令书写格式有误

处理结果 :如果定义的事务中所包含的命令存在语法错误,整体事务中所有命令均不会执行。包括那些语法正确的命令。 并且需要从新输入multi开启事务

2、运行错误: 指命令格式正确,但是无法正确的执行。例如对list进行incr操作

​ 处理结果 能够正确运行的命令会执行,运行错误的命令不会被执行

注意:已经执行完毕的命令对应的数据不会自动回滚,需要程序员自己在代码中实现回滚

手动进行事务回滚
  • 记录操作过程中被影响的数据之前的状态

    • 单数据:string
    • 多数据:hash、list、set、zset
  • 设置指令恢复所有的被修改的项

    • 单数据:直接set(注意周边属性,例如时效)
    • 多数据:修改对应值或整体克隆复制

一、Watch

对 key 添加监视锁,在执行exec前如果key发生了变化,终止事务执行

watch key1 [key2……] 

取消对所有 key 的监视

unwatch

应用场景:redis 应用基于状态控制的批量任务执行

例如:对已经售罄的货物追加补货,4个业务员都有权限进行补货。补货的操作可能是一系 列的操作,牵扯到多个连续操作,如何保障不会重复操作?

业务分析 :

  • 多个客户端有可能同时操作同一组数据,并且该数据一旦被操作修改后,将不适用于继续操作
  • 在操作之前锁定要操作的数据,一旦发生变化,终止当前操作

二、分布式锁setnx

使用 setnx 设置一个公共锁

 setnx lock-key value #例:setnx lock-name 1

利用setnx命令的返回值特征,有值则返回设置失败,无值则返回设置成功

  • 对于返回设置成功的,拥有控制权,进行下一步的具体业务操作
  • 对于返回设置失败的,不具有控制权,排队或等待

注意:**setnx并不是和数据库那样的直接给key加上锁,而是使用setnx lock-key value生成一个锁(lock-key),别的客户端需要操作key时,先setnx lock-key value,如果返回1说明没加所可以操作,如果返回0说明可以已经加锁,需要等待。**上述解决方案是一种设计概念,依赖规范保障,具有风险性

操作完毕通过del操作释放锁

del lock-key #例:dellock-name

需求分析

  • 由于锁操作由用户控制加锁解锁,必定会存在加锁后未解锁的风险
  • 需要解锁操作不能仅依赖用户控制,系统级别要给出对应的保底处理方案

使用 expire 为锁key添加时间限定,到时不释放,放弃锁

expire lock-key second 
pexpire lock-key milliseconds 

由于操作通常都是微秒或毫秒级,因此该锁定时间不宜设置过大。具体时间需要业务测试后确认。

  • 例如:持有锁的操作最长执行时间127ms,最短执行时间7ms。
  • 测试百万次最长执行时间对应命令的最大耗时,测试百万次网络延迟平均耗时
  • 锁时间设定推荐:最大耗时120%+平均网络延迟110%
  • 如果业务最大耗时<<网络平均延迟,通常为2个数量级,取其中单个耗时较长即可

Redis 删除策略

过期数据

Redis是一种内存级数据库,所有数据均存放在内存中,可以使用expire指令设置其有效期,内存中的数据可以通过TTL指令获取其状态

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

数据删除策略

时效性数据的存储结构 :

在这里插入图片描述

数据删除策略的目标:在内存占用与CPU占用之间寻找一种平衡,顾此失彼都会造成整体redis性能的下降,甚至引发服务器宕机或 内存泄露

定时删除(到期立即删除)

在这里插入图片描述

惰性删除 (过期后,get时才删除)

在这里插入图片描述

定期删除 (随机抽查,重点抽查)

在这里插入图片描述
定期删除特点:

  • 周期性轮询redis库中的时效性数据,采用随机抽取的策略,利用过期数据占比的方式控制删除频度
  • CPU性能占用设置有峰值,检测频度可自定义设置
  • 内存压力不是很大,长期占用内存的冷数据会被持续清理
  • 总结:周期性抽查存储空间 (随机抽查,重点抽查)
删除策略比对

1、定时删除

  • 节约内存,无占用 ;内存占用严重 ;内存定期随机清理

2、 惰性删除

  • 不分时段占用CPU资源,频度高 ;延时执行,CPU利用率高 ;每秒花费固定的CPU资源维护内存

3、 定期删除

  • 拿时间换空间;拿空间换时间; 随机抽查,重点抽查

逐出算法

引入

当新数据进入redis时,如果内存不足怎么办?

  • Redis使用内存存储数据,在执行每一个命令前,会调用freeMemoryIfNeeded()检测内存是否充足。如 果内存不满足新加入数据的最低存储要求,redis要临时删除一些数据为当前指令清理存储空间。清理数据 的策略称为逐出算法。
  • 注意:逐出数据的过程不是一定能够清理出足够的可使用的内存空间,如果不成功则反复执行。当对所 有数据尝试完毕后,如果不能达到内存清理的要求,将出现错误信息。
    在这里插入图片描述
影响数据逐出的相关配置

1、最大可使用内存 : 占用物理内存的比例,默认值为0,表示不限制。生产环境中根据需求设定,通常设置在50%以上。

maxmemory

2、每次选取待删除数据的个数 : 选取数据时并不会全库扫描,导致严重的性能消耗,降低读写性能。因此采用随机获取数据的方式作为待检测删除数据

 maxmemory-samples

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

 maxmemory-policy

maxmemory-policy参数的相关取值

1、检测易失数据(可能会过期的数据集server.db[i].expires )

  • volatile-lru:挑选最近最少使用的数据淘汰
  • volatile-lfu:挑选最近使用次数最少的数据淘汰
  • volatile-ttl:挑选将要过期的数据淘汰
  • volatile-random:任意选择数据淘汰

2、检测全库数据(所有数据集server.db[i].dict )

  • allkeys-lru:挑选最近最少使用的数据淘汰
  • allkeys-lfu:挑选最近使用次数最少的数据淘汰
  • allkeys-random:任意选择数据淘汰

3、放弃数据驱逐

  • no-enviction(驱逐):禁止驱逐数据(redis4.0中默认策略),会引发错误OOM(Out Of Memory)

Redis 核心配置

服务器端设定

1、设置服务器以守护进程的方式运行 (后台运行)

daemonize yes|no 

2、 绑定主机地址

 bind 127.0.0.1 #绑定之后只能通过127.0.0.1访问

3、设置服务器端口号

 port 6379 

4、设置数据库数量

 databases 16 

日志配置

1、设置服务器以指定日志记录级别

 loglevel debug|verbose|notice|warning 

2、日志记录文件名

logfile 端口号.log 

注意:日志级别开发期设置为verbose即可,生产环境中配置为notice,简化日志输出量,降低写日志IO的频度

客户端配置

1、设置同一时间最大客户端连接数,默认无限制。当客户端连接到达上限,Redis会关闭新的连接

 maxclients 0 

2、客户端闲置等待最大时长,达到最大值后关闭连接。如需关闭该功能,设置为 0

timeout 300 

多服务器快捷配置

1、导入并加载指定配置文件信息,用于快速创建redis公共配置较多的redis实例配置文件,便于维护

 include /path/server-端口号.conf 

高级数据类型

Bitmaps

业务场景 :

  • 统计每天某一部电影是否被点播
  • 统计每天有多少部电影被点播
  • 统计每周/月/年有多少部电影被点播
  • 统计年度哪部电影没有被点播

业务分析 :使用每一位表示该电影是否被点播过

在这里插入图片描述

Bitmaps类型的操作 : 应用于信息状态统计

1、设置指定key对应偏移量上的bit值,value只能是1或0

setbit key offset value 

2、获取指定key对应偏移量上的bit值

 getbit key offset 

3、 对指定key按位进行交、并、非、异或操作,并将结果保存到destKey中

 bitop op destKey key1 [key2...] 
  • and:交
  • or:并
  • not:非
  • xor:异或

4、统计指定key中1的数量

 bitcount key [start end] 

HyperLogLog

HyperLogLog :应用于独立信息统计

基数 :

  • 基数是数据集去重后元素个数
  • HyperLogLog 是用来做基数统计的,运用了LogLog的算法
    在这里插入图片描述
    HyperLogLog类型的基本操作

1、添加数据

pfadd key element [element ...] 

2、统计数据

pfcount key [key ...] 

3、合并数据

 pfmerge destkey sourcekey [sourcekey...] 

相关说明:

  • 用于进行基数统计,不是集合,不保存数据,只记录数量而不是具体数据
  • 核心是基数估算算法,最终数值存在一定误差
  • 误差范围:基数估计的结果是一个带有 0.81% 标准错误的近似值
  • 耗空间极小,每个hyperloglog key占用了12K的内存用于标记基数
  • pfadd命令不是一次性分配12K内存使用,会随着基数的增加内存逐渐增大
  • Pfmerge命令合并后占用的存储空间为12K,无论合并之前数据量多少

GEO

GEO主要用于地理位置相关的计算

在这里插入图片描述

GEO类型的操作

1、添加坐标点

 geoadd key longitude latitude member [longitude latitude member ...] 

2、 获取坐标点

geopos key member [member ...] 

3、 计算坐标点距离

geodist key member1 member2 [unit]

4、 计算key中在指定的经纬度下一定距离的范围内有多少个点

georadius key longitude latitude radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count] 

5、计算key中在member一定距离的范围内有多少个点

georadiusbymember key member radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count] 

6、计算位置member的hash值

geohash key member [member ...] 

3、 计算坐标点距离

geodist key member1 member2 [unit]

4、 计算key中在指定的经纬度下一定距离的范围内有多少个点

georadius key longitude latitude radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count] 

5、计算key中在member一定距离的范围内有多少个点

georadiusbymember key member radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count] 

6、计算位置member的hash值

geohash key member [member ...] 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值