Redis之事务、发布订阅与持久化
一、Redis事物
Redis事务可以一次执行多个命令
Redis事物的重要保证:
1.事务是一个单独的隔离操作:
事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
2.事务是一个原子操作:
事务中的命令要么全部被执行,要么全部都不执行。
Redis事物的执行阶段
一个事务从开始到执行会经历以下三个阶段:
开始事务
命令入队
执行事务
Redis事务实例
Redis事物是以MULTI命令开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC命令触发事务, 一并执行事务中的所有命令。
事务命令
命令 | 描述说明 |
---|---|
DISCARD | 取消事务,放弃执行事务块内的所有命令。 |
EXEC | 执行所有事务块内的命令。 |
MULTI | 标记一个事务块的开始。 |
UNWATCH | 取消 WATCH 命令对所有 key 的监视。 |
WATCH key [key …] | 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。 |
事务命令使用示例
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set name1 redis1
QUEUED
127.0.0.1:6379> set name2 redis2
QUEUED
127.0.0.1:6379> set name3 redis3
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) OK
3) OK
127.0.0.1:6379> keys *
1) "name1"
2) "name2"
3) "name3"
127.0.0.1:6379>
二、Redis发布订阅
Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。Redis客户端可以订阅任意数量的频道。
发布订阅命令
命令 | 描述说明 |
---|---|
PSUBSCRIBE pattern [pattern …] | 订阅一个或多个符合给定模式的频道。 |
PUBSUB subcommand [argument [argument …]] | 查看订阅与发布系统状态。 |
PUBLISH channel message | 将信息发送到指定的频道。 |
PUNSUBSCRIBE [pattern [pattern …]] | 退订所有给定模式的频道。 |
SUBSCRIBE channel [channel …] | 订阅给定的一个或多个频道的信息。 |
UNSUBSCRIBE [channel [channel …]] | 指退订给定的频道。 |
发布订阅使用示例
订阅
SUBSCRIBE 订阅频道名称
127.0.0.1:6379> SUBSCRIBE channel-1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel-1"
3) (integer) 1
发布
PUBLISH 订阅频道名称 消息
D:\Program Files (x86)\Redis>redis-cli.exe
127.0.0.1:6379> PUBLISH channel-1 "hello"
(integer) 1
127.0.0.1:6379>
接收到消息
127.0.0.1:6379> SUBSCRIBE channel-1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel-1"
3) (integer) 1
1) "message"
2) "channel-1"
3) "hello"
三、Redis的持久化方式
A、RDB持久化
在指定的时间间隔能对数据进行快照,类似MySQL的dump备份文件。
Redis快照
快照就是把整个内存数据映射到硬盘中,保存一份到硬盘,因此恢复数据起来比较快,把数据映射回去即可,不像AOF需要一条一条的执行操作命令。
快照是默认的持久化方式,该方式就是将内存中的数据以快照的方式写入到二进制文件中,默认文件名dump.rdb。可通过配置文件设置自动做快照持久化的方式。
RDB是在某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化的文件,达到数据恢复。
产生快照的情况:
手动bgsave执行,该命令是非阻塞的
手动save执行,该命令是阻塞的
根据配置文件自动执行
客户端发送shutdown,系统会自动执行save命令阻塞客户端,然后关闭服务器
若是主从架构模式,从服务器向主服务器发送sync命令来执行复制操作时,主服务器会执行bgsave操作。
开启RDB
配置Redis在N秒内如果超过M个Key被修改则自动做快照,如果注释配置,则代表RDB禁用。
Redis默认的快照保存配置:
# 900秒内如果超过1个key改动,则发起快照保存
save 900 1
# 300秒内如果超过10个key改动,则发起快照保存
save 300 10
# 60秒内如果超过1W个key改动,则发起快照保存
save 60 10000
redis.conf
# 放行访问IP限制
bind 0.0.0.0
# 后台启动
daemonize yes
# 日志存储目录及日志文件名
logfile "/usr/local/program/redis/log/redis.log"
# 持久化数据存储在本地的文件名
dbfilename dump.rdb
# 持久化数据存储在本地的路径 rdb数据文件和aof数据文件存储目录
dir /usr/local/program/redis/data
# 设置密码
requirepass 123456
# 5秒内如果超过2个key改动,则发起快照保存
save 5 2
# 当snapshot时出现错误无法继续时,是否阻塞客户端“变更操作”,“错误”可能因为磁盘已满/磁盘故障/OS级别异常等
stop-writes-on-bgsave-error yes
# 是否启用rdb文件压缩,默认为yes,压缩往往意味着“额外的cpu消耗”,同时也意味这较小的文件尺寸以及较短的网络传输时间
rdbcompression yes
使用配置文件启动Redis
bin/redis-server conf/redis.conf
连接客户端
root@DESKTOP-3M0E60F:/usr/local/program/redis# bin/redis-cli -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379>
执行测试
在5秒内触发2次key的改动,发现快照执行成功,生成dump.rdb文件
root@DESKTOP-3M0E60F:/usr/local/program/redis# ll data
total 0
drwxr-xr-x 1 root root 4096 Jul 26 22:33 ./
drwxr-xr-x 1 root root 4096 Jul 26 21:48 ../
-rw-r--r-- 1 root root 102 Jul 26 22:33 dump.rdb
root@DESKTOP-3M0E60F:/usr/local/program/redis#
RDB的优缺点
优点:
紧凑压缩的二进制文件,恢复速度快
fork子进程性能最大化,使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了redis的高性能
启动效率高,紧凑的压缩二进制文件
缺点:
生产快照的时机问题,RDB是间隔一段时间进行持久化,如果持久化之间 redis发生故障,会发生数据丢失。更适合数据要求不严谨的时候
fork子进程的开销问题,数据集很大的情况,频繁fork子进程进行快照
B、AOF持久化
记录每次对服务器写的操作,当服务器重启的时候重新执行这些命令来恢复原始的数据,类似MySQL的binlog日志
将“操作 + 数据”以格式化指令的方式追加到操作日志文件的尾部,在append操作返回后(已经写入到文件或者即将写入),才进行实际的数据变更,“日志文件”保存了历史所有的操作过程;当 server 需要数据恢复时,可以直接 replay此日志文件,即可还原所有的操作过程。AOF相对可靠,它和 mysql中bin.log、apache.log、zookeeper 中 txn-log 简直异曲同工。AOF文件内容是字符串,非常容易阅读和解析。
AOF只追加文件,也就是每次处理完请求命令后都会将此命令追加到aof文件的末尾,而RDB是压缩程二进制等时机开子进程去做这件事。
优点:
可以保持更高的数据完整性,如果设置追加file的时间是1s,如果redis发生故障,最多会丢失1s的数据;且如果日志写入不完整支持 redis-check-aof来进行日志修复;AOF文件没被rewrite 之前(文件过大时会对命令进行合并重写),可以删除其中的某些命令(比如误操作的flushall)。
缺点:
AOF文件比RDB 文件大,且恢复速度慢。
可以简单的认为AOF就是日志文件,只会记录“变更操作”(如:set/del 等),如果server中持续的大量变更操作,将会导致 AOF文件非常的庞大,意味着server失效后,数据恢复的过程将会很长;事实上,一条数据经过多次变更,将会产生多条 AOF记录,其实只要保存当前的状态,历史的操作记录是可以抛弃的;因为AOF持久化模式还伴生了“AOF rewrite”。
AOF的特性决定了它相对比较安全,如果期望数据更少的丢失,那么可以采用AOF模式。如果AOF文件正在被写入时突然 server失效,有可能导致文件的最后一次记录是不完整,可以通过手工或者程序的方式去检测并修正不完整的记录,以便通过aof文件恢复能够正常;同时需要提醒,如果redis持久化手段中有aof,那么在server故障失效后再次启动前,需要检测 aof文件的完整性。
AOF 默认关闭,开启方法,修改配置文件 reds.conf:appendonly yes
开启AOF
Redis默认使用RDB持久化方式,AOF默认是关闭的
# 放行访问IP限制
bind 0.0.0.0
# 后台启动
daemonize yes
# 日志存储目录及日志文件名
logfile "/usr/local/program/redis/log/redis.log"
# 持久化数据存储在本地的文件名
dbfilename dump.rdb
# 持久化数据存储在本地的路径 rdb数据文件和aof数据文件存储目录
dir /usr/local/program/redis/data
# 设置密码
requirepass 123456
# aof功能开关,默认为no,关闭状态
appendonly yes
# 指定aof文件名称
appendfilename appendonly.aof
# 指定aof操作中文件同步策略,有三个合法值:always everysec no,默认为everysec
appendfsync everysec
# 在aof-rewrite期间,appendfsync是否暂缓文件同步,no:不暂缓,yes:暂缓,默认为no,
# 开启可以减轻文件重写时CPU和磁盘的负载,但可能会丢失AOF重写期间的数据,需在负载和安全中间平衡取舍
no-appendfsync-on-rewrite no
# aof文件rewrite触发的最小文件尺寸(mb,gb),只有大于此aof文件大于此尺寸是才会触发rewrite,默认“64mb”,建议“512mb”
# 当aof文件大于指定字节后才触发重写
auto-aof-rewrite-min-size 64mb
# 相对于上一次重写,本次rewrite触发时aof文件应该增长的百分比。
# 每一次rewrite之后,redis都会记录下此时“新aof”文件的大小(例如A),那么当aof文件增长到A*(1 + p)之后触发下一次rewrite,每一次aof记录的添加,都会检测当前aof文件的尺寸。
# 当写入日志文件大小超过上一次写入后的文件大小的百分之100时触发Rewrite
auto-aof-rewrite-percentage 100
# 如果AOF文件结尾损坏,Redis启动时是否仍然载入aof文件
aof-load-truncated yes
同步策略
Redis中提供了3种AOF同步策略
appendfsync everysec
每秒同步,默认方式,每秒同步一次,性能和安全都比较中庸的方式,也是redis 推荐的方式。如果遇到物理服务器故障,有可能导致最近一秒内aof记录丢失(可能为部分丢失)。everysec是最佳的选择
appendfsync always
每修改则同步,会极大削弱Redis的性能,每一条aof记录都立即同步到文件,这是最安全的方式,也带来更多的磁盘操作和阻塞延迟,IO开支较大。
appendfsync no
不主动同步,由操作系统自动调度,redis并不直接调用文件同步,而是交给操作系统来处理,操作系统可以根据buffer填充情况 / 通道空闲时间等择机触发同步;这是一种普通的文件操作方式。性能较好,在物理服务器故障时,数据丢失量会因OS配置有关。
写入与恢复
AOF文件是一个只进行append操作的日志文件,因此写入过程中如果出现宕机情况,也不会破坏日志中已存在内容。如果某一次操作只写入了一半数据就宕机了,可以再Redis下一次启动前,通过Redis-check-aof工具帮助修复问题。
AOF文是有序保存对数据库执行的所有写入操作,因此AOF文件内容易于被人读懂。
重写
Redis可以在AOF文件体积变得过大时,自动的在后台对AOF文件进行重写。也就是Redis以append方式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创建一个新文件用于记录此期间那些修改命令被执行。
因为Redis在创建新AOF文件过程中,会继续将命令追加到现有的AOF文件里,即使重写过程中发生宕机情况,现有AOF文件也不会丢失。
而一旦新AOF文件创建完毕,Redis就会从旧的AOF文件切换到新的AOF文件,并开始对新AOF文件进行追加操作。
AOF文件会不断增大,它的大小直接影响“故障恢复”的时间, 而且AOF文件中历史操作是可以丢弃的。
AOF重写操作就是“压缩”AOF 文件的过程,当然redis并没有采用“基于原aof 文件”来重写的方式,而是采取了类似snapshot的方式:基于 copy-on-write,全量遍历内存中数据,然后逐个序列到aof 文件中。因此 AOF重写能够正确反应当前内存数据的状态,这正是所需要的;
重写过程中,对于新的变更操作将仍然被写入到原 AOF 文件中,同时这些新的变更操作也会被 redis 收集起来(buffer,copy-on-write 方式下,最极端的可能是所有的 key 都在此期间被修改,将会耗费 2 倍内存),当内存数据被全部写入到新的 aof 文件之后,收集的新的变更操作也将会一并追加到新的aof文件中,此后将会重命名新的aof文件为 appendonly.aof, 此后所有的操作都将被写入新的 aof 文件。
如果在 rewrite 过程中,出现故障,将不会影响原AOF文件的正常工作,只有当 rewrite完成之后才会切换文件,因为rewrite过程是比较可靠的。
触发rewrite的时机可以通过配置文件来声明,同时 redis中可以通过 bgrewriteaof 指令人工干预。因为rewrite操作aof记录同步snapshot都消耗磁盘 IO,redis 采取了“schedule”策略:无论是“人工干预”还是系统触发,snapshot 和rewrite需要逐个被执行。AOF rewrite 过程并不阻塞客户端请求。系统会开启一个子进程来完成。
AOF优缺点
优点:
数据不易丢失,每秒记录命令与数据
自动重写机制,保证AOF文件不会无限的膨胀,在恢复数据时不至于太慢
易懂易恢复,日志记录是有序写入,便于读懂
缺点:
AOF文件恢复数据慢,相对于RDB而言,RDB是二进制存储
AOF持久化效率低,每秒都会记录操作命令
C、RDB与AOF混合使用
RDB与AOF混合使用是Redis4.0开始的新特性,默认开启状态。
解决问题:Redis在重启时通常是加载AOF文件,但是加载速度慢,因为RDB数据不完整,所以加载AOF。
开启后,在混合使用中AOF直接读取RDB数据重建原始数据集,集合二者优势为一体。
数据恢复
当开启混合持久化时,启动Redis依然优先加载aof文件,aof文件加载可能有两种情况:
aof文件开头是rdb格式,先加载rdb内容在加载剩余的aof文件
aof文件开头不是rdb格式,直接以aof格式加载整个文件
优缺点
优:
既能快速备份又能避免大量数据丢失
缺:
rdb是压缩格式,AOF在读取时可读性较差。
动态切换
Redis在2.2后版本,可以在不重启的情况下,从RDB切换到AOF。
1.将最新dump.rdb文件创建备份
cp dump.rdb dump.rdb.backup
2.开启AOF
执行该命令后,Redis会阻塞直到初始化AOF文件创建完成为止,然后继续处理命令请求并开始将写入命令追加到AOF文件末尾。
redis-cli config set appendonly yes
3.关闭rdb
redos-cli config set save ""
四、Redis容灾备份
开启RDB持久化
save 900 1
save 300 10
开启AOF配置
# 开启aof
appendonly yes
appendfilename "appendony.aof"
# 开启重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 选择使用同步策略
appendfsync everysec
RDB日志备份
RDB日志备份,编写定时备份脚本:backup_del.sh
#!bin/bash
# 获取当前时间
cur_date=$(date "+%Y%m%d%H%M%S")
# 先删除在创建
rm -rf /usr/local/program/redis/backup/$cur_date
mkdir -p /usr/local/program/redis/backup/$cur_date
# 备份数据
cp /usr/local/program/redis/data/dump.rdb /usr/local/program/redis/backup/$cur_date
# 删除48小时前的数据
del_date=$(date -d -48hour "+%Y%m%d%H%M")
rm -rf /usr/local/program/redis/backup/$del_date
使用定时任务执行备份脚本
# 打开crontab
crontab -e
写入定时任务
* */1 * * * sh /usr/local/program/redis/backup_del.sh
四、Redis优化
1.独立部署:fork子进程频繁创建与销毁
2.硬盘优化:Redis大量的写入
3.缓存功能禁用持久化:缓存数据存在关系型数据库中,Redis可禁用持久化
4.主从模式,主关闭持久化,让从节点进行持久化
5.优化fork子进程:降低Aof重写频率,增大aof文件大小配置,关闭重写期间追加操作的配置
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/137044.html