redis主从持久化讨论
Redis有两种持久化方式,AOF和RDB,AOF持久化是指追加写命令到aof文件的方式,RDB是指定期保存内存快照到rdb文件的方式。
RDB虽然可以通过bgsave指令后台保存快照,但fork()子进程是有开销的,在内存数据集较大的情况下会占用很长的cpu时间,fork新进程时,虽然可共享的数据内容不需要复制,但会复制之前进程空间的内存页表,如果内存空间有40G(考虑每个页表条目消耗 8 个字节),那么页表大小就有80M,这个复制是需要时间的,在有的服务器结点上测试,35G的数据bgsave瞬间会阻塞200ms以上,一般建议Redis使用内存不超过20g。I/O消耗,我们线上是在Slave节点开启rdb持久化,磁盘性能一般,1.2g的rdb文件持久化一分钟一次,一次大概耗时30s左右,所以rdb的频率也不能太频繁,需要根据情况做好配置。
AOF是追加写命令到aof文件的方式,优点是可以基本做到数据无损,缺点是文件增长较快,需要间歇性bgrewrite,bgrewrite也是一个既耗cpu又耗磁盘IO的操作,单cpu利用率最高可达100%。bgrewrite期间可以设置将新的写请求暂时缓存,bgrewrite完成后同步写盘,同步会暂时停止处理客户端请求,如果bgrewrite时间较长,缓冲区积压数据较多,核心阻塞时间会很长,所以如果必须要开启aof,一般建议找几个空闲时段设置脚本来做bgrewrite。
AOF还有一个比较坑的地方是刷盘策略fsync的设置,这个设置一般有3种方式:always、everysec、no,如果设置为no,就将写盘的时机交给操作系统,这在很大程度上牺牲了aof数据无损的优势,如果设置为always就意味着每条命令都会同步刷盘,会造成频繁I/O,所以一般建议是设置everysec,Redis会默认每隔一秒进行一次fsync调用,将缓冲区中的数据写到磁盘。但是当这一次的fsync调用时长超过1秒时。Redis会采取延迟fsync的策略,再等一秒钟。也就是在两秒后再进行fsync,这一次的fsync就不管会执行多长时间都会进行。这时候由于在fsync时文件描述符会被阻塞,所以当前的写操作就会阻塞,因为是同步操作所以核心处理阻塞,开启aof且要求Redis性能无损对磁盘有极高要求。下图是我们一段时间内的磁盘监控截图:

这种间歇性的磁盘IO毛刺就会使fsync阻塞,fsync阻塞时一般会输出如下日志:

持久化为Redis提供了异常情况下的数据恢复机制,但开启持久化是有代价的,哪一种持久化都可能造成CPU卡顿,影响对客户端请求的处理。不开启持久化又存在风险,如果一旦误重启master节点,或者试想这样一种场景,主从切换失败,很可能因为疏忽直接重启master,这时没有开启持久化的master会把所有slave的数据清0。所以是否开启持久化,怎样开启持久化是一个难题。和运维同事探讨了一些方案,这里总结一下供大家参考:
1、极端情况下可以容忍全量数据丢失,那么建议master关闭持久化,slave关闭持久化;
2、极端情况下不能容忍全量数据丢失,但可以容忍部分数据丢失,如果内存数据集较小且不会增长建议master开启rdb,slave开启rdb;如果数据集很大,或不确定数据集增长趋势,建议master关闭持久化,slave开启rdb
开启rdb需要cpu和磁盘性能保障。如果master关闭持久化,slave开启rdb需要保证slave的rdb不会被master误重启所覆盖,这里提供几种方案:
重启脚本包一层命令先网络请求加载备机备份目录下的rdb文件后再执行start,可以防止误重启,但备机调整部署可能需要调整脚本,主机打开持久化也需要调整脚本
定时将rdb文件通过网络io传给master节点(文件大比较耗时,文件增长需要考虑定时脚本执行间隔,否则会造成持续的网络io),而且也会有一定数据损失
定时备份Slave的rdb到备份目录,不做任何其他操作,误重启时人工拷贝rdb到master节点(会有一定数据损失)
3、最大限度需要数据无损,建议master开启aof,slave开启aof
开启aof需要cpu和磁盘性能保障。开启aof建议fsync同步刷盘使用everysec,自定义脚本在应用空闲时定时做bgrewrite,bgrewrite期间增量数据做缓冲。
目前大部分业务都允许部分数据丢失,为使Redis性能最大化,关闭了Master持久化,slave开启rdb,为防止误重启对rdb做了5分钟一次备份,保留最近1小时的备份文件,必要时人工copy到master数据目录下恢复数据。后续硬件性能提升后,看情况再调整持久化机制
tips:注意,一般是在命令行做主从,同时主关闭持久化
做主从:
redis-cli -h ip -p
ip:>slaveof ip
关闭持久化:
config set save ""
redis主从持久化讨论的更多相关文章
- redis + 主从 + 持久化 + 分片 + 集群 + spring集成
Redis是一个基于内存的数据库,其不仅读写速度快,每秒可以执行大约110000的写操作,81000的读取操作,而且其支持存储字符串,哈希结构,链表,集合丰富的数据类型.所以得到很多开发者的青睐.加之 ...
- Linux下的redis的持久化,主从同步及哨兵
redis持久化 Redis是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失, 为了解决这个问题,Redis提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失. RDB持久 ...
- Redis 主从配置和参数详解
安装redis 下载redis wget http://download.redis.io/releases/redis-3.0.7.tar.gz 解压redis tar -xvf redis-.ta ...
- redis主从,哨兵回忆手册
redis主从 持久化的开启与主从集群是否生效无关系 Slave Server同样是以非阻塞的方式完成数据同步.在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据(注意初次同步则会阻 ...
- Redis数据"丢失"讨论及规避和解决的几点总结
Redis大部分应用场景是纯缓存服务,请求后端有Primary Storage的组件,如MySQL,HBase;请求Redis的键未命中,会从primary Storage中获取数据返回,同时更新Re ...
- 深入理解Redis的持久化机制和原理
Redis是一种面向“key-value”类型数据的分布式NoSQL数据库系统,具有高性能.持久存储.适应高并发应用场景等优势.它虽然起步较晚,但发展却十分迅速. 近日,Redis的作者在博客中写到, ...
- 那一天,我被Redis主从架构支配的恐惧
面试官:要不你来讲讲你最近在看的点呗?可以拉出来一起讨论下(今天我也不知道要问什么) 候选者:最近在看「Redis」相关的内容 面试官:嗯,我记得已经问过Redis的基础和持久化了 面试官:要不你来讲 ...
- redis 主从同步
修改redis.conf配置文件 vi redis.conf 在编辑模式下 输入 /slaveof 来搜索 将slaveof启用 即 将#删除 依次配置所有 slave 并将进程 kill 掉 重启 ...
- Redis主从自动failover
Redis主从架构持久化存在一个问题,即前次测试的结论,持久化需要配置在主实例上才能跨越实例保证数据不丢失,这样以来主实例在持久化数据到硬 盘的过程中,势必会造成磁盘的I/O等待,经过实际测试,这个持 ...
随机推荐
- P问题,NP问题 NPC问题 大神解答
http://blog.sina.com.cn/s/blog_5212bec30100o03y.html http://blog.csdn.net/u010385646/article/details ...
- Python爬链接
# -*- coding: utf-8 -*- """ Created on Wed Jan 11 17:21:54 2017 @author: PE-Monitor & ...
- [BZOJ4538]网络
今天打比赛,毒瘤yww把这题出到$n,m\leq 5\times10^5$,因为不会写整体二分所以来写坑爹的$O\left(n\log_2n\right)$做法 考虑按重要度建权值线段树(相同权值的请 ...
- [CF538H]Summer Dichotomy
[CF538H]Summer Dichotomy 题目大意: 将若干个学生分为两个班级\(S_1,S_2\),每个班的学生数分别为\(n_1,n_2\)(甚至可以没有学生,也可以没有老师).给出限 ...
- [Hybrid App]--Android混合开发,Android、Js的交互
AndroidJs通信 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !imp ...
- PythonGUI编程--向列表框添加滚动条
代码如下: from tkinter import * window = Tk() window.title("New England") yscroll = Scrollbar( ...
- 对象数组的初始化:null reference
今天写代码的时候,发现我写的对象数组,只声明,而没有初始化,所以记录一下这个问题:null reference. Animals [] an=new Animals[5];//这只是个对象类型数组的声 ...
- Linux下判断字符串长度
方法1:使用wc -L命令 wc -L可以获取到当前行的长度,因此对于单独行的字符串可以用这个简单的方法获取,另外wc -l则是获取当前字符串内容的行数. echo 'abc' |wc -L 注意:这 ...
- Objective-C:Objective-C 和 Core Foundation 对象相互转换的内存管理
Objective-C 和 Core Foundation 对象相互转换的内存管理 iOS允许Objective-C 和 Core Foundation 对象之间可以轻松的转换,拿 NSString ...
- Kafka 简单实验一(安装Kafka)
Apache Kafka - 安装步骤 步骤1 - Java安装 希望您现在已经在您的计算机上安装了Java,因此您只需使用以下命令进行验证. $ java -version 如果您的计算机上成功安装 ...