重启redis服务数据丢失的问题(rdb与aof持久化策略)
先说明解决方案:
在服务使用的配置文件中启用rdb和aof配置
(1)启用aof
CONFIG SET XXX XXX
appendonly yes #开启aof特性,这个控制是否启用aof
no-appendfsync-on-rewrite no #是否在后台写时同步单写,默认值no(表示需要同步).这里的后台写,表示后台正在重写文件.no表示新的主进程的set操作会被阻塞掉,而yes表示新的主进程的set不会被阻塞,待整个后台写完成之后再将这部分set操作同步到aof文件中。但这可能会存在数据丢失的风险(机率很小),如果对性能有要求,可以设置为yes,仅在后台写时会异步处理命令.
appendfsync everysec #写入策略,默认值everysec,每秒写一次(调用flush)。另外两个值,always | no,分别表示每次redis写命令之外就写文件,和由操作系统保证。always对硬盘压力大,everysec是一个平衡值,no对硬盘压力最小,但调度由系统控制,丢失数据风险最大.
auto-aof-rewrite-percentage 100 # aof文件增长比例,指当前aof文件比上次重写的增长比例大小。aof重写即在aof文件在一定大小之后,重新将整个内存写到aof文件当中,以反映最新的状态(相当于bgsave)。这样就避免了,aof文件过大而实际内存数据小的问题(频繁修改数据问题).
auto-aof-rewrite-min-size 67108864 # aof文件重写最小的文件大小,即最开始aof文件必须要达到这个文件时才触发,后面的每次重写就不会根据这个变量了(根据上一次重写完成之后的大小).此变量仅初始化启动redis有效.如果是redis恢复时,则lastSize等于初始aof文件大小.
(2)修改rdb策略
修改服务使用的配置文件
# save
save 900 1
save 300 10
save 60 10000
# The filename where to dump the DB
dbfilename dump.rdb
# Note that you must specify a directoryhere, not a file name.
dir ./
(save 900 1、save 300 10、save 60 10000:分别表示 900 秒(15 分钟)内有 1 个更改,300 秒(5 分钟)内有 10 个更改以及 60 秒内有 10000 个更改即保存到硬盘
dbfilename dump.rdb:指定本地数据库文件名,默认值为 dump.rdb
dir ./:指定本地数据库存放目录)
(3)配置生效
window只需要重启服务,指定对应的配置文件启动即可
Linux需修改sysctl.conf:
<1>编辑 sysctl.conf 配置文件
vi /etc/sysctl.conf
<2>另起一行增加参数 vm.overcommit_memory 配置
vm.overcommit_memory = 1
<3>使配置文件生效
sysctl -p
(4)重启前使用SAVE或者BGSAVE通过rdb快照保存数据
为了保证性能我们不能让rdb快照每次执行时都实时写入,所以在重启前手动保存数据是必要的
(SAVE 保存是阻塞主进程,客户端无法连接redis,等SAVE完成后,主进程才开始工作,客户端才能连接;BGSAVE 是fork一个save的子进程,在执行save过程中,不影响主进程,客户端可以正常链接redis,等子进程fork执行save完成后,通知主进程,子进程关闭。BGSAVE适合线上的维护操作)
Redis采用rdb和aof两种策略来实现数据持久化
Rdb快照:
在默认情况下, Redis 将数据库快照保存在名字为 dump.rdb 的二进制文件中。
你可以对 Redis 进行设置, 让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时, 自动保存一次数据集。
你也可以通过调用 SAVE 或者 BGSAVE , 手动让 Redis 进行数据集保存操作。
比如说, 以下设置会让 Redis 在满足“ 60 秒内有至少有 1000 个键被改动”这一条件时, 自动保存一次数据集:
save 60 1000
AOF 持久化:
如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据
你可以通过修改配置文件来打开 AOF 功能:
appendonly yes
开启aof后, 每当 Redis 执行一个改变数据集的命令时(比如 SET key value [EX seconds] [PX milliseconds] [NX|XX]), 这个命令就会被追加到 AOF 文件的末尾。
这样的话, 当 Redis 重新启时, 程序就可以通过重新执行 AOF 文件中的命令来达到重建数据集的目的。
因为 AOF 的运作方式是不断地将命令追加到文件的末尾, 所以随着写入命令的不断增加, AOF 文件的体积也会变得越来越大。可以通过BGREWRITEAOF命令来对aop文件进行压缩重建,Redis 2.4 后的版本可以自动触发 AOF 重写
可以配置 Redis 多久才将数据 追加保存到磁盘一次
(1)always:每次有新命令追加到 AOF 文件时就执行一次 fsync :非常慢,也非常安全。
(2)everysec:每秒 fsync 一次:足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒钟的数据。
(3)no:从不 fsync :将数据交给操作系统来处理。更快,也更不安全的选择。