事务
redis中事务的特性
- redis中事务并不能保证所有的命令都会执行成功,执行结果取决于事务中的命令。
- 在发送exec之前所有命令都会被放在一个队列中缓存起来,不会立即执行。
- 在收到exec命令之后事务开始执行,事务中任何一个事务执行失败,其他事务仍能够执行。
- 在事务执行过程中,其他客户端提交的命令请求,并不会被插入到事务的执行队列中。
redis中的事务作用
批量执行命令,在多个客户端链接一个服务端的情况下,避免一个客户端执行的命令之间插入了其他客户端的命令。保证客户端的安全性。
multi开启事务
exec/discard执行/取消事务
实例:
redis
127.0.0.1:6379(TX)> set k1 1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> set k3 3
QUEUED
127.0.0.1:6379(TX)> incr k1
QUEUED
127.0.0.1:6379(TX)> incr k2
QUEUED
127.0.0.1:6379(TX)> incr k3
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) OK
3) OK
4) (integer) 2
5) (error) ERR value is not an integer or out of range
6) (integer) 4
持久化
持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失
数据存放于:
内存:高效、断电(关机)内存数据会丢失
磁盘:读写速度慢于内存,断电数据不会丢失
rdb方式(默认)
服务器正常使用shutdown关闭时会保存快照
-
可以在redis.conf中修改配置来自动保存快照**(常用)**
相关配置文件中: # save "" # # Unless specified otherwise, by default Redis will save the DB: # * After 3600 seconds (an hour) if at least 1 change was performed # * After 300 seconds (5 minutes) if at least 100 changes were performed # * After 60 seconds if at least 10000 changes were performed # # You can set these explicitly by uncommenting the following line. # # save 3600 1 300 100 60 10000 -
save:手动保存快照
保存后在linux中可以使用xxd命令来查看rdb的内容,找到快照
save保存时redis是阻塞的,不能接受任何请求
- bgsave:创建一个子进程来保存快照
由于快照方式是在一定间隔时间做一次,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。如果应用要求不能丢失任何修改的话,可以采用aof持久化方式。
aof方式
**原理:**执行写命令的时候,不仅会将命令写到内存中,还会将命令写入到一个追加的文件(aof文件)中。当redis重启时会重新执行aof文件中的命令来重建整个数据库的内容。
每当执行服务器任务或者函数时,flushappendonlyfile函数都会被调用,这个函数执行以下两个工作aof写入保存:
write:根据条件,将aof_buf中的缓存写入到aof文件。
save:根据条件,调用fsync或fdatasync函数,将aof文件保存到磁盘中。
**开启aof方式:**在redis.conf配置文件中将appendonly改为yes
有三种方式:
- appendfsync always:收到命令就立即写入磁盘。最慢,但是保证完全持久化。
- appendfsynceverysec:每秒写入磁盘一次。在性能和持久化方面做了很好的折中。
- appendfsync no:完全依赖os。性能最好,持久化没保证。
混合持久化
其实混合持久化是AOF的一个功能,只有在开启AOF后才可能生效。默认情况下Redis使用RDB持久化,混合持久化并不单独存在。
过期策略
-
惰性过期:
当客户端尝试访问某个键时,redis会先检查该键是否设置了过期时间,并判断是否过期。
如果键已经过期,则redis会立即将其删除。这就是惰性删除策略。
**优点:**可以最大化的节省CPU资源。
**缺点:**极端情况可能出现大量过期的key没有被再次访问,从而没有被清除,占用了大量内存。
-
定期过期:
redis会每隔一段时间(默认100毫秒)随机检查一部分设置了过期时间的键。
定期过期策略通过使用循环遍历方式,逐个检查键是否过期,并删除已过期的键值对。
通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同的情况下使得CPU和内存资源达到最优的平衡效果。
redis中同时使用了惰性过期和定期过期两种过期策略。
假设redis当前存放20w个key,并且都设置了过期时间,如果你每隔100ms就去检查这部分key,cpu的负载会特别高,最后可能会挂掉。
因此redis采用的定期过期 ,每隔100ms就随机 抽取一定数量的key来检查和删除。
但是,仍可能有很多过期的key没被删除。这时候就采用惰性过期来删除。
尽管如此,仍可能有一些过期的key躲过了定期过期的删除,也没有被惰性过期删除,从而积在内存中。最终可能导致内存溢出。
为了解决这个问题,redis引入了内存淘汰策略进行优化,这里不再多说。