Redis 主从复制

定义

单个Redis数据库很容易出现单点故障和容量瓶颈问题,Redis支持将主数据库(Master)上的数据复制多份到在多个不同的从数据库(Slave)上,数据流向是单向的 - Master -> Slave。通常主数据进行数据写入操作,从数据库进行读操作,实现数据的读写分离。

实现方式

  1. 命令方式

    • slaveof slavehost # 将 slavehost 将复制为当前Redis数据库的从数据库,异步操作,会将数据库的数据进行清除。
      e.g., 127.0.0.1: 6380 > slaveof 127.0.0.1: 6379 # 127.0.0.1: 6379将会成为127.0.0.1: 6380的主数据库
    • slaveof no one # 取消当前命令执行数据库的复制,以前主数据库已经同步的数据不会清除。
    • info replication # 当前数据库是主还是从数据库的相关信息
  2. 配置 - redis.conf,配置之后需重启

    • slaveof masterip masterport
    • slave-read-only yes

命令传播

执行完全量复制之后,主从数据库之间数据库状态已经相同了。但这个状态并非一成不变,如果主数据库执行了写操作,那么主数据库的数据库状态就会修改,并导致主从数据库状态不再一致。所以为了让主从数据库再次回到一致状态,主数据库需要对从数据库执行命令传播操作:主数据库会将自己执行的写命令,也即是造成主从数据库不一致的那条写命令,发送给从数据库执行,当从数据库执行了相同的写命令之后,主从数据库将再次回到一致状态。

全量复制

全量复制.png
  1. 复制过程
    • 从数据库向主数据库发送PSYNC命令 - 从2.8开始,SYNC替换成PSYNC,提供了完整重同步和部分重同步
    • 收到PSYNC命令后,主数据库将自身的runId和offset传给从数据库,之后主数据库执行BGSAVE命令,在后台生成一个RDB文件,并使用一个缓冲区记录从现在开始执行的所有写命令
    • 当主数据库的BGSAVE命令执行完毕时,主数据库会将BGSAVE命令生成的RDB文件发送给从数据库,从数据库接收并载入这个RDB文件,将自己的数据库状态更新至主数据库执行BGSAVE命令时的数据库状态
    • 主数据库将记录在缓冲区里面的所有写命令发送给从数据库,从数据库执行这些写命令,将自己的数据库状态更新至主数据库数据库当前所处的状态
  2. 开销
    • bgsave时间
    • RDB文件网络传输时间
    • 清空从数据库花费时间
    • 从数据库加载RBD文件花费的时间,并且载入期间,从数据库可能因为阻塞而无法处理客户端请求

部分复制

部分复制.png
  1. 解决问题:处理从数据库断线后的重连问题。当从数据库在断线后重新连接主数据库时,如果条件允许,主数据库可以将主从数据库连接断开期间执行的写命令发送给从数据库,从数据库只要接收并执行这些写命令,就可以将数据库更新至主数据库当前所处的状态。而2.8以前,断连之后还要进行一次SYNC操作。
  2. 复制过程
    • 当从数据库断线后,主数据库会继续把写命令放入到复制积压缓冲区(replication backlog)中
    • 当从数据库重新连上主数据库时,从数据库会通过PSYNC命令将自己的复制偏移量(replication offset)和主数据库的运行ID(run id)发送给主数据库,主数据库会根据这个复制偏移量和运行ID来决定对从数据库执行何种同步操作
    • 如果从数据库发送的运行ID和当前连接的主数据库的运行ID相同,那么说明从数据库断线之前复制的就是当前连接的这个主数据库,主数据库可以继续尝试执行部分复制操作
    • 相反,如果从数据库发送的运行ID和当前连接的主数据库的运行ID并不相同,主数据库将对从数据库执行全量复制操作
    • 如果从数据库的复制偏移量之后的数据(也即是offset+1开始的数据)仍然存在于复制积压缓冲区里面,那么主数据库将对从数据库执行部分复制操作
    • 相反,如果offset之后的数据已经不存在于复制积压缓冲区,那么主数据库将对从数据库执行全量复制操作

扩展

  1. 复制偏移量(replication offset):主数据库和从数据库会分别维护一个复制偏移量:
    • 主数据库每次向从数据库传播N个字节的数据时,就将自己的复制偏移量的值加上N
    • 从数据库每次收到主数据库传播来的N个字节的数据时,就将自己的复制偏移量的值加上N
      对比主从数据库的复制偏移量,可知道主从数据库是否处于一致状态:
    • 如果主从数据库处于一致状态,那么主从数据库两者的偏移量总是相同的
    • 相反,如果主从数据库两者的偏移量并不相同,那么说明主从数据库并未处于一致状态
复制偏移量.png
  1. 复制积压缓冲区(replication backlog):复制积压缓冲区是由主数据库维护的一个固定长度(fixed-size)先进先出(FIFO)队列。当主数据库进行命令传播时,它不仅会将写命令发送给所有从数据库,还会将写命令入队到复制积压缓冲区里面。因此,主数据库的复制积压缓冲区里面会保存着一部分最近传播的写命令,并且复制积压缓冲区会为队列中的每个字节记录相应的复制偏移量


    复制积压缓冲区.png

复制积压缓冲区默认大小为1MB,如果主数据库需要执行大量写命令,又或者主从数据库断线后重连接所需的时间比较长,那么Redis的部分复制功能可能会达不到想要的效果。复制积压缓冲区的最小大小可以根据公式 second*write_size_per_second 来估算:

  • write_size_per_second是主数据库平均每秒产生的写命令数据量。
  • second为从数据库断线后重新连接上主数据库所需的平均时间(以秒计算)

例如,如果主数据库平均每秒产生1 MB的写数据,而从数据库断线之后平均要5秒才能重新连接上主数据库,那么复制积压缓冲区的大小就不能低于5MB。为了安全起见,可以将复制积压缓冲区的大小设为2secondwrite_size_per_second,这样可以保证绝大部分断线情况都能用部分重同步来处理,可以通过修改repl-backlog-size配置进行设置。

  1. 数据库运行ID: 每个Redis数据库,不论主数据库还是从服务,都会有自己的运行ID。运行ID在数据库启动时自动生成,由40个随机的十六进制字符组成,例53b9b28df8042fdc9ab5e3fcbbbabff1d5dce2b3。
    当从数据库对主数据库进行初次复制时,主数据库会将自己的运行ID传送给从数据库,而从数据库则会将这个运行ID保存起来。当从数据库断线并重新连上一个主数据库时,从数据库将向当前连接的主数据库发送之前保存的运行ID。

问题

  1. 读写分离
    • 数据复制延迟
    • 读到过期数据
    • 从数据库故障
  2. 主从数据库配置不一致
    • maxmemory不一致:丢失数据
    • 数据结构优化参数(例如hash-max-ziplist-entries):内存不一致
  3. 规避全量复制
    • 第一次全量复制不可避免 - 尽量低峰(夜间)进行
    • 避免主数据库runId不匹配导致的全量复制
    • 避免复制积压缓冲区不足导致的全量复制 - 修改rel_backlog_size配置
  4. 规避复制风暴
    • 单主数据库复制风暴 - 主数据库重启,多从数据库复制
    • 单机器复制风暴 - 机器有多个主数据库,机器宕机,大量全量复制。避免多个主数据库部署在一个机器上

参考资料

[1] https://coding.imooc.com/class/151.html

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

推荐阅读更多精彩内容

  • 一、Redis主从复制 主从复制:主节点负责写数据,从节点负责读数据,主节点定期把数据同步到从节点保证数据的一致性...
    爱情小傻蛋阅读 943评论 0 0
  • 本篇就一下方面展开分析 如何使用主从复制? 主从复制的原理(重点是全量复制和部分复制、以及心跳机制) 实际应用中需...
    lucode阅读 986评论 0 5
  • 概述 主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后...
    Lin_Shao阅读 267评论 0 0
  • redis主从复制 redis的一主多从能很好地提升性能,但这种系统面临一个很大的一个同步问题,特别是在系统重启,...
    cheng南旧事阅读 201评论 0 0
  • 90天践行3.0的目标: 1)每天番茄钟看书半小时 2)每天冥想 第二十九周目标: [x]1)催卡斯 []2)看完...
    抹茶半拉阅读 166评论 1 1