您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關如何解析Redis中的集群主從復制原理,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
本篇文章帶大家深入理解下Redis集群主從復制原理,希望對大家有所幫助!
1、實現更高性能:高并發應用,單機性能會有影響,需要更多redis服務器分擔壓力,實現負載均衡
2、實現高可用:如果單機,防止宕機/硬件故障
3、實現可擴展:單機內存和硬件有限制,實現橫向擴展
冗余或者分片存儲實現如上特性。
和Kafka,Mysql,Rocketmq一樣,redis支持集群部署,集群節點有master和slave之分,主節點是master,從節點是slave(最新叫副本replica).slave會通過復制機制,從master同步最新的數據。Redis提供了非常方便的命令開啟主從復制。【相關推薦:Redis視頻教程】
如何配置開啟主從復制?
以本機搭建偽集群為例,6379端口是從節點,6378作為主節點。
1、從節點redis.conf配置 replicaof masterip masterport 從節點啟動后,自動連接到master節點,開始同步數據.
源碼說明:
//每1s執行這個方法 void replicationCron(void) { ... //檢查是否需要連接到master 如果是REPL_STATE_CONNECT狀態,必須連接到master //#define REPL_STATE_CONNECT 1 Must connect to master if (server.repl_state == REPL_STATE_CONNECT) { serverLog(LL_NOTICE,"Connecting to MASTER %s:%d", server.masterhost, server.masterport); //和master創建連接 if (connectWithMaster() == C_OK) { serverLog(LL_NOTICE,"MASTER <-> REPLICA sync started"); } } //發送ping命令給slave if ((replication_cron_loops % server.repl_ping_slave_period) == 0 && listLength(server.slaves)) { /* Note that we don't send the PING if the clients are paused during * a Redis Cluster manual failover: the PING we send will otherwise * alter the replication offsets of master and slave, and will no longer * match the one stored into 'mf_master_offset' state. */ int manual_failover_in_progress = server.cluster_enabled && server.cluster->mf_end && clientsArePaused(); if (!manual_failover_in_progress) { ping_argv[0] = createStringObject("PING",4); replicationFeedSlaves(server.slaves, server.slaveseldb, ping_argv, 1); decrRefCount(ping_argv[0]); } } //發送換行符到所有slave,告訴slave等待接收rdb文件 listRewind(server.slaves,&li); while((ln = listNext(&li))) { client *slave = ln->value; int is_presync = (slave->replstate == SLAVE_STATE_WAIT_BGSAVE_START || (slave->replstate == SLAVE_STATE_WAIT_BGSAVE_END && server.rdb_child_type != RDB_CHILD_TYPE_SOCKET)); if (is_presync) { if (write(slave->fd, "\n", 1) == -1) { /* Don't worry about socket errors, it's just a ping. */ } } } ... }
3、全量復制流程-支持無盤復制或者rdb持久化復制
當slave連接到master后,使用psync(以前是sync命令,它不允許部分重新同步,所以現在改用PSYNC)命令初始化復制,將主節點replication id和處理過最大offset發送到master。
master節點擁有如下兩個屬性,一個replication id(標志實例),一個offset(標志寫入從節點的stream)
Replication ID, offset
如果主節點緩沖區中沒有足夠的積壓工作,或者如果復制副本引用的是不再已知的歷史記錄(復制ID),則會發生完全重新同步
源碼說明:
//沒有在rdb進程,沒有aof重寫進程 if (server.rdb_child_pid == -1 && server.aof_child_pid == -1) { time_t idle, max_idle = 0; int slaves_waiting = 0; int mincapa = -1; listNode *ln; listIter li; listRewind(server.slaves,&li); while((ln = listNext(&li))) { client *slave = ln->value; //判斷slave是否是等待bgsave狀態 if (slave->replstate == SLAVE_STATE_WAIT_BGSAVE_START) { //多久沒有發送心跳或查詢數據了 空閑時間間隔 idle = server.unixtime - slave->lastinteraction; if (idle > max_idle) max_idle = idle; slaves_waiting++; mincapa = (mincapa == -1) ? slave->slave_capa : (mincapa & slave->slave_capa); } } if (slaves_waiting && (!server.repl_diskless_sync || max_idle > server.repl_diskless_sync_delay)) { /* Start the BGSAVE. The called function may start a * BGSAVE with socket target or disk target depending on the * configuration and slaves capabilities. */ //bgsave rdb生成 startBgsaveForReplication(mincapa); } }
復制過程中,slave狀態轉換流程。
每次實例作為主實例從頭開始重新啟動,或者將復制副本提升為主實例,都會為此實例生成一個新的復制ID。如果兩個replica的復制id相同,則他們可能在不同的時間,有相同的數據,對于保存最新數據集的給定歷史記錄(復制ID),偏移量作為一個邏輯時間來理解。需要通過Replication ID, offset兩個數據來判斷。用來判斷從節點同步數據到哪了。
1、slave本身有數據,會怎么樣?
slave先刪除自身的數據,再用rdb文件加載。
2、生成rdb文件的過程中,客戶端寫命令怎么處理?
保存到內存緩存中,rdb發送完成后發送到slave。
3、Redis復制如何處理key過期的?
1、副本不會使key過期,而是等待主機使key過期。當主機使key過期(或由于LRU而將其逐出)時,它將合成一個DEL命令,該命令將傳輸到所有副本。
2、但是,由于主機驅動的expire,有時副本可能仍然具有邏輯上已過期的內存密鑰,因為主服務器無法及時提供DEL命令。為了處理這個問題,副本使用它的邏輯時鐘來報告一個key不存在,只用于不違反數據集一致性的讀取操作(因為來自主服務器的新命令將到達)
3、在Lua腳本執行期間,不執行密鑰過期。當Lua腳本運行時,從概念上講,主節點中的時間是凍結的,因此給定的鍵在腳本運行的所有時間內都將存在或不存在。這可以防止key在腳本中間過期,并且需要key才能以保證在數據集中具有相同效果的方式將相同的腳本發送到副本。
一旦復制副本升級為主副本,它將開始獨立地使key過期,并且不需要舊主副本的任何幫助。
1、解決了數據備份的問題,但是rdb文件大,傳輸大文件,恢復時間也長
2、如果master異常,需要手工將replica選舉為master
3、1主多從,1主1從的情況下,還是存在單點問題
4、Redis版本2.8.18后支持無盤復制,性能更高。
1、默認用異步復制,通過異步確認同步的命令數量
2、1個master可以有多個副本
3、副本也可以有自己的副本,從redis4.0開始,副本都會從主節點接收完全相同的復制流
4、復制既可以用于可擴展性,也可以用于只讀查詢的多個副本
關于如何解析Redis中的集群主從復制原理就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。