您的位置:首页 > 数据库 > Redis

Redis实战 - 数据安全与性能保障

2017-04-13 00:00 393 查看
摘要: 摘要:主要内容:
将数据持久化到硬盘
将数据复制到其他机器
处理系统故障
Redis事务

一、持久化选项介绍

Redis提供了两种不同的持久化方法来将数据存储到硬盘。一种方法叫快照(snapshotting),它可以将存在于某一时刻的所有数据都写入到硬盘里面。另一种方法叫只追加文件(append-only file, AOF),它会在执行写命令时,将被执行的写命令复制到硬盘。

1.1 快照持久化选项:

save 60 1 # 60秒内有1次写入操作的时候执行快照的创建

stop-writes-on-gbsave-error no #创建快照失败的时候是否仍然继续执行

rdbcompression yes #是否对快照文件进行压缩

dbfilename dump.rdb #如何命名硬盘上的快照文件

dir ./ #快照文件保存的位置

在redis配置文件redis.conf中内容如下:





1.2 AOF 持久化选项

appendonly on #是否使用AOF持久化

appendsync everysec #多久执行一次将写入内容同步到硬盘

no-appendfsync-on-rewrite no #对AOF进行压缩的同时能否执行同步操作

auto-aof-rewrite-percentage 100 #多久执行一次AOF压缩

auto-aof-rewrite-min-size 64mb #多久执行一次AOF压缩

dir ./ #AOF所保存的位置










这两种持久化方法既可以同时使用,用可以单独使用,具体选择那种持久化方法需要根据用户的数据以及应用决定。

二、快照持久化

Redis可以通过创建快照来获得存储在内存里面的数据在某个时间点上的副本。在创建快照之后,用户可以对快照进行备份,可以将快照复制到其他服务器从而创建具有相同数据的服务器副本,还可以将快照留在原地以便重启服务器时使用。

如果在新的快照文件创建完毕之前,Redis、系统或者硬件这三者中任意一个崩溃了,那么Redis将丢失最近一次创建快照之后写入的所有数据。

创建快照的办法有以下几种:

客户端可以向Redis发送BGSAVE 命令来创建快照。对于支持BGSAVE命令的平台来说,Redis会调用fork来创建一个子进程,然后子进程负责将快照写入到硬盘,而父进程则继续处理命令请求。

客户端还可以向Redis发送SAVE命令来创建快照。接到SAVE命令的Redis服务器在快照创建完毕之前将不再响应任何其他命令。SAVE不常用,我们通常只会在没有足够内存去执行BGSAVE命令的时候才会使用这个命令。

如果用户设置了save配置选项,那么当任意一个save配置选项所设置的条件被满足时,Redis就会触发一次BGSAVE命令。

当Redis通过SHUTDOWN命令接收并关闭服务器请求时,或者接收到标准TERM信号时,会执行一次SAVE,阻塞客户端,不再执行客户端发送的任何命令,并在SAVE命令执行完毕之后关闭服务器

当一个Redis服务器连接到另一个Redis服务器,并向对方发送SYNC命令来开始复制操作的时候,如果主服务器目前没有在执行BGSAVE操作,或者主服务器并非刚刚执行完BGSAVE操作,那么主服务器就会执行BGSAVE。

当Redis存储的数据量只有几个GB的时候,使用快照来保存数据时没有问题的。Redis会创建子进程并将数据保存到硬盘里,生成快照的时间很短。但是随着Redis占用内存越来也多,BGSAVE在创建子进程时耗费时间会越来越多。如果Redis的内存占用量达到数十个GB,并且剩余的空间内存并不多时,执行BGSAVE可能导致系统长时间停顿,从而导致Redis的性能降低甚至无法使用。在这种情况下,我们可以使用AOF持久化来将存储在内存里面的数据尽快地保存到硬盘里面

三、AOF持久化

简单来说AOF持久化会将被执行的命令写到AOF文件的末尾,以此来记录数据发生的变化。因此,Redis只要从头到尾地重新执行一次AOF文件包含的所有写命令,就可以恢复AOF文件所记录的数据集。

我们可以通过变更redis.conf下的appendonly属性yes来打开AOF。更改appendfsync属性为everysec/always/no来配置AOF文件的同步频率

appendfsync同步频率的区别如下:

选项同步频率
always每个Redis写命令都要同步写入硬盘,这样会严重降低Redis的速度
everysec每秒执行一次同步,显示地将多个写命令同步到硬盘
no让操作系统决定应该何时进行同步
always的方式固然可以对没一条数据进行很好的保存,但是这种同步策略需要对硬盘进行大量的写操作,所以Redis处理命令的速度会受到硬盘性能的限制。普通的硬盘每秒钟只能处理大约200个写命令,使用固态硬盘SSD每秒可以处理几万个写命令,但是每次只写一个命令,这种只能怪不断地写入很少量的数据的做法有可能引发严重的写入放大问题,这种情况下降严重影响固态硬盘的使用寿命。

everysec的方式,Redis以每秒一次的频率大队AOF文件进行同步。这样的话既可以兼顾数据安全也可以兼顾写入性能。Redis以每秒同步一次AOF文件的性能和不使用任何持久化特性时的性能相差无几,使用每秒更新一次 的方式,可以保证,即使出现故障,丢失的数据也在一秒之内产生的数据。

no的方式,Redis将不对AOF文件执行任何显示的同步操作,而是由操作系统来决定应该何时对AOF文件进行同步。这个命令一般不会对Redis的性能造成多大的影响,但是当系统出现故障的时候使用这种选项的Redis服务器丢失不定数量的数据。另外,当用户的硬盘处理写入操作的速度不够快的话,那么缓冲区被等待写入硬盘的数据填满时,Redis的写入操作将被阻塞,并导致Redis处理命令请求的速度变慢,因为这个原因,一般不推荐使用这个选项。

四、重写/压缩 AOF文件

因为Redis会不断地将被执行的写命令记录到AOF文件里面,所以随着Redis不断运行,AOF文件的体积也会不断增长,在极端情况下,体积不断增大的AOF文件甚至可能会用完硬盘的所有可用空间。另外,因为Redis在重启之后需要通过重新执行AOF文件记录的所有命令来还原数据集,所以当AOF体积非常大的时候,还原操作需要的时间会非常长。

为了解决AOF体积不断增大的问题,用户可以向Redis发送BGREWRITEAOF命令,这个命令会通过移除AOF文件中的冗余命令来重写AOF文件,使得AOF文件的体积变得尽可能的小。

BGREWRITEAOF命令会让Redis创建一个子进程对AOF文件进行重写。AOF持久化可以通过设置auto-aof-rewrite-percentage选项和auto-aof-rewrite-min-size选项来自动执行BGREWRIRWAOF。

示例:auto-aof-rewrite-percentage 100和auto-aof-rewrite-min-size 64mb表示当AOF文件的体积大于64mb,并且AOF文件的体积比上一次重写之后的体积大了至少一倍的时候,Redis将执行BGREWRITEAOF命令。

五、复制

复制可以让其他服务器拥有一个不断更新的数据副本,从而使得拥有数据副本的服务器可以用于处理客户端发送的读请求。

5.1 对Redis的复制相关选项进行配置

当从服务器连接主服务器时,主服务器会执行BGSAVE操作。为了正确使用复制特性,用户需要保证主服务器已经正确配置了持久化清单(快照和aof持久化)。而且开启从服务器所必须的选项中只有slaveof一个。如果用户在启动Redis服务器时,指定了一个包含slaveof host port选项的配置文件,那么Redis服务器将根据该选项给定的IP地址和端口号来连接主服务器。

5.2 Redis 复制的启动过程

步骤主服务器操作从服务器操作
1(等待命令进入)连接(或者重连接)主服务器,发送SYNC命令
2开始执行BGSAVE,并使用缓冲区记录BGSAVE之后执行的所有命令根据配置选项来决定是继续使用现有数据(如果有数据的话)来处理客户端的命令请求,还是向发送请求的客户端返回错误
3BGSAVE执行完毕,向从服务器发送快照文件,并在发送期间继续使用缓冲区记录被执行的写命令丢弃所有的旧数据(如果有的话),开始载入主服务器发来的快照文件
4快照文件发送完毕,开始向从服务器发送存储在缓冲区的写命令完成对快照文件的解释操作,像往常一样开始接受客户的命令请求
5缓冲区存储的写命令发送完毕;从现在开始,每执行一个写命令,就向从服务器发送相同的写命令执行主服务器发来的所有存储在缓冲区里面的写命令;从现在开始,接收并执行主服务器传来的每个写命令
用户可以通过配置SLAVEOF host port 来将一个Redis服务器设置为从服务器,也可以通过向正在运行中的Redis服务器发送SLAVEOF命令来将其设置为从服务器。如果用户使用的是SLAVEOF配置选项,那么Redis在启动时首先会载入当前可用的任何快照或者AOF文件,然后连接主服务器并执行复制过程。如果用户使用的是SLAVEOF命令,那么Redis会立即尝试连接服务器,如果连接成功,那么开始执行复制过程。

5.3 主从链

因为Redis的主服务器和从服务器没有特别不同的地方,所以从服务器也可以拥有自己的从服务器,并由此形成主从链。

为了将数据保存到多台机器上面,用后首先需要为主服务器设置多个从服务器,然后对每个从服务器设置appendonly yes选项和appendfsync everysec选项,这样的话,用后就可以让多台服务器以每秒一次的频率将数据同步到硬盘了。

5.4 检查硬盘写入

为了验证主服务器是否已经将写数据发送至从服务器,用户需要在向主服务器写入真正的数据之后,再向主服务器写入一个唯一的虚构值,然后通过检查虚构值是否存在于从服务器来判断写数据是否已经到达从服务器。另外,可以通过检查INFO命令的输出结果中aof_pending_bio_fsync实行是否为0,如果是的话,那么就表示服务器已经将已知的所有数据都保存到硬盘里了。咋向主服务器写入数据之后,用户可以将主服务器和从服务器的连接作为参数,来检查硬盘写入。

info命令结果如下(无关信息太多,以省略号代替):

127.0.0.1:6379> info

# Server

redis_version:3.2.8

redis_git_sha1:00000000

redis_git_dirty:0

redis_build_id:3adf919ae7e68908

redis_mode:standalone

os:Linux 2.6.32-642.6.2.el6.i686 i686

...

executable:/usr/local/bin/redis-server

config_file:/usr/local/soft/redis-stable/redis.conf

# Clients

connected_clients:1

...

# Memory

used_memory:646640

...

mem_allocator:jemalloc-4.0.3

# Persistence

loading:0

rdb_changes_since_last_save:0

rdb_bgsave_in_progress:0

rdb_last_save_time:1492011141

rdb_last_bgsave_status:ok

rdb_last_bgsave_time_sec:0

rdb_current_bgsave_time_sec:-1

aof_enabled:0

aof_rewrite_in_progress:0

aof_rewrite_scheduled:0

aof_last_rewrite_time_sec:-1

aof_current_rewrite_time_sec:-1

aof_last_bgrewrite_status:ok

aof_last_write_status:ok

# Stats

total_connections_received:55

total_commands_processed:299

instantaneous_ops_per_sec:0

total_net_input_bytes:9774

total_net_output_bytes:29924707

instantaneous_input_kbps:0.00

instantaneous_output_kbps:0.00

rejected_connections:0

sync_full:0

sync_partial_ok:0

sync_partial_err:0

expired_keys:0

evicted_keys:0

keyspace_hits:181

keyspace_misses:1

pubsub_channels:0

pubsub_patterns:0

latest_fork_usec:178

migrate_cached_sockets:0

# Replication

...

# CPU

...

# Cluster

cluster_enabled:0

# Keyspace

db0:keys=6,expires=0,avg_ttl=0


六、处理系统故障

6.1 验证快照文件和AOF文件

无论是快照持久化还是AOF持久化,都提供了在遇到系统瓶颈故障时进行数据恢复的工具。Redis提供了两个命令行程序redis-check-aof和redis-check-dump/redis-check-rdb,他们可以在系统故障发生之后,检查AOF文件和快照文件的状态,并在有需要的情况下对文件进行修复。



如果在运行运行redis-check-aof程序时给定了--fix参数,那么程序将对AOF文件进行修复。它会扫描AOF文件,寻找不正确或者不完成的命令,当发现第一个出错命令的时候,程序会删除出错的命令以及位于出错命令之后的所有命令。

6.2 更换故障主服务器

假设A、B两台服务器都运行着Redis,其中机器A的Redis为主服务器,而B的Redis为从服务器。不巧的是,机器A刚刚因为某个故障断开了网络连接,因此用户决定将同样安装了Redis的机器C用作新的主服务器。

更换服务器的计划非常简单:首先向机器B发送一个SAVE命令,让它创建一个新的快照文件,接着将这个快照文件发送给机器C,并在机器C上启动Redis。最后让机器B成为机器C的从服务器。

七、Redis事务

Redis事务是以特殊命令MULTI为开始,之后跟着用户传入的多个命令,最后以EXEC为结束。但是由于这种简单的事务在EXEC命令被调用之前不会执行任何实际操作,所以用户将没办法根据读取到的数据来做决定。为此Redis采用了延迟执行事务(一次性发送多个命令,然后等待所有回复出现)以提高性能,减少客户端与Redis服务器之间的网络通信次数来提升Redis在执行多个命令时的性能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息