文章目录
Reids
1.redis持久化
1-1 持久化简介
什么是持久化?
利用永久性存储介质将数据进行保存,在特定的时间将保存的数据进行恢复的工作机制称为持久化。
为什么要进行持久化?
防止数据的意外丢失,确保数据安全性
持久化过程保存什么?
- 将当前数据状态进行保存,快照形式,存储数据结果,存储格式简单,关注点在数据 (RDB)
- 将数据的操作过程进行保存,日志形式,存储操作过程,存储格式复杂,关注点在数据的操作过程(AOF)
1-2 RDB
1-2-1 save
save指令:
-
命令:
save
-
作用:手动执行一次保存操作
save指令相关配置:
-
dbfilename dump.rdb
- 说明:设置本地数据库文件名,默认值为
dump.rdb
- 经验:通常设置为
dump-端口号.rdb
- 说明:设置本地数据库文件名,默认值为
-
dir
- 说明:设置存储
.rdb
文件的路径 - 经验:通常设置成存储空间较大的目录中,目录名称
data
- 说明:设置存储
-
rdbcompression yes
- 说明:设置存储至本地数据库时是否压缩数据,默认为 yes,采用 LZF 压缩
- 经验:通常默认为开启状态,如果设置为no,可以节省 CPU 运行时间,但会使存储的文件变大(巨大)
-
rdbchecksum yes
- 说明:设置是否进行RDB文件格式校验,该校验过程在写文件和读文件过程均进行
- 经验:通常默认为开启状态,如果设置为no,可以节约读写性过程约10%时间消耗,但是存储一定的数据损坏风险
save指令工作原理:
注意:save指令的执行会阻塞当前Redis服务器,直到当前RDB过程完成为止,有可能会造成长时间阻塞,线上环境不建议使用。
1-2-2 bgsave
bgsave指令:
-
命令:
bgsave
-
作用:手动启动后台保存操作,但不是立即执行
bgsave指令工作原理:
注意: bgsave命令是针对save阻塞问题做的优化。Redis内部所有涉及到RDB操作都采用bgsave的方式,save命令可以放弃使用,推荐使用bgsave
bgsave指令相关配置:
dbfilename dump.rdb
dir
rdbcompression yes
rdbchecksum yes
-
stop-writes-on-bgsave-error yes
- 说明:后台存储过程中如果出现错误现象,是否停止保存操作
- 经验:通常默认为开启状态
1-2-3 相关配置
RDB启动方式——save配置:
-
配置:
save second changes
-
作用:满足限定时间范围内key的变化数量达到指定数量即进行持久化
-
参数:
- second:监控时间范围
- changes:监控key的变化量
-
位置:在conf文件中进行配置
RDB启动方式——save配置原理:
注意:
- save配置要根据实际业务情况进行设置,频度过高或过低都会出现性能问题,结果可能是灾难性的
- save配置中对于second与changes设置通常具有互补对应关系(一个大一个小),尽量不要设置成包含性关系
- save配置启动后执行的是bgsave操作
RDB特殊启动形式:
-
全量复制:在后面的主从复制在详细讲解
-
服务器运行过程中重启:
debug reload
-
关闭服务器时指定保存数据:
shutdown save
默认情况下执行shutdown命令时,自动执行 bgsave(如果没有开启AOF持久化功能)
1-2-4 RDB优缺点
优点:
- RDB是一个紧凑压缩的二进制文件,存储效率较高
- RDB内部存储的是redis在某个时间点的数据快照,非常适合用于数据备份,全量复制等场景
- RDB恢复数据的速度要比AOF快很多
- 应用:服务器中每X小时执行bgsave备份,并将RDB文件拷贝到远程机器中,用于灾难恢复
缺点:
- RDB方式无论是执行指令还是利用配置,无法做到实时持久化,具有较大的可能性丢失数据
- bgsave指令每次运行要执行fork操作创建子进程,要牺牲掉一些性能
- Redis的众多版本中未进行RDB文件格式的版本统一,有可能出现各版本服务之间数据格式无法兼容现象
1-2-5 RDB两种启动方式对比
1-3 AOF
1-3-1 概述
AOF概念:
- AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中命令,以达到恢复数据的目的。与RDB相比可以简单描述为改记录数据为记录数据产生的过程
- AOF的主要作用:是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式
AOF写数据过程:
1-3-2 AOF写数据三种策略
-
always:
- 每次写入操作均同步到AOF文件中,数据零误差,性能较低,不建议使用
-
everysec:
- 每秒将缓冲区中的指令同步到AOF文件中,数据准确性较高,性能较高 ,建议使用,也是默认配置
- 在系统突然宕机的情况下丢失1秒内的数据
-
no:
- 由操作系统控制每次同步到AOF文件的周期,整体过程不可控
1-3-3 相关操作
AOF功能开启:
-
配置
appendonly yes|no
作用:是否开启AOF持久化功能,默认为不开启状态
-
配置
appendfsync always|everysec|no
作用:AOF写数据策略
AOF相关配置:
-
配置
appendfilename filename
作用:AOF持久化文件名,默认文件名未
appendonly.aof
,建议配置为appendonly-端口号.aof
-
配置
dir
作用:AOF持久化文件保存路径,与RDB持久化文件保持一致即可
1-3-4 重写
AOF重写:随着命令不断写入AOF,文件会越来越大,为了解决这个问题,Redis引入了AOF重写机制压缩文件体积。AOF文件重写是将Redis进程内的数据转化为写命令同步到新AOF文件的过程。简单说就是将对同一个数据的若干个条命令执行结果转化成最终结果数据对应的指令进行记录。
AOF重写作用:
- 降低磁盘占用量,提高磁盘利用率
- 提高持久化效率,降低持久化写时间,提高IO性能
- 降低数据恢复用时,提高数据恢复效率
AOF重写规则:
- 进程内已超时的数据不再写入文件
- 忽略无效指令,重写时使用进程内数据直接生成,这样新的AOF文件只保留最终数据的写入命令
- 如del key1、 hdel key2、srem key3、set key4 111、set key4 222等
- 对同一数据的多条写命令合并为一条命令
- 如lpush list1 a、lpush list1 b、 lpush list1 c 可以转化为:lpush list1 a b c
- 为防止数据量过大造成客户端缓冲区溢出,对list、set、hash、zset等类型,每条指令最多写入64个元素
AOF重写方式:
-
手动重写
bgrewriteaof
-
自动重写
//触发重写的最小大小 auto-aof-rewrite-min-size size //触发重写须达到的最小百分比 auto-aof-rewrite-percentage percentage
1-4 RDB与AOF区别
RDB与AOF的选择之惑:
- 对数据非常敏感,建议使用默认的AOF,持久化方案:
- AOF持久化策略使用everysecond,每秒钟fsync一次。该策略redis仍可以保持很好的处理性能,当出现问题时,最多丢失0-1秒内的数据。
- 注意:由于AOF文件存储体积较大,且恢复速度较慢
- 数据呈现阶段有效性,建议使用RDB持久化方案
- 数据可以良好的做到阶段内无丢失(该阶段是开发者或运维人员手工维护的),且恢复速度较快,阶段点数据恢复通常采用RDB方案
- 注意:利用RDB实现紧凑的数据持久化会使Redis降的很低
- 综合比对
- RDB与AOF的选择实际上是在做一种权衡,每种都有利有弊
- 如不能承受数分钟以内的数据丢失,对业务数据非常敏感,选用AOF
- 如能承受数分钟以内的数据丢失,且追求大数据集的恢复速度,选用RDB
- 灾难恢复选用RDB
- 双保险策略,同时开启 RDB 和 AOF,重启后,Redis优先使用 AOF 来恢复数据,降低丢失数据
2.redis事务
2-1 事务简介
redis事务就是一个命令执行的队列,将一系列预定义命令包装成一个整体(一个队列)。当执行时,一次性按照添加顺序依次执行,中间不会被打断或者干扰
一个队列中,一次性、顺序性、排他性的执行一系列命令
2-2 事务基本操作
-
开启事务:
multi
作用:设定事务的开启位置,此指令执行后,后续的所有指令均加入到事务中
-
取消事务:
discard
作用:终止当前事务的定义,发生在multi之后,exec之前
-
执行事务:
exec
作用:设定事务的结束位置,同时执行事务。与multi成对出现,成对使用
事务操作的基本流程:
2-3 事务的注意事项
定义事务的过程中,命令格式输入错误怎么办?
- 语法错误
- 指命令书写格式有误。例如执行了一条不存在的指令
- 处理结果
- 如果定义的事务中所包含的命令存在语法错误,整体事务中所有命令均不会执行。包括那些语法正确的命令
定义事务的过程中,命令执行出现错误怎么办?
- 运行错误
- 指命令格式正确,但是无法正确的执行。例如对list进行incr操作
- 处理结果
- 能够正确运行的命令会执行,运行错误的命令不会被执行
注意:已经执行完毕的命令对应的数据不会自动回滚,需要程序员自己在代码中实现回滚。
2-4 锁
基于特定条件的事务执行——锁:
-
对 key 添加监视锁,在执行exec前如果key发生了变化,终止事务执行
watch key1, key2....Copy
-
取消对所有key的监视
unwatch
基于特定条件的事务执行——分布式锁:
-
使用 setnx 设置一个公共锁
//上锁 setnx lock-key value //释放锁 del lock-keyCopy
利用setnx命令的返回值特征,有值则返回设置失败,无值则返回设置成功
- 对于返回设置成功的,拥有控制权,进行下一步的具体业务操作
- 对于返回设置失败的,不具有控制权,排队或等待操作完毕通过del操作释放锁
注意:上述解决方案是一种设计概念,依赖规范保障,具有风险性
基于特定条件的事务执行——分布式锁改良:
-
使用 expire 为锁key添加时间限定,到时不释放,放弃锁
expire lock-key seconds pexpire lock-key millisecondsCopy
-
由于操作通常都是微秒或毫秒级,因此该锁定时间不宜设置过大。具体时间需要业务测试后确认。
- 例如:持有锁的操作最长执行时间127ms,最短执行时间7ms。
- 测试百万次最长执行时间对应命令的最大耗时,测试百万次网络延迟平均耗时
- 锁时间设定推荐:最大耗时120%+平均网络延迟110%
- 如果业务最大耗时<<网络平均延迟,通常为2个数量级,取其中单个耗时较长即可
3.删除策略
3-1 Redis中的数据特征
Redis是一种内存级数据库,所有数据均存放在内存中,内存中的数据可以通过TTL指令获取其状态
- XX :具有时效性的数据
- -1 :永久有效的数据
- -2 :已经过期的数据 或 被删除的数据 或 未定义的数据
3-2 数据删除策略
- 定时删除
- 惰性删除
- 定期删除
时效性数据的存储结构:
Redis中的数据,在expire中以哈希的方式保存在其中。其value是数据在内存中的地址,filed是对应的生命周期
数据删除策略的目标:
在内存占用与CPU占用之间寻找一种平衡,顾此失彼都会造成整体redis性能的下降,甚至引发服务器宕机或内存泄露
定时删除:
- 创建一个定时器,当key设置有过期时间,且过期时间到达时,由定时器任务立即执行对键的删除操作
- 优点:节约内存,到时就删除,快速释放掉不必要的内存占用
- 缺点:CPU压力很大,无论CPU此时负载量多高,均占用CPU,会影响redis服务器响应时间和指令吞吐量
- 总结:用处理器性能换取存储空间 (拿时间换空间)
惰性删除:
- 数据到达过期时间,不做处理。等下次访问该数据时
- 如果未过期,返回数据
- 发现已过期,删除,返回不存在
- 优点:节约CPU性能,发现必须删除的时候才删除
- 缺点:内存压力很大,出现长期占用内存的数据
- 总结:用存储空间换取处理器性能 (拿空间换时间)
定期删除:
- 周期性轮询redis库中的时效性数据,采用随机抽取的策略,利用过期数据占比的方式控制删除频度
- 特点1:CPU性能占用设置有峰值,检测频度可自定义设置
- 特点2:内存压力不是很大,长期占用内存的冷数据会被持续清理
- 总结:周期性抽查存储空间 (随机抽查,重点抽查)
删除策略对比:
3-3 逐出算法
当新数据进入redis时,如果内存不足怎么办 ?
- Redis使用内存存储数据,在执行每一个命令前,会调用freeMemoryIfNeeded()检测内存是否充足。如果内存不满足新加入数据的最低存储要求,redis要临时删除一些数据为当前指令清理存储空间。清理数据的策略称为逐出算法
- 注意:逐出数据的过程不是100%能够清理出足够的可使用的内存空间,如果不成功则反复执行。当对所有数据尝试完毕后,如果不能达到内存清理的要求,将出现错误信息。
影响数据逐出的相关配置:
-
最大可使用内存
maxmemoryCopy
占用物理内存的比例,默认值为0,表示不限制。生产环境中根据需求设定,通常设置在50%以上。
-
每次选取待删除数据的个数
maxmemory-samplesCopy
选取数据时并不会全库扫描,导致严重的性能消耗,降低读写性能。因此采用随机获取数据的方式作为待检测删除数据
-
删除策略
maxmemory-policyCopy
达到最大内存后的,对被挑选出来的数据进行删除的策略
影响数据逐出的相关配置:
LRU:最长时间没被使用的数据
LFU:一段时间内使用次数最少的数据
数据逐出策略配置依据:
-
使用INFO命令输出监控信息,查询缓存 hit 和 miss 的次数,根据业务需求调优Redis配置
5.高级数据类型
5-1 Bitmaps
基础操作:
-
获取指定key对应偏移量上的bit值:
getbit key offset
-
设置指定key对应偏移量上的bit值,value只能是1或0:
setbit key offset value
扩展操作:
-
对指定key按位进行交、并、非、异或操作,并将结果保存到destKey中
bitop op destKey key1 [key2...]Copy
- and:交
- or:并
- not:非
- xor:异或
-
统计指定key中1的数量
bitcount key [start end]
5-2 HyperLogLog
基数:
- 基数是数据集去重后元素个数
- HyperLogLog 是用来做基数统计的,运用了LogLog的算法
基本操作:
-
添加数据
pfadd key element1, element2...
-
统计数据
pfcount key1 key2....
-
合并数据
pfmerge destkey sourcekey [sourcekey...]
相关说明:
- 用于进行基数统计,不是集合,不保存数据,只记录数量而不是具体数据
- 核心是基数估算算法,最终数值存在一定误差
- 误差范围:基数估计的结果是一个带有 0.81% 标准错误的近似值
- 耗空间极小,每个hyperloglog key占用了12K的内存用于标记基数
- pfadd命令不是一次性分配12K内存使用,会随着基数的增加内存逐渐增大
- Pfmerge命令合并后占用的存储空间为12K,无论合并之前数据量多少
5-3 GEO
基本操作:
-
添加坐标点
geoadd key longitude latitude member [longitude latitude member ...] georadius key longitude latitude radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count]Copy
-
获取坐标点
geopos key member [member ...] georadiusbymember key member radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count]Copy
-
计算坐标点距离
geodist key member1 member2 [unit] geohash key member [member ...]
最后喜欢的小伙伴,记得三联哦!