redis主从复制

redis主从复制

redis的一主多从能很好地提升性能,但这种系统面临一个很大的一个同步问题,特别是在系统重启,链接断开的情况下,如何保持主从数据一致是一个很重要的事情。

本文将从redis不同版本来对redis为保证主从数据库数据一致性而做的主从复制做详细说明。

主从复制步骤

从服务器从敲入复制命令到主从完成复制过程可以分为以下几个步骤:

1.客户端向从服务器发送SLAVEOF -h -p ,从服务器给客户端返回ok,此时主从复制真正开始
2.从服务器和主服务器之间建立连接,此时我们可以将从服务器看做主服务器的客户端,因为之后从服务器需要向主服务器发送各种命令
3.首先发送PING命令,主服务器返回PONG命令则表示主从之间通信正常,否则从服务器会尝试重连
4.从服务器收到PONG命令后,如果从服务器设置了masterauth选项,那么进行身份验证,此时从服务器向主服务器发送AUT命令来和主服务器进行权限验证。
5.从服务器向主服务器发送监听端口,执行命令REPLCONF listening-port <port number>
6.从服务器发送PSYNC命令(redis2.8之前是SYNC命令)开始同步数据
7.建立复制流程后,主从服务器就会进入命令传播阶段,主服务器会一直将自己执行的写命令发送给从服务器

以上就是主从复制的大致步骤

SYNC命令

2.8版本之前使用SYNC命令来进行复制,包括两个操作:

  • 同步(sync)
  • 命令传播(command propagate)

同步步骤:
1.从服务器向主服务器发送SYNC命令
2.收到SYNC命令后执行BGSAVE命令,后台生成RDB文件,并且使用缓冲区来保存从现在开始执行的所有命令
3.主服务器BGSAVE命令执行完后,把RDB文件发送从服务器,从服务器载入文件进行同步
4.主服务器将缓冲区内命令发送给从服务器,从服务器执行最终达成主从数据一致

上述过程看起来很ok了,但是存在缺陷问题,倘若在第4步时主从之间失去联系,在重新连上后,主从之间会再次走完这四步,但是明显只有第4步是必须的,我们知道生成RDB文件设计到IO操作,这会是一个耗时操作,明显这一步需要优化。

PSYNC命令

2.8之后,redis使用PSYNC命令来代替SYNC命令,该命令具有两种模式

  • 完整重同步:类似于SYNC命令的步骤,写RDB,执行缓冲区保存掉的命令
  • 部分重同步:处理掉线后的情况,此时主服务器只需要在掉线重连后将缓冲区的命令发给从服务器即可,而不需要再来一遍完整同步。

部分重同步

部分重同步由以下三个功能组成:

  • 主从服务器的复制偏移量
    主从服务器各自维护一个复制偏移量,这个偏移量的起的作用就是如果主从处于一致性,则相等,否则不相等

  • 主服务器的复制积压缓冲区
    这是主服务器的一个固定长度的先进先出(FIFO)队列,默认大小是1MB,命令传播时,主服务器不仅将命令传播给从服务器,也会写入这个缓冲区,此时在发生断开连接再重现连接的情况时,主服务器就根据复制偏移量和缓冲区来决定是部分重同步还是完整重同步(因为服务器并不知道重新连接后到底是因为故障而重新连接,还是正常的初始连接)

以下是缓冲区的构造:


复制积压缓冲区

如果偏移量之后的数据(也就是偏移量+1开始的数据)还在这个缓冲区内,此时进行部分重同步,否则完整重同步。

  • 服务器的运行ID
    这是一个由40个随机的十六进制组成的字符,断线重连或者初次连接时从服务器会将这个ID发给主服务器,如果这个两个ID同步,则表示本次是断线重连而不是初次连接,此时执行部分重同步,否则完整重同步。

PSYNC2

Redis 4.0 版本新增 混合持久化,还优化了 psync(以下称 psync2,实现即使redis实例重启的情况下也能实现部分同步,PSYNC2在之前的PSYNC基础上新增两个复制id

  • master_replid: 复制id1(后文简称:replid1),一个长度为41个字节(40个随机串+’0’)的字符串,每个redis实例都有,和runid没有直接关联,但和runid生成规则相同。当实例变为从实例后,自己的replid1会被主实例的replid1覆盖。
  • master_replid2:复制id2(后文简称:replid2),默认初始化为全0,用于存储上次主实例的replid1。

在4.0之前的版本,redis复制信息完全丢失,所以每个实例重启后只能进行全量复制,到了4.0版本,任然可以使用部分同步,其实现过程

1.存储复制信息
redis在关闭时,通过shutdown save,都会调用rdbSaveInfoAuxFields函数,把当前实例的repl-id和repl-offset保存到RDB文件中,当前的RDB存储的数据内容和复制信息是一致性的可通过redis-check-rdb命令查看。

2.重启后加载RDB文件中的复制信息
redis加载RDB文件,会专门处理文件中辅助字段(AUX fields)信息,把其中repl_id和repl_offset加载到实例中,分别赋给master_replid和master_repl_offset两个变量值,特别注意当从库开启了AOF持久化,redis加载顺序发生变化优先加载AOF文件,但是由于aof文件中没有复制信息,所以导致重启后从实例依旧使用全量复制!

3.向主库上报复制信息,判断是否进行部分同步
从实例向主库上报master_replid和master_repl_offset+1;从实例同时满足以下两条件,就可以部分重新同步,否则执行全量同步:

  • 从实例上报master_replid串,与主实例的master_replid1或replid2有一个相等,用于判断主从未发生改变;
  • 从实例上报的master_repl_offset+1字节,还存在于主实例的复制积压缓冲区中,用于判断从库丢失部分是否在复制缓冲区中;

PSYNC2除了解决redis重启使用部分同步外,还为解决在主库故障时候从库切换为主库时候使用部分同步机制。redis从库默认开启复制积压缓冲区功能,以便从库故障切换变化master后,其他落后该从库可以从缓冲区中获取缺少的命令。该过程的实现通过两组replid、offset替换原来的master runid和offset变量实现:

  • master_replid和master_repl_offset:如果redis是主实例,则表示为自己的replid和复制偏移量; 如果redis是从实例,则表示为自己主实例的replid1和同步主实例的复制偏移量。
  • master_replid2和second_repl_offset:无论主从,都表示自己上次主实例repid1和复制偏移量;用于兄弟实例或级联复制,主库故障切换psync。
    判断是否使用部分复制条件:如果从库提供的master_replid与master的replid不同,且与master的replid2不同,或同步速度快于master; 就必须进行全量复制,否则执行部分复制。

以上便是redis主从复制的全部内容。

参考资料

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,245评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,749评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,960评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,575评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,668评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,670评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,664评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,422评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,864评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,178评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,340评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,015评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,646评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,265评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,494评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,261评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,206评论 2 352

推荐阅读更多精彩内容

  • 本篇就一下方面展开分析 如何使用主从复制? 主从复制的原理(重点是全量复制和部分复制、以及心跳机制) 实际应用中需...
    lucode阅读 994评论 0 5
  • 一、Redis主从复制 主从复制:主节点负责写数据,从节点负责读数据,主节点定期把数据同步到从节点保证数据的一致性...
    爱情小傻蛋阅读 959评论 0 0
  • -----------updated 2019-1-30------------ 近期笔者发现VSCode在vim...
    snow4web阅读 40,249评论 18 33
  • 凉拌豆角 食材: 豆角250g,大蒜5瓣,红辣椒2-3个,香油10g,姜,老干妈辣椒酱或辣椒油一大勺,生抽10g,...
    味博士阅读 250评论 0 2