一、redis 持久化说明
1) 手工持久化
SAVE(同步回写)和 BGSAVE(异步回写) 两个命令都会调用 rdbSave 函数,它们都实现RDB持久化,但它们调用的方式各有不同:
SAVE 直接调用 rdbSave ,阻塞 Redis 主进程,直到保存完成为止。在主进程阻塞期间,服务器不能处理客户端的任何请求。
BGSAVE 则 fork 出一个子进程,子进程负责调用 rdbSave ,并在保存完成之后向主进程发送信号,通知保存已完成。因为 rdbSave 在子进程被调用,所以 Redis 服务器在BGSAVE 执行期间仍然可以继续处理客户端的请求
2) 自动持久化(两种持久化方式: 一种是RDB持久化,一种是AOF持久化)
RDB持久化默认生成的文件名为dump.rdb
save 900 1 900秒之内对服务进行了至少一次修改
save 300 10 300秒之内服务器进行了至少10次修改
save 60 10000 60秒之内对服务器进行了至少10000次修改
# 以上这些条件满足其中的任意一个bgsave命令就会自动执行
save "" 表示关闭RDB持久化功能
AOF(Append-Only File) 持久化方式时,Redis会将每一个收到的写命令都通过Write函数追加到文件中,类似于MySQL中的binlog。当Redis重启是会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。
appendonly yes #启用AOF持久化方式
appendfilename appendonly.aof #AOF文件的名称,默认为appendonly.aof
#appendfsync always #每次收到写命令就立即强制写入磁盘,是最有保证的完全的持久化,但速度也是最慢的,一般不推荐使用。
appendfsync everysec #每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,是受推荐的方式。
#appendfsync no #完全依赖OS的写入,一般为30秒左右一次,性能最好但是持久化最没有保证,不被推荐。
no-appendfsync-on-rewrite yes #在日志重写时,不进行命令追加操作,而只是将其放在缓冲区里,避免与命令的追加造成DISK IO上的冲突。
auto-aof-rewrite-percentage 100 #当前AOF文件大小是上次日志重写得到AOF文件大小的二倍时,自动启动新的日志重写过程。
auto-aof-rewrite-min-size 64mb #当前AOF文件启动新的日志重写过程的最小值,避免刚刚启动Reids时由于文件尺寸较小导致频繁的重写。
AOF的完全持久化方式同时也带来了另一个问题,持久化文件会变得越来越大。比如在不同的时间中调用了INCR test命令100次,文件中就必须保存全部的100条命令,但其实99条都是多余的(仅有最后一次incr test才有效)。因为要恢复数据库的状态其实文件中保存一条SET test 100就够了。为了压缩AOF的持久化文件,Redis提供了bgrewriteaof命令。收到此命令后Redis将使用与快照类似的方式将内存中的数据以命令的方式保存到临时文件中,最后替换原来的文件,以此来实现控制AOF文件的增长。由于是模拟快照的过程,因此在重写AOF文件时并没有读取旧的AOF文件,而是fork一个子进程,直接遍历整个内存中的数据库内容,并写入新的AOF临时文件。在写入新文件的过程中,所有的写操作日志还是会写到原来老的 AOF文件中,同时还会记录在内存缓冲区中。当重完操作完成后,会将所有缓冲区中的日志一次性写入到临时文件中。然后调用原子性的rename命令用新的 AOF文件取代老的AOF文件。(提示:正因为bgrewriteaof时需要大量的内存,所以一般情况下会将maxmemory的大小指定为服务器内存大小的50%,这也是为了防止在bgrewriteaof时内存溢出)
在数据恢复方面:
RDB的启动时间会更短,原因有两个:
1)、RDB文件中每一条数据只有一条记录,不会像AOF日志那样可能有一条数据的多次操作记录。所以每条数据只需要写一次就行了。
2)、原因是RDB文件的存储格式和Redis数据在内存中的编码格式是一致的,不需要再进行数据编码工作,所以在CPU消耗上要远小于AOF日志的加载
二、性能与监控
1、redis 是一个单线程的APP,除了bgsave或bgrewriteaof时它会启动另一个线程外,其它时间都是一个线程,且它并不支持cpu rebalance,它只会占用一颗CPU的资源,所以在多处理器环境中,尽量手工将不同redis实例绑定到不同的CPU上
2、为了提高性能,建议:
在cluster中所有的master上关闭 各种持久化功能,在cluster中所有的slave上开启持久化;
为了防止master/slave的自动切换,调整优先级( redis 优先级数字越小 优先级越高)
如果某个shard 宕掉,尽量先启动原slave( 该主机已持久化),然后再启动原 master ,等数据稳定后,再cluster failover
3、关于监控项,监控内容如下:
进程数量 / 端口状态(port 是否存在)
进程占内存的情况
master的数量 / cluster_slots_ok 的数量是否为16384 / cluster_state
三、关于cluster-require-full-coverage
如果 cluster-require-full-coverage no,某个shard down掉,使用cluster info 命令时 cluster_state: ok,其它shard 照常可以get/set key 。
如果 cluster-require-full-coverage yes,某个shard down掉,使用cluster info 命令时 cluster_state: fail ,其它shard 不能get/set key, 在 get 或 set key 时 系统提示:(error) CLUSTERDOWN The cluster is down;可以使用 keys * 获取 key 名称
在每隔0.1s插入一个数据时,手工cluster failover 不会影响写入数据,数据没有丢失。