当前位置:首页 > 娱乐星闻

repl Redis4.0新特性-PSYNC2

Redis4.0,增加了新特性PSync 2(部分同步版本2);主要解决Redis运维管理中从实例重启、主实例故障转移等场景导致的全重同步问题。

1什么是Redis部分再同步-psync

Redis部分重新同步:当复制由于某种原因中断后,从库中重新同步redis时,只同步主实例的差异数据(写指令),复制整个RDB文件而不进行bgsave。

本文中的名词约定:

部分再同步:以下简称psync

完全再同步:以下称为完全同步

Redis2.8版本1部分再同步:以下简称psync1

Redis4.0版本2部分再同步:以下简称psync2。

在解释psync2的功能之前,先简单解释一下redis2.8版本发布的psync1。

Redis2.8 psync1解决了什么问题

在psync1函数出现之前,第二级的redis复制中断从实例触发了fullsync。

每次fullsync,集群的性能和资源使用都可能带来抖动;如果redis处于不稳定的网络环境中,fullsync的传出频率可能会很高。为了解决这个问题,redis2.8引入了psync1,有效地解决了这种拷贝闪存的影响。Redis的fullsync对业务的影响相对“沉重”;性能和可用性存在一定的风险。

以下是fullsync的一些常见效果:

Master需要运行bgsave,出现fork(),可能导致master在毫秒或秒内堵塞(latest_fork_usec状态监控);

redis进程分叉导致写时复制内存使用(以下简称COW)的消耗,最多可以导致主进程内存使用的消耗。(在eg日志中输出RDB:写入时复制使用5213兆内存)

redis从负载RDB进程会导致复制线程的客户端输出缓冲区大幅增长;增加主进程的内存消耗;

Redis节省了RDB(不考虑丢失复制),导致服务器磁盘IO和CPU(压缩)资源的消耗

发送几千兆字节的RDB文件将导致服务器网络出口的爆炸。如果使用千兆网卡服务器,会影响正常的服务请求响应时间(以及其他连锁效应)

psync1的基本实现

因为psync2是基于psync1的增强实现,所以在介绍psync2之前,先简单分析一下psync1的实现。

为了支持psync1,redis2.8引入了复制积压缓冲区(以下简称复制积压缓冲区);复制积压缓冲区是redis维护的固定长度缓冲区队列(由参数repl-backlog-size设置,默认值为1MB),主机的写命令与从机同步,缓冲区中写入一个副本(主机只有一个积压缓冲区,由所有从机共享)。

redis复制中断时,从机会尝试使用psync来报告当前同步的主机的原始主机runid+offset(复制offset,类似于mysql binlog文件和位置);

如果runid与master的一致,且拷贝偏移量仍在master的拷贝积压缓冲区(即偏移量>:= min(积压值),则master认为部分再同步成功,不会进行完全同步。

部分重新同步成功。主日志显示如下:30422: m04aug 14: 33: 48.505 *从xxxxx: 10005请求同步30422: m04aug 14: 33: 48.506 *接受来自xxx: 10005的部分再同步请求。从偏移量6448313开始发送0字节的积压。

redis2.8的部分同步机制有效解决了网络环境不稳定和redis执行高时间复杂度命令导致的复制中断,导致完全同步。然而,在处理从机重启和主机故障转移的情况时,psync1仍然需要完全同步。

psync1的缺点

从上面可以看出,psync1需要同时满足两个条件才能成功:主运行id不变,复制偏移量在主复制产品缓冲区中。

然后,当Redissslave重新启动时,主runid和副本偏移量将丢失,因此需要完全重新同步;redis主机故障转移,因为主机runid已更改;故障切换后,新的从机需要完全重新同步。而从维护重启和主故障转移是redis运维的常见场景,针对redis的psync1无法解决这两种场景的部分再同步成功问题。

所以redis4.0 -psync2的增强型部分再同步功能主要解决这两种场景的部分再同步。

2 psync2实现简介

在redis集群的实际生产操作中,实例的维护重启和主实例的故障转移(如集群故障转移)是常见的操作(如实例升级、重命名命令和释放实例内存碎片等)。).在redis 4.0版本之前,这种维护处理,Redis会有完全的重新同步,导致对性能敏感服务的少量破坏。

如前所述,psync2主要使redis能够在从属实例重启和主实例故障转移的情况下使用部分重新同步。在本节中,将简要描述psync2在这两种情况下的逻辑实现。

名词解释:

Master_replid:重复ID1(以下简称replid1),长度为41字节(40个随机字符串+'0 ')的字符串。还有所有redis实例,都和runid没有直接关系,但是都是getRandomHexChars函数生成的,和runid生成规则一样。当一个实例成为从实例时,它自己的replid1将被主实例的replid1覆盖。

Master_replID2:复制ID2(以下称为replID2),默认初始化为全零,用于存储最后一个主实例的replid1

可以通过信息复制查看实例的replid信息;例子如下:

127.0.0.1:6385 >信息复制# Replicationrole:slave master _ host:xxxx//IP模糊处理master _ port:6382 master _ link _ status:up slave _ repl _ offset:119750 master _ repl id:Fe 093 add 4 ab 71544 ce 6508 d2e 0 B1 FD 0 b 7d 7 D1 C5 b 2//这是主实例的相同master _ repl id 1:00000000000000000000000000000000000000000000000000000000000000000

在以前的版本中,redis重启后,复制信息完全丢失;因此,从实例重新启动后,只能执行完全重新同步。

Redis4.0重启后仍然可以进行部分再同步,主要做以下三点:

当redis关闭时,复制信息作为辅助字段存储在RDB文件中。从而实现同步信息持久性;

当redis开始加载RDB文件时,它会将复制信息分配给相关字段;

redis再同步时,会上报repl-id和repl-offset的同步信息。如果它与主实例匹配,并且偏移量仍在主实例的复制积压缓冲区中,则只会执行部分重新同步。

接下来,我们详细分析每个步骤的简单实现

当redis关闭时,持续将信息复制到RDB

redis关闭时,关闭保存将调用rdbSaveInfoAuxFields函数。

将当前实例的复制标识和复制偏移量保存到RDB文件中。

注意:当前RDB存储的数据内容和复制信息是一致的。熟悉MySQL的同学可以认为MySQL中的备份总数与binlog信息一致。

rdbSaveInfoAuxFields函数在rdb.c源文件中实现,省略的代码如下:

/*保存几个默认的辅助字段,其中包含RDB生成的信息。*/int rdbSaveInfoAuxFields(Rio * rdb,int flags,rdbSaveInfo *rsi) { /*添加几个关于RDB创建时的状态的字段。*/if(rdbsaveauxfieldstr(RDB," redis-ver ",REDIS _ VERSION)= =-1)return-1;//将实例的repl-id和repl-offset作为辅助字段存储在RDB if (rdbsaveauxfieldstr (RDB,“repl-id”,服务器。replid = =-1)return-1;if (rdbSaveAuxFieldStrInt(rdb," repl-offset ",server . master _ repl _ offset)= =-1)return-1;返回1;}

对于生成的RDB文件,可以通过redis-check-RDB工具查看辅助字段信息。

复制器信息的两个字段与信息中的字段相同;

$shell>。/src/redis-check-RDB dump . RDB[offset 0]Checking RDB文件dump . RDB[offset 26]AUX FIELD redis-ver = ' 4 . 0 . 1 '[offset 133]AUX FIELD repl-id = ' 44873 f 839 AE 3a 57572920 cdaf 70399672 b 842691 '[offset 148]AUX FIELD repl-offset = ' 0 '[offset 167]o/RDB看起来还可以!0/[信息] 1密钥读取[信息] 0过期[信息] 0已经过期redis开始读取RDB的复制信息

redis实例开始读取RDB文件,这是通过rdb.c文件中的rdbLoadRio()函数实现的。

redis加载RDB文件时,会处理文件中辅助字段的信息,并将repl_id和repl_offset加载到实例中,并分别赋予master_replid和master_repl_offset两个变量值。

下面的代码从RDB文件中读取两个辅助字段值。

Int rdbloadrio (Rio * RDB,rdbsaveinfo * RSI){-省略-else if(!strcasecmp(auxkey->;Ptr," repl-id")) {//读取的aux字段为repl-id if(RSI & amp:& amp;sdslen(auxval->;ptr = = CONFIG _ RUN _ ID _ SIZE){ memcpy(RSI-& gt;repl_id,auxval->ptr,CONFIG _ RUN _ ID _ SIZE+1);rsi->。repl _ id _ is _ set = 1;} } else if(!strcasecmp(auxkey->;ptr," repl-offset")) { if (rsi) rsi->。repl_offset = strtoll(auxval->;ptr,NULL,10);} else { /*我们忽略我们不理解的字段,如AUX字段*合同。*/服务器日志(LL_DEBUG),"无法识别的RDB辅助字段:“%s”,(char *)AUX key->;ptr);}} redis试图从实例进行部分重新同步

重新启动redis实例后,从RDB文件加载Master_replid和master _ repl _ offset(注意:这里不讨论AOF和RDB加载优先级);等效于实例的server.cached_master。当我们将其视为一个实例的从库(包括被动集群从或主动执行slaveof指令)时,该实例向主实例报告master_replid和master _ repl _ offset+1;当实例同时满足以下两个条件时,部分重新同步是可能的:

1.来自实例的report master_replid字符串,它等于主实例的master_replid1或replid2

2.从实例报告的master_repl_offset+1字节仍然存在于主实例的复制积压缓冲区中

请尝试从实例(在replication.c文件中)部分重新同步slavertrypartialresynchronization函数;

主实例判断是否可以执行部分再同步功能MasterTrypArtialSynchronization(在replication.c文件中)。

redis重新启动时,临时调整主实例的复制积压缓冲区大小

redis的复制积压缓冲区由参数repl-backlog-size设置,为1MB默认情况下。为了确保从实例重新启动后的部分重新同步,应该设置一个合理的repl-backlog-size值。

1计算合理的复件积压量值

根据以主库每秒为增量的主复制偏移量master _ repl _ offset(由信息复制指令获得),

如果偏移量每秒增加5MB,主实例副本的backlog缓冲区应该保留最后60秒写入的内容,backlog_size设置应该大于300MB(60*5)。但是,从实例中重新启动和加载RDB文件是一个耗时的过程。如果重启某个实例需要120秒(RDB大小与CPU配置有关),那么主实例的backlog_size必须设置为至少600MB。

计算公式:backlog_size =重启从实例时间*主实例偏移量每秒写入量

2在重新启动从属实例之前,调整主实例的动态调整repl-backlog-size值。

因为当redis的repl-backlog-size通过配置集动态调整时,redis会释放当前的backlog缓冲区,并重新分配一个指定大小的缓冲区。因此,在重新启动从属实例之前,我们必须调整主实例的repl-backlog-size。

调整backlog_size处理函数resizeReplicationBacklog,代码逻辑如下:

void ResizeReplicationbacklog(long long newsize){ if(newsize & lt;config _ repl _ backlog _ min _ size)//如果设置的新值小于16 KB,则修改为16KB新大小= config _ repl _ backlog _ min _ sizeif(server . repl _ backlog _ size = = newsize)return;//如果新值与原始值相同,则不做任何处理返回。server . repl _ backlog _ size = newsize;//如果(server.repl_backlog!= NULL) {//当backlog的内容不是空时,释放当前backlog。并根据新的值/*分配一个新的积压,我们实际上要做的是刷新旧的缓冲区,并重新锁定一个新的*空缓冲区。它将随着新数据的增加而增加。*原因是复制几千兆字节会增加延迟,更糟糕的是,我们经常需要在释放旧缓冲区之前分配额外的空间。*/zfree(server . repl _ backlog);server . repl _ backlog = zmalloc(server . repl _ backlog _ size);server . repl _ backlog _ hist len = 0;//将backlog内容的长度和第一个字节的偏移量修改为0 server.repl _ backlog _ idx = 0/*我们的下一个字节是...因为缓冲区是空的。*/server . repl _ backlog _ off = server . master _ repl _ offset+1;}} 3 psync2实现Redis集群故障转移的部分新同步

为了解决主实例故障转移后重新同步新主实例数据时使用psync的问题,fullsync改为使用。

1 redis4.0使用两组replid和offset来替换原来的master runid和offset。

2 Redissslave默认开启复印积压缓冲功能;以便其他后向从设备在从设备故障转移后更改主设备时,可以从缓冲区获取写指令。

第一组:master_replid和master_repl_offset

如果redis是主实例,则表示为自己的replid和复制偏移量;如果redis是一个从实例,它被表示为自己的主实例的replid1和同步主实例的复制偏移量。

第二组:master_replid2和second_repl_offset

无论主实例和从实例是什么,它们都代表它们的最后一个主实例repid1和复制偏移量;用于同级实例或级联复制、主库故障转移psync。

初始化时,前者为40个字符,长度为0,后者为-1;只有当主实例进行故障转移时,redis才会将其replid1和master_repl_offset+1分别分配给master_replid2和second_repl_offset。

这个切换逻辑在函数shiftReplicationId中实现。

void shift ReplicationId(void){ memcpy(server.replid 2,server . replid,sizeof(server . replid));//replid分配给replid2/*我们将第二个replid偏移量设置为主偏移量+1。由于*从机将请求尚未收到的第一个字节,因此*我们需要向偏移量添加一个字节:例如,如果作为从机,我们*确定我们与主机有相同的50个字节的历史,在我们*变成主机后,我们可以接受偏移量为* 51的PSYNC请求,因为从机请求直到第50个*字节都有相同的历史,并且正在请求从偏移量51开始的新字节。*/server . second _ replid _ offset = server . master _ repl _ offset+1;changeReplicationId();服务器日志(LL_WARNING),"将辅助复制标识设置为%s,在偏移量%lld之前有效。新复制ID为%s ",server.replid2,server.second_replid_offset,server . replid);}

通过这种方式,主库可以进行故障转移,以下三种常见结构可以执行psync:

1一主一从开关,a->: B开关变成B->:A;

2一主多从切换时,兄弟节点变成父子节点;

3级复制被切换,a->:B->;C开关变成b->:C->;A

主实例判断psync的逻辑功能是否可以在mastertrypartiresynchronization()中执行

int master try manual synchronization(client * c){//如果从机提供的master_replid与主机的replid不同,与主机的replid2不同,或者同步速度比主机快;full sync . if(str escmp(master _ replid,server . replid)&:& amp;(str secmp(master _ replid,server . replid 2)| | psync _ offset & gt;server . second _ replid _ offset)){/* Run id "?"由想要强制完全重新同步的从机使用。*/ if (master_replid[0]!= '?'){ if(str cascmp(master _ replid,server . replid)& amp;& ampstr secmp(master_replid,server.replid 2)){ Serverlog(LL _ NOTICE,"不接受部分重新同步:" "复制id不匹配(从机要求' %s ',我的" "复制id为' %s '和' %s ')",master _ replid,server . replid,server . replid 2);} else { serverLog(LL_NOTICE,“不接受部分重新同步:“”第二个ID的请求偏移量为%lld,但我可以回复“”,最多%lld”,psync_offset,server . second _ replid _ offset);} } else { serverLog(LL_NOTICE,“从%s请求完全重新同步”,replicationGetslavename(c));} goto need _ full _ resync} /*我们还有奴隶要的数据?*/ if(!server . repl _ backlog | | psync _ offset & lt;server . repl _ backlog _ off | | psync _ offset & gt;(server . repl _ backlog _ off+server . repl _ backlog _ histlen)){ Serverlog(LL _ NOTICE,“由于缺少backlog,无法与从属%s部分重新同步(从属请求为:%lld)。”,replicationGetSlaveName(c),psync _ offset);if (psync_offset >;server . master _ repl _ offset){ ServerLog(LL _ WARNING),"警告:从%s试图使用大于主复制偏移量的偏移量进行PSYNC。",replicationGetSlaveName(c));} goto need _ full _ resync}

-结束-

推荐订阅原作者微信官方账号DBACoder

1.《repl Redis4.0新特性-PSYNC2》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。

2.《repl Redis4.0新特性-PSYNC2》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。

3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/yule/1444782.html

上一篇

绿萝可以晒太阳吗 适合夏季养的植物,不怕晒好养活,你家养了吗

下一篇

郑辉闯佟年宿舍第几集

k40次列车 哈铁局调整列车时刻 K40/39次8日起部分时段调整为鸡西至北京

k40次列车 哈铁局调整列车时刻 K40/39次8日起部分时段调整为鸡西至北京

10月1日,记者从铁路部门了解到,近日,哈尔滨铁路局多列列车调整运行时间和到站时间,海拉尔至北京的K40/39临时调整运行于鸡西至北京之间。鸡西到北京继续运营K40/39次1.齐齐哈尔-虎林K7154/5次临时调整为齐...

四川自然保护区 四川:严禁在自然保护区的核心区、缓冲区开展旅游活动

7月23日,在阿坝州松潘县的圣地,海拔3500米的地方,当地人身着薰衣草花迎接来自四面八方的游客。3300亩薰衣草已全面进入花期,成为九环特有的景观。本报记者李翔宇照片探索生态环境旅游发展模式绿色价值观根植于旅游业发展...

粤通卡电话人工服务 我省部分高速路下月起 货车刷粤通卡缴路费85折

人工智能阅读:记者2017年6月29日从广东联合电子服务有限公司获悉,2017年7月1日零时起,合法装载的货运车辆将在广东省部分高速公路上缴纳通行费,享受15%的优惠。我们省的一些高速公路将于下月开工月通卡卡车交的通行...

成灌快铁时刻表 火车北站改造 部分成灌线车次7月1日起从安靖始发

城关快速铁路安靖站7月1日起,乘成都到都江堰,部分列车在北站无法再上车。成都铁路局昨日介绍,由于成都火车站正在建设车站建筑,车站容量将进行调整。7月1日起,成灌线部分列车将调整为从成灌高速铁路安靖站发车。大厅开始显示测...

贵阳生孩子和谐帮您 贵阳部分学校发告家长书 告诫孩子远离“蓝鲸游戏”

贵阳生孩子和谐帮您 贵阳部分学校发告家长书 告诫孩子远离“蓝鲸游戏”

告诉孩子们远离“蓝鲸游戏”坏游戏入侵,贵阳部分学校向家长发出举报——遇到玩这种游戏的孩子,请立即停车报警“如果发现有加入“蓝鲸游戏”倾向的孩子,请及时劝导并有效制止,并及时向老师和学校报告……”近日,贵阳部分学校发布家...

风流王侯 2019年北京电影学院艺术与电影基础理论(电影部分总结)

2019年北京电影学院艺术与电影基础理论(电影部分总结) 前言 首先,什么是电影 电影是一种以科学技术为基础的综合艺术形式,它与时代的政治经济密不可分,具有很强的商业性和社会性,能够真实、快速地反映时代的社会生活。 在...

高校电脑全被黑 全球74国遭遇大规模网络攻击 中国部分高校中招

新华社北京5月13日电综合新华社驻外记者报道,12日,世界上许多国家都遭到了一次勒索,受害者包括中国的一些大学和英国的许多医院。据了解,这个ransomware是从国安局网络武库中泄露出来的黑客工具。360岁的中国网络...

九寨沟景区部分景观3月8日起恢复开放 全年110元/张

九寨沟景区部分景观3月8日起恢复开放 全年110元/张

九寨沟景区部分景观3月8日起恢复开放 全年110元/张杨克宁代表:九寨沟景区部分景观3月8日起恢复开放  新华社北京3月7日电 2017年8月8日晚,四川省北部阿坝州九寨沟县发生7。0级地震,九寨沟多处景点遭到损坏...