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 ...]