最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Mysql的主從同步/復(fù)制的原理分析

 更新時間:2025年06月06日 14:39:26   作者:奇怪的爪哇島開發(fā)  
這篇文章主要介紹了Mysql的主從同步/復(fù)制的原理分析,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

為什么要主從同步?

  • 數(shù)據(jù)容災(zāi)、備份。當(dāng)我們的數(shù)據(jù)庫只使用一臺服務(wù)時,如果我們的數(shù)據(jù)庫遭到破壞,例如黑客的攻擊、人為操作的失誤等等情況。這時候我們就可以在一定程度上保障我們數(shù)據(jù)庫的恢復(fù)。
  • 緩解 MySQL 主服務(wù)的壓力。主服務(wù)器寫數(shù)據(jù),從服務(wù)器讀數(shù)據(jù)(讀寫分離)。

Mysql主從同步架構(gòu)有哪些?

一主一從/多從架構(gòu)

  • 適用于讀多寫少

雙主/多主

  • 適用于讀寫均勻,同時整體的并發(fā)量也不算低,至少超出了單庫的承載閾值

多主一從

  • 適用于寫大于讀

級聯(lián)復(fù)制架構(gòu)

  • 存在兩層從庫,這實際上屬于一主多從架構(gòu)的升級版,畢竟如果一個主節(jié)點存在多個從節(jié)點時,多個從節(jié)點都會同時去主節(jié)點拉取新數(shù)據(jù),如果數(shù)據(jù)量較大,就會導(dǎo)致主節(jié)點的I/O負(fù)載過高,因此這種級聯(lián)復(fù)制架構(gòu)要解決的問題,也就是多個從庫會對主庫造成太大壓力的問題。
  • 下面會根據(jù)原理介紹為什么級聯(lián)復(fù)制架構(gòu)更好

主從架構(gòu),都會存在致命硬傷,同時也會存在些許問題需要解決:

  • 硬傷:木桶效應(yīng),一個主從集群中所有節(jié)點的容量,受限于存儲容量最低的哪臺服務(wù)器。
  • 數(shù)據(jù)一致性問題:由于同步復(fù)制數(shù)據(jù)的過程是基于網(wǎng)絡(luò)傳輸完成的,所以存儲延遲性。
  • 腦裂問題:從節(jié)點會通過心跳機(jī)制,發(fā)送網(wǎng)絡(luò)包來判斷主機(jī)是否存活,網(wǎng)絡(luò)故障情況下會產(chǎn)生多主。

Mysql主從復(fù)制的原理/整體流程

  • master 服務(wù)器會將 SQL 記錄通過多 dump 線程寫入到 binary log 中。
  • 主庫會為每個從庫創(chuàng)建一個專屬的 dump 線程。
  • slave 服務(wù)器開啟一個 io thread 線程向服務(wù)器發(fā)送請求,向 master 服務(wù)器請求 binary log。master 服務(wù)器在接收到請求之后,根據(jù)偏移量將新的 binary log 發(fā)送給 slave 服務(wù)器。
  • slave 服務(wù)器收到新的 binary log 之后,寫入到自身的 relay log 中,這就是所謂的中繼日志。
  • slave 服務(wù)器,單獨開啟一個 sql thread 讀取 relay log 之后,寫入到自身數(shù)據(jù)中。

級聯(lián)復(fù)制架構(gòu)為什么好?

級聯(lián)復(fù)制架構(gòu)好的原因大家可以從這個圖中可以看出,主庫會為每個從庫建立一個Dump線程,而Dump線程又擔(dān)負(fù)著重要的作用:將監(jiān)聽到的數(shù)據(jù)通過網(wǎng)絡(luò)傳輸發(fā)送給從庫??上攵绻麖膸爝^多對給主庫帶來巨大的IO壓力,那如果只給一個從庫發(fā)送數(shù)據(jù),并且這個從庫又擔(dān)任其他從庫的復(fù)制職責(zé),這樣就會減輕我們主庫的壓力,從而提高我們主庫的性能。

Mysql主從復(fù)制注意點

從庫 I/O 線程主要職責(zé)是“接收 + 寫 relay log

  • 連接到主庫并請求binlog內(nèi)容
  • 接收主庫dump線程發(fā)送的binlog事件
  • 將接收到的binlog事件寫入從庫的relay log(中繼日志)
  • 更新從庫的master info信息(記錄已讀取的主庫binlog位置)
  • 斷點續(xù)傳:如果連接中斷,IO線程會按照配置的重試策略定期嘗試重新連接

主庫 dump 線程負(fù)責(zé)從 binlog 中讀取變更數(shù)據(jù),并“源源不斷推送”給從庫。

  • 等待從庫連接并發(fā)送binlog位置請求
  • 根據(jù)從庫請求的binlog文件名和位置(或GTID)定位讀取點
  • 以事件(event)為單位讀取binlog內(nèi)容
  • 將事件發(fā)送給從庫的I/O線程
  • 在沒有新事件時進(jìn)入等待狀態(tài)(不是持續(xù)推送)
  • 即使主庫沒有數(shù)據(jù)變化,主庫 dump 線程 也會根據(jù) master_heartbeat_period 發(fā)送一個 Heartbeat log event 給 從庫 IO 線程,作為 binlog 的一部分傳輸,用來維持連接活躍、防止超時斷線。
  • 主庫是怎么判斷從庫有沒有數(shù)據(jù)?
  • 主庫不判斷!是從庫告訴主庫它需要從哪個位置開始同步!

MySQL 支持三種 binlog 格式(也就是傳輸給從庫的數(shù)據(jù)格式)

STATEMENT (不推薦,有風(fēng)險)

  • 最早期的方式,記錄執(zhí)行的原始 SQL 語句
  • 優(yōu)點:可讀(看得懂)、日志體積小、性能開銷小
  • 缺點:有副作用可能不一致(如 UUID、now())

ROW(依舊是邏輯日志)

  • 不記錄 SQL,而是記錄每一行數(shù)據(jù)的變更

對比redolog

  • redolog:表空間X,頁號Y,偏移量Z處的數(shù)據(jù)從0x1234改為0x5678
  • redolog記錄的是具體的物理存儲位置而ROW僅存儲表信息以及數(shù)據(jù)因此依舊是邏輯日志(這里大家不要混淆以為記錄數(shù)據(jù)就是物理日志)
  • 記錄信息:表的 database name + table name、表的 列結(jié)構(gòu)、對應(yīng)數(shù)據(jù)行的變化
  • 優(yōu)點:準(zhǔn)確,幾乎無副作用問題
  • 缺點:日志體積大、不可讀(二進(jìn)制)、性能開銷大(行變更多則更慢)

MIXED

  • 自動在 STATEMENT 和 ROW 之間切換,MySQL 自行判斷

主從復(fù)制數(shù)據(jù)的模式(重點)

相信大家看有的博客說Mysql主從模式三種或有四種模式的,錯大錯特錯,其實就兩種模式,其他兩種是基于第二個模式配置出來的,下面給大家具體介紹一下:

異步復(fù)制(默認(rèn))

  • 客戶端發(fā)送請求先寫入主庫并返回客戶端,然后再異步同步給從庫
  • 優(yōu)點:返回給客戶端快,不會因為同步從庫帶來阻塞
  • 缺點:主從數(shù)據(jù)不一致的風(fēng)險

半同步模式(推薦)

  • 在異步同步的基礎(chǔ)上等待從庫返回結(jié)果再返回給客戶端
  • 優(yōu)點:極大的保證了主庫和從庫的數(shù)據(jù)一致性
  • 缺點:對客戶端的阻塞帶來影響

內(nèi)部細(xì)節(jié)

  • 如果從庫相應(yīng)時間過長默認(rèn)10秒,會切換為異步同步模式

同時為了避免網(wǎng)絡(luò)延遲造成主庫長時間收不到從庫的ACK,因此在配置半同步式復(fù)制時,會有一個rpl_semi_sync_master_timeout參數(shù)來控制超時時間,其默認(rèn)值是10000ms/10s,如若主庫在10s內(nèi)依舊未收到從庫的ACK,則會將復(fù)制模式切換成異步模式,切成異步模式后,會在后續(xù)網(wǎng)絡(luò)正常后再次切回半同步模式。

  • 對于多個從庫節(jié)點可以配置有多少個從庫返回就給客戶端響應(yīng)

5.7版本后對主從一致性保障策略

AFTER_SYNC(默認(rèn),增強(qiáng)半同步復(fù)制)【其他博客的第三種模式】

當(dāng)主庫未收到從庫的ACK之前,也不會在主庫上提交事務(wù),也就是保證了主從節(jié)點的數(shù)據(jù)強(qiáng)一致性,解決了after-commit中存在的問題。

AFTER_COMMIT(傳統(tǒng)半同步復(fù)制,可能出現(xiàn)數(shù)據(jù)不一致)

  • 主庫在未收到從庫的ACK之前,雖然不會給客戶端返回寫入成功,但本質(zhì)上在MySQL中會提交事務(wù),也就是主庫中的其他事務(wù)是可以看見對應(yīng)數(shù)據(jù)的,當(dāng)此時出現(xiàn)宕機(jī)時,就會導(dǎo)致舊主上能查詢出的數(shù)據(jù),在新主(原本的從庫)上無法查詢出來了。
  • 兩者之間的區(qū)別就在于:對主從節(jié)點的數(shù)據(jù)嚴(yán)格性不同,一般情況下,無損復(fù)制會比傳統(tǒng)半同步復(fù)制開銷更大一些,因為事務(wù)遲遲不提交,會導(dǎo)致對應(yīng)的鎖資源不會主動釋放,其他需要獲取對應(yīng)鎖資源的事務(wù)只能阻塞等待,這會造成主庫的整體性能出現(xiàn)一定影響。

同步復(fù)制(本身不支持,需通過半同步復(fù)制設(shè)置為等待所有從庫【其他博客中第四種模式】

  • 對于同步復(fù)制而言,Master主機(jī)將事件發(fā)送給Slave主機(jī)后會觸發(fā)一個等待,直到所有Slave節(jié)點(如果有多個Slave)返回數(shù)據(jù)復(fù)制成功的信息給Master。這種復(fù)制方式最安
  • 全,但是同時,效率也是最差的。

Mysql對于從庫的一些優(yōu)化/策略

  • 從庫的執(zhí)行策略

延遲復(fù)制

延遲復(fù)制通常用于一些特殊場景,它可以支持從庫數(shù)據(jù)的延遲同步,也就是當(dāng)從庫上的I/O線程,將主庫的Bin-log日志請求回來后,從節(jié)點的SQL線程并不會立刻解析日志執(zhí)行,而是等待一段時間后再解析日志執(zhí)行,這個等待的時間可以由開發(fā)者來配置,一般建議設(shè)為3~6小時之間。

那延遲復(fù)制的好處在于什么呢?

可以防止誤刪操作,如若在主庫上不小心誤刪了大量數(shù)據(jù)、表、庫或其他數(shù)據(jù)庫對象,因為從庫并不是立即執(zhí)行同步過去的記錄,因此可以及時通過從節(jié)點上的數(shù)據(jù)回滾數(shù)據(jù)。除此之外,也能對一些線上Bug進(jìn)行實時觀測,比如一個無法復(fù)現(xiàn)的故障問題發(fā)生時,如果發(fā)現(xiàn)時還在配置的延遲復(fù)制時間內(nèi),則可以去到從庫上觀察。

  • 從庫的優(yōu)化手段并行復(fù)制(mysql8.0更完善)

GTID復(fù)制(為什么要先說GTID,因為并行復(fù)制是基于組復(fù)制,而組復(fù)制是基于GTID)

  • 在傳統(tǒng)的主從架構(gòu)中,當(dāng)需要發(fā)生主從切換時,需要開發(fā)/運(yùn)維人員手動找到Bin-log的POS同步點,然后執(zhí)行change master to [new-master-pos]命令,將其他從節(jié)點指向新主庫,但每個從節(jié)點可能同步數(shù)據(jù)的進(jìn)度都不一致,因此每個從節(jié)點都需要去找到它上次的POS點,然后指向新主庫,這個工作是不是聽起來就比較繁雜?答案是Yes,不過到了MySQL5.6版本后,開啟了GTID復(fù)制后,則無需手動尋找POS點!
  • GTID(Global Transaction ID)也就是全局事務(wù)標(biāo)識符的意思,它由節(jié)點UUID+事務(wù)ID兩部分組成,MySQL在第一次啟動時都會利用UUID隨機(jī)生成一個server_id,還記得在之前的《MVCC機(jī)制》中聊過的事務(wù)ID嘛?MySQL會對每一個寫事務(wù)都分配一個順序遞增的值作為事務(wù)ID,而GTID則是由這兩玩意兒組成的,格式為server_uuid:trx_id。
  • 當(dāng)主庫的事務(wù)有了這個全局事務(wù)標(biāo)識后,再發(fā)生主從切換時就無需手動尋點了,僅需要執(zhí)行change master to master_auto_position = 1這條命令即可,它會自動去新主庫上尋找數(shù)據(jù)的同步點,也就是MySQL自身就具備斷點復(fù)制的功能。

為什么需要用GTID代替POS同步點呢?

因為同一個主從集群中,所有節(jié)點加入集群的時間可能會不同

假設(shè)這個集群中每個節(jié)點加入的時間都不一致

  • master:日志文件中的同步點POS=1200。
  • slave1:日志文件中的同步點POS=1100。
  • slave2:日志文件中的同步點POS=800。
  • slave3:日志文件中的同步點POS=200。

此時假設(shè)master節(jié)點宕機(jī)或故障了,slave1成為了新主,那么slave2、slave3也應(yīng)該成為新主slave1的從節(jié)點,但此刻問題就來了:原本slave2、slave3的POS同步點是基于master中的日志而言的,但現(xiàn)在主節(jié)點變成了slave1,這時slave2、slave3如何去尋找自己在slave1中的POS點呢?顯然MySQL無法自己完成該工作,因此需要人工指定同步點才行。

而GTID出現(xiàn)的原因,就是為了解決上述這個問題,但具體怎么解決的呢?

GTID的工作過程

master在更新數(shù)據(jù)時,會為每一個寫事務(wù)分配一個全局的GTID,并記錄到Bin-log中。

slave節(jié)點的I/O線程拉取數(shù)據(jù)時,會將讀到的記錄寫到relay-log中,并設(shè)置gtid_next值。

slave節(jié)點的SQL線程執(zhí)行前,會讀取gtid_next值得知接下來該解析哪條日志并執(zhí)行。

slave節(jié)點的SQL線程在執(zhí)行時,會先比對自身的Bin-log日志中是否有對應(yīng)的GTID:

  • 有:意味著該GTID對應(yīng)的事務(wù)已經(jīng)執(zhí)行過了,slave會自動忽略掉這條記錄。
  • 沒有:SQL解析該GTID對應(yīng)的relay-log記錄并執(zhí)行,再將GTID記錄到Bin-log。

GTID自動尋找同步點的原理

  • 開啟GTID后,從庫會基于它來復(fù)制主庫的數(shù)據(jù),此時發(fā)生了主從切換,假設(shè)這時主從集群中有多個從節(jié)點,MySQL首先會選擇距離master的GTID最近的從節(jié)點作為新主,然后將其他從節(jié)點轉(zhuǎn)變?yōu)樾轮鞯膹膸欤渌麖膸鞎鶕?jù)自身gtid_next值,去新主的日志文件中做對比,然后找到各自的同步點,繼續(xù)從新主中復(fù)制數(shù)據(jù)。
  • 因為MySQL挑選的是和舊主GTID值,最接近的從節(jié)點作為新主,也就意味著作為新主的從節(jié)點,絕對會比其他從節(jié)點的數(shù)據(jù)要完善,因此新主中的GTID值也是最大的!同時,每個從節(jié)點中都存在一個gtid_next值,記錄著自身下一次要同步數(shù)據(jù)的GTID值,此時剩下的從節(jié)點就可以根據(jù)該值,直接去新主中尋找到自己的同步點位置,從而避免了之前那種手動介入的尷尬場景出現(xiàn)。
  • 不過由于GTID復(fù)制是基于事務(wù)來實現(xiàn)的,這也就代表不支持事務(wù)的存儲引擎無法使用這種機(jī)制,在之前的章節(jié)中也聊過,MySQL眾多存儲引擎中,基本上只有InnoDB支持事務(wù),所以GTID機(jī)制基本上只對InnoDB引擎生效。
  • 組復(fù)制

GTID復(fù)制則是組復(fù)制的實現(xiàn)基礎(chǔ),而組復(fù)制則是并行復(fù)制的基礎(chǔ),那么什么叫做組復(fù)制呢?組復(fù)制是指將一組并行執(zhí)行的事務(wù),全部放入到一個GTID中記錄,后續(xù)從節(jié)點同步數(shù)據(jù)時,會一次性讀取這一組事務(wù)解析并執(zhí)行,與傳統(tǒng)的GTID區(qū)別如下:

  • 傳統(tǒng)的GTID值由節(jié)點ID+事務(wù)ID組成:12EEA4RD6-45AC-667B-33DD-CCC55EF718D:88。
  • 組復(fù)制的GTID通過逗號分隔:12EEA4RD6-45AC-667B-33DD-CCC55EF718D:89, 12EEA4RD6-45AC-667B-33DD-CCC55EF718D:89-94, ......。

MySQL如何實現(xiàn)事務(wù)分組的呢?

  • MySQL提交事務(wù)時內(nèi)部會調(diào)用ordered_commit函數(shù)來處理相關(guān)工作,其函數(shù)執(zhí)行的邏輯流程圖如下:

當(dāng)一個事務(wù)提交時都會調(diào)用ordered_commit函數(shù),首先會將事務(wù)加入等待事務(wù)組,接著會經(jīng)過三個核心步驟:FLUSH、SYNC、COMMIT,對應(yīng)的也會有三個隊列,它們?nèi)叩墓ぷ髟矶即笾孪嗤?/p>

  • ①如果某個事務(wù)進(jìn)入FLUSH隊列時,該隊列還是空的,則這個事務(wù)會擔(dān)任“隊長”的角色。
  • ②當(dāng)后續(xù)其他事務(wù)進(jìn)入隊列時,發(fā)現(xiàn)隊列不為空,則會將提交工作委托給隊長來完成。
  • ③如上圖中的「事務(wù)1」則是隊長,后續(xù)的都是隊員,但隊長不會無限制等待隊員到來:

從隊長加入的時間點開始,當(dāng)超出binlog_group_commit_sync_delay規(guī)定的時間后,就會進(jìn)行一次組提交。

  • 同一時刻只允許一組事務(wù)做這些工作,也就是當(dāng)有另外一組事務(wù)提交時,需要等待上一組事務(wù)提交完成。
  • 在做組提交工作時,會將當(dāng)前事務(wù)組的內(nèi)容記錄到Bin-log日志中,同時會將這組事務(wù)記錄成一個GTID,不同事務(wù)之間通過,逗號分隔(實際過程更為復(fù)雜,這里只做簡單講解)。

并行復(fù)制

在MySQL5.6之前的版本中,從庫同步數(shù)據(jù)時,所有數(shù)據(jù)同步工作都是基于單線程完成的,也就是不管主庫上的數(shù)據(jù)是不是多線程并發(fā)寫入的,從庫上只會有一條SQL線程來執(zhí)行解析執(zhí)行工作。

到了MySQL5.6之后,引入了并行復(fù)制的思想,但5.6中的并行復(fù)制極其雞肋,基本無人問津,因為是基于庫級別的并行復(fù)制,也就是一個從節(jié)點對應(yīng)多個主節(jié)點時,有幾個主節(jié)點就開幾條SQL線程去解析并寫入數(shù)據(jù),即多主一從架構(gòu)中才會用到。

因為官方最初在實現(xiàn)并行復(fù)制時,一直糾結(jié)鎖沖突的問題,所以為了防止并行執(zhí)行時出現(xiàn)數(shù)據(jù)沖突,就造出了上面那種庫級別的并行復(fù)制,為啥要糾結(jié)鎖/數(shù)據(jù)沖突呢?

比如從庫I/O線程在主庫中請求了100條記錄回去,從庫中開100條SQL線程解析并執(zhí)行這些記錄,如果其中有兩條記錄操作的是同一條數(shù)據(jù),就會出現(xiàn)鎖沖突問題。

  • 但上述原因不是最主要的,最主要的是并發(fā)執(zhí)行的順序問題,如果主庫上對于一條數(shù)據(jù)是先改后刪,從庫在并發(fā)執(zhí)行時,因為多線程執(zhí)行的無序性,把執(zhí)行順序改為了先刪后改,這顯然就會導(dǎo)致數(shù)據(jù)沖突,因此變更操作很難實現(xiàn)并行復(fù)制。
  • 到了MySQL5.7中,才基于組復(fù)制技術(shù)實現(xiàn)了真正意義上的并行復(fù)制,因為能夠在同一時間內(nèi)提交的事務(wù),絕對是不存在鎖沖突的,所以可以開啟多條線程同時執(zhí)行一個組中不同的事務(wù),但這個思想是從MariaDB中照抄過來的~

一句話來總結(jié)就是:主庫上是咋樣并發(fā)寫入數(shù)據(jù)的,從庫也會開啟對應(yīng)的線程數(shù)去并發(fā)寫入。

在5.7中官方為這種機(jī)制命名為enhanced multi-threaded slave,簡稱MTS機(jī)制,同時為了兼容5.6版本中的并行復(fù)制,又多加入了一個slave-parallel-type參數(shù):

  • DATABASE:默認(rèn)的并行復(fù)制模式,表示基于庫級別的來完成并行復(fù)制。
  • LOGICAL_CLOCK:表示基于組提交的方式來完成并行復(fù)制。

并行復(fù)制出現(xiàn)的意義是什么?

能夠在很大程度上提升從庫復(fù)制數(shù)據(jù)的速度,也就是能夠讓從庫的數(shù)據(jù)實時性提升,尤其是無損復(fù)制模式中,主節(jié)點需要等待從節(jié)點的ACK才會真正提交事務(wù),從庫使用并行復(fù)制后,能夠在一定程度上解決從庫的復(fù)制延遲問題。

不過雖然5.7中的并行復(fù)制,在一定程度上解決了原有的從庫延遲問題,但如果一個新的從節(jié)點加入集群時,因為要從頭開始同步數(shù)據(jù),這種并行復(fù)制的模式依舊存在效率問題,而到了MySQL8.0中,對于并行復(fù)制技術(shù)提出了真正的解決之道,也就是基于writeset的MTS技術(shù)。

主從數(shù)據(jù)一致性的解決方案

讀寫分離數(shù)據(jù)一致性場景:一個用戶將個人信息修改后,然后再次查看時,發(fā)現(xiàn)個人信息依舊是修改之前的原數(shù)據(jù),這時用戶就有可能再次修改,經(jīng)過反反復(fù)復(fù)多次修改后,用戶發(fā)現(xiàn)依舊未生效

想要解決上述這種讀寫分離導(dǎo)致的數(shù)據(jù)不一致性,主要有四種解決方案:

業(yè)務(wù)邏輯做改變、復(fù)制方式做更改、數(shù)據(jù)庫架構(gòu)做調(diào)整、引入第三方中間件。

改變業(yè)務(wù)邏輯

  • 對業(yè)務(wù)做一定更改,比如當(dāng)用戶立即修改數(shù)據(jù)后,因為在從庫讀不到數(shù)據(jù),所以先顯示一個審核狀態(tài),這樣能夠給出用戶的反饋,從而避免用戶再次重復(fù)操作
  • 這種方式屬于和數(shù)據(jù)不一致妥協(xié)的方案,接受一定的數(shù)據(jù)延遲,不過這種方式并不適用于一些對數(shù)據(jù)實時性要求較高的場景

更改復(fù)制方式

  • 在之前曾聊過MySQL四種數(shù)據(jù)同步復(fù)制的方式,即全同步、異步、半同步與無損復(fù)制,MySQL默認(rèn)會是異步復(fù)制模式,即主節(jié)點寫入數(shù)據(jù)后會立即返回成功的狀態(tài)給客戶端,這樣能夠確保性能達(dá)到最佳,但如果對實時性要求較高,可以將其改為全同步或半同步模式。

調(diào)整數(shù)據(jù)庫架構(gòu)

  • 如果無法接受主從架構(gòu)帶來的短期數(shù)據(jù)不一致,那可以升級服務(wù)器硬件,并將架構(gòu)恢復(fù)成單庫架構(gòu),所有讀寫操作都走單庫完成,這就自然不會出現(xiàn)數(shù)據(jù)不一致問題。
  • 但如果升級硬件配置后,無法承載客戶端的訪問壓力時,可將整體架構(gòu)升級到分庫分表架構(gòu),制定好合適的分片策略和路由鍵,每次讀寫數(shù)據(jù)都根據(jù)業(yè)務(wù)不同,操作不同的庫。

引入第三方中間件

  • 前面聊到的三種方案,多多少少都存在一些局限性,因為要么接受數(shù)據(jù)不一致、要么損失性能、要么使用更高規(guī)模的架構(gòu)處理,但這些方案似乎都存在令人不能接受的后患,那有沒有一種萬全之策來解決這個問題呢?答案是有的,就是引入Canal中間件來監(jiān)控主節(jié)點的Bin-log日志。
  • 在之前講主從同步數(shù)據(jù)原理時,曾講到過,主節(jié)點上存在一個log dump線程會監(jiān)聽Bin-log日志,當(dāng)日志出現(xiàn)變更時會通知從節(jié)點來拉取數(shù)據(jù),而Canal的思想也是一樣的,會監(jiān)控主節(jié)點的Bin-log日志,當(dāng)發(fā)生變更時,就直接去拉取數(shù)據(jù),然后直接推送給從節(jié)點寫入。
  • 但這種方式也無法做到真正的數(shù)據(jù)實時性,畢竟Canal監(jiān)聽變更、拉取數(shù)據(jù)、推送數(shù)據(jù)都需要時間,這部分的時間開銷必然存在,只是它會比從庫去主庫上拉取,速度會更快一些罷了。
  • 一般企業(yè)內(nèi)部都會引入Canal來解決數(shù)據(jù)不一致問題,因為它不僅僅只能解決主從延遲問題,還能解決MySQL-ES、MySQL-Redis.....等多種數(shù)據(jù)不一致的場景
  • 也可以制定某些敏感數(shù)據(jù)走主庫查詢,這樣能夠確保數(shù)據(jù)的實時性,但容易模糊讀寫分離的界限,不過因為不需要引入額外的技術(shù),所以在某些情況下也是個不錯的方案。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論

通榆县| 二连浩特市| 延寿县| 永靖县| 茶陵县| 平江县| 吴旗县| 旺苍县| 东兴市| 诸暨市| 宜都市| 闻喜县| 陕西省| 许昌县| 徐水县| 湘潭县| 渝北区| 闸北区| 金昌市| 盐亭县| 双桥区| 田东县| 呼伦贝尔市| 阿巴嘎旗| 冕宁县| 河南省| 万山特区| 五河县| 鹤山市| 沙河市| 静安区| 新民市| 仙居县| 濮阳市| 汪清县| 黎川县| 公安县| 德惠市| 永嘉县| 蒙城县| 武陟县|