亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MySQL主從延遲問題怎么解決

發布時間:2022-06-30 09:12:01 來源:億速云 閱讀:171 作者:iii 欄目:MySQL數據庫

本篇內容主要講解“MySQL主從延遲問題怎么解決”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“MySQL主從延遲問題怎么解決”吧!

MySQL主從延遲問題怎么解決

什么是主從延遲

在討論如何解決主從延遲之前,我們先了解下什么是主從延遲。

為了完成主從復制,從庫需要通過 I/O 線程獲取主庫中 dump 線程讀取的 binlog 內容并寫入到自己的中繼日志 relay log 中,從庫的 SQL 線程再讀取中繼日志,重做中繼日志中的日志,相當于再執行一遍 SQL,更新自己的數據庫,以達到數據的一致性

與數據同步有關的時間點主要包括以下三個:

  1. 主庫執行完一個事務,寫入 binlog,將這個時刻記為 T1;

  2. 之后傳給從庫,將從庫接收完這個 binlog 的時刻記為 T2;

  3. 從庫執行完成這個事務,將這個時刻記為 T3。

所謂主從延遲,就是同一個事務,從庫執行完成的時間與主庫執行完成的時間之差,也就是 T3 - T1

可以在備庫上執行 show slave status 命令,它的返回結果里面會顯示 seconds_behind_master,用于表示當前備庫延遲了多少秒。
seconds_behind_master 的計算方法是這樣的:

  1. 每個事務的 binlog 里面都有一個時間字段,用于記錄主庫上寫入的時間;

  2. 備庫取出當前正在執行的事務的時間字段的值,計算它與當前系統時間的差值,得到 seconds_behind_master

在網絡正常的時候,日志從主庫傳給從庫所需的時間是很短的,即 T2 - T1 的值是非常小的。也就是說,網絡正常情況下,主從延遲的主要來源是從庫接收完 binlog 和執行完這個事務之間的時間差。

由于主從延遲的存在,我們可能會發現,數據剛寫入主庫,結果卻查不到,因為可能還未同步到從庫。主從延遲越嚴重,該問題也愈加明顯。

主從延遲的來源

主庫和從庫在執行同一個事務的時候出現時間差的問題,主要原因包括但不限于以下幾種情況:

  • 有些部署條件下,從庫所在機器的性能要比主庫性能差

  • 從庫的壓力較大,即從庫承受了大量的請求。

  • 執行大事務。因為主庫上必須等事務執行完成才會寫入 binlog,再傳給備庫。如果一個主庫上語句執行 10 分鐘,那么這個事務可能會導致從庫延遲 10 分鐘。

  • 從庫的并行復制能力

主從延遲的解決方案

解決主從延遲主要有以下方案:

  1. 配合 semi-sync 半同步復制

  2. 一主多從,分攤從庫壓力;

  3. 強制走主庫方案(強一致性);

  4. sleep 方案:主庫更新后,讀從庫之前先 sleep 一下;

  5. 判斷主備無延遲方案(例如判斷 seconds_behind_master 參數是否已經等于 0、對比位點);

  6. 并行復制 — 解決從庫復制延遲的問題;

這里主要介紹我在項目中使用的幾種方案,分別是半同步復制、實時性操作強制走主庫、并行復制

semi-sync 半同步復制

MySQL 有三種同步模式,分別是:

「異步復制」:MySQL 默認的復制即是異步的,主庫在執行完客戶端提交的事務后會立即將結果返給客戶端,并不關心從庫是否已經接收并處理。這樣就會有一個問題,一旦主庫宕機,此時主庫上已經提交的事務可能因為網絡原因并沒有傳到從庫上,如果此時執行故障轉移,強行將從提升為主,可能導致新主上的數據不完整。

「全同步復制」:指當主庫執行完一個事務,并且所有的從庫都執行了該事務,主庫才提交事務并返回結果給客戶端。因為需要等待所有從庫執行完該事務才能返回,所以全同步復制的性能必然會收到嚴重的影響。

「半同步復制」:是介于全同步復制與全異步復制之間的一種,主庫只需要等待至少一個從庫接收到并寫到 Relay Log 文件即可,主庫不需要等待所有從庫給主庫返回 ACK。主庫收到這個 ACK 以后,才能給客戶端返回 “事務完成” 的確認。

MySQL 默認的復制是異步的,所以主庫和從庫的數據會有一定的延遲,更重要的是異步復制可能會引起數據的丟失。但是全同步復制又會使得完成一個事務的時間被拉長,帶來性能的降低。因此我把目光轉向半同步復制。從 MySQL 5.5 開始,MySQL 以插件的形式支持 semi-sync 半同步復制

相對于異步復制,半同步復制提高了數據的安全性,減少了主從延遲,當然它也還是有一定程度的延遲,這個延遲最少是一個 TCP/IP 往返的時間。所以,半同步復制最好在低延時的網絡中使用

需要注意的是:

  • 主庫和從庫都要啟用半同步復制才會進行半同步復制功能,否則主庫會還原為默認的異步復制。

  • 如果在等待過程中,等待時間已經超過了配置的超時時間,沒有收到任何一個從庫的 ACK,那么此時主庫會自動轉換為異步復制。當至少一個半同步從節點趕上來時,主庫便會自動轉換為半同步復制。

半同步復制的潛在問題

在傳統的半同步復制中(MySQL 5.5 引入),主庫寫數據到 binlog,并且執行 commit 提交事務后,會一直等待一個從庫的 ACK,即從庫寫入 Relay Log 后,并將數據落盤,再返回給主庫 ACK,主庫收到這個 ACK 以后,才能給客戶端返回 “事務完成” 的確認。

MySQL主從延遲問題怎么解決

這樣會出現一個問題,就是實際上主庫已經將該事務 commit 到了存儲引擎層,應用已經可以看到數據發生了變化,只是在等待返回而已。如果此時主庫宕機,可能從庫還沒寫入 Relay Log,就會發生主從庫數據不一致

為了解決上述問題,MySQL 5.7 引入了增強半同步復制。針對上面這個圖,“Waiting Slave dump” 被調整到了 “Storage Commit” 之前,即主庫寫數據到 binlog 后,就開始等待從庫的應答 ACK,直到至少一個從庫寫入 Relay Log 后,并將數據落盤,然后返回給主庫 ACK,通知主庫可以執行 commit 操作,然后主庫再將事務提交到事務引擎層,應用此時才可以看到數據發生了變化。

MySQL主從延遲問題怎么解決

當然之前的半同步方案同樣支持,MySQL 5.7.2 引入了一個新的參數 rpl_semi_sync_master_wait_point 進行控制。這個參數有兩種取值:

  1. AFTER_SYNC:這個是新的半同步方案,Waiting Slave dump 在 Storage Commit 之前。

  2. AFTER_COMMIT:這個是老的半同步方案。

在 MySQL 5.5 - 5.6 使用 after_commit 的模式下,客戶端事務在存儲引擎層提交后,在主庫等待從庫確認的過程中,主庫宕機了。此時,結果雖然沒有返回給當前客戶端,但事務已經提交了,其他客戶端會讀取到該已提交的事務。如果從庫沒有接收到該事務或者未寫入 relay log,同時主庫宕機了,之后切換到備庫,那么之前讀到的事務就不見了,出現了幻讀,也就是數據丟失了。

MySQL 5.7 默認值則是 after_sync,主庫將每個事務寫入 binlog,傳給從庫并刷新到磁盤 (relay log)。主庫等到從庫返回 ack 之后,再提交事務并且返回 commit OK 結果給客戶端。 即使主庫 crash,所有在主庫上已經提交的事務都能保證已經同步到從庫的 relay log 中,解決了 after_commit 模式帶來的幻讀和數據丟失問題,故障切換時數據一致性將得到提升。因為從庫沒有寫入成功的話主庫也不會提交事務。并且在 commit 之前等待從庫 ACK,還可以堆積事務,有利于 group commit 組提交,有利于提升性能。

但這樣也會有個問題,假設主庫在存儲引擎提交之前掛了,那么很明顯這個事務是不成功的,但由于對應的 Binlog 已經做了 Sync 操作,從庫已經收到了這些 Binlog,并且執行成功,相當于在從庫上多了數據(從庫上有該數據而主庫沒有),也算是有問題的,但多了數據一般不算嚴重的問題。它能保證的是不丟數據,多了數據總比丟數據要好。

一主多從

如果從庫承擔了大量查詢請求,那么從庫上的查詢操作將耗費大量的 CPU 資源,從而影響了同步速度,造成主從延遲。那么我們可以多接幾個從庫,讓這些從庫來共同分擔讀的壓力。

簡而言之,就是加機器,方法簡單粗暴,但也會帶來一定成本。

強制走主庫方案

如果某些操作對數據的實時性要求比較苛刻,需要反映實時最新的數據,比如說涉及金錢的金融類系統、在線實時系統、又或者是寫入之后馬上又讀的業務,這時我們就得放棄讀寫分離,讓此類的讀請求也走主庫,這就不存延遲問題了。

當然這也失去了讀寫分離帶給我們的性能提升,需要適當取舍。

并行復制

一般 MySQL 主從復制有三個線程參與,都是單線程:Binlog Dump 線程、IO 線程、SQL 線程。復制出現延遲一般出在兩個地方:

  • SQL 線程忙不過來(主要原因);

  • 網絡抖動導致 IO 線程復制延遲(次要原因)。

日志在備庫上的執行,就是備庫上 SQL 線程執行中繼日志(relay log)更新數據的邏輯。

在 MySQL 5.6 版本之前,MySQL 只支持單線程復制,由此在主庫并發高、TPS 高時就會出現嚴重的主備延遲問題。從 MySQL 5.6 開始有了多個 SQL 線程的概念,可以并發還原數據,即并行復制技術。這可以很好的解決 MySQL 主從延遲問題。

從單線程復制到最新版本的多線程復制,中間的演化經歷了好幾個版本。其實說到底,所有的多線程復制機制,都是要把只有一個線程的 sql_thread,拆成多個線程,也就是都符合下面的這個多線程模型:

coordinator 就是原來的 sql_thread,不過現在它不再直接更新數據了,只負責讀取中轉日志和分發事務。真正更新日志的,變成了 worker 線程。而 worker 線程的個數,就是由參數 slave_parallel_workers 決定的。

由于 worker 線程是并發運行的,為了保證事務的隔離性以及不會出現更新覆蓋問題,coordinator 在分發的時候,需要滿足以下這兩個基本要求:

  1. 更新同一行的兩個事務,必須被分發到同一個 worker 中(避免更新覆蓋)

  2. 同一個事務不能被拆開,必須放到同一個 worker 中(保證事務隔離性)

各個版本的多線程復制,都遵循了這兩條基本原則。

以下是按表分發策略和按行分發策略,可以幫助理解 MySQL 官方版本并行復制策略的迭代:

  • 按表分發策略:如果兩個事務更新不同的表,它們就可以并行。因為數據是存儲在表里的,所以按表分發,可以保證兩個 worker 不會更新同一行。

    • 按表分發的方案,在多個表負載均勻的場景里應用效果很好,但缺點是:如果碰到熱點表,比如所有的更新事務都會涉及到某一個表的時候,所有事務都會被分配到同一個 worker 中,就變成單線程復制了。

  • 按行分發策略:如果兩個事務沒有更新相同的行,則它們在備庫上可以并行。顯然,這個模式要求 binlog 格式必須是 row。

    • 按行并行復制的方案解決了熱點表的問題,并行度更高,但缺點是:相比于按表并行分發策略,按行并行策略在決定線程分發的時候,需要消耗更多的計算資源。

MySQL 5.6 版本的并行復制策略

MySQL 5.6 版本,支持了并行復制,只是支持的粒度是按庫并行(基于 Schema)

其核心思想是:不同 schema 下的表并發提交時的數據不會相互影響,即從庫可以對 relay log 中不同的 schema各分配一個類似 SQL 線程功能的線程,來重放 relay log 中主庫已經提交的事務,保持數據與主庫一致。

如果在主庫上有多個 DB,使用這個策略對于從庫復制的速度可以有比較大的提升。但通常情況下都是單庫多表,那基于庫的并發也就沒有什么作用,根本無法并行重放,所以這個策略用得并不多。

MySQL 5.7 的并行復制策略

MySQL 5.7 引入了基于組提交的并行復制,參數 slave_parallel_workers 設置并行線程數,由參數 slave-parallel-type 來控制并行復制策略:

  • 配置為 DATABASE,表示使用 MySQL 5.6 版本的按庫并行策略;

  • 配置為 LOGICAL_CLOCK,表示使用基于組提交的并行復制策略;

利用 binlog 的組提交 (group commit) 機制,可以得出一個組提交的事務都是可以并行執行的,原因是:能夠在同一組里提交的事務,一定不會修改同一行(由于 MySQL 的鎖機制),因為事務已經通過鎖沖突的檢驗了

基于組提交的并行復制具體流程如下

  1. 在一組里面一起提交的事務,有一個相同的 commit_id,下一組就是 commit_id+1;commit_id 直接寫到 binlog 里面;

  2. 傳到備庫應用的時候,相同 commit_id 的事務分發到多個 worker 執行;

  3. 這一組全部執行完成后,coordinator 再去取下一批執行。

所有處于 prepare 和 commit 狀態的事務都是可以在備庫上并行執行的

binlog 的組提交的兩個有關參數:

  • binlog_group_commit_sync_delay 參數,表示延遲多少微秒后才調用 fsync 刷盤;

  • binlog_group_commit_sync_no_delay_count 參數,表示累積多少次以后才調用 fsync。

這兩個參數是用于故意拉長 binlog 從 write 到 fsync 的時間,以此減少 binlog 的寫盤次數。在 MySQL 5.7 的并行復制策略里,它們可以用來制造更多的“同時處于 prepare 階段的事務”。可以考慮調整這兩個參數值,來達到提升備庫復制并發度的目的。

到此,相信大家對“MySQL主從延遲問題怎么解決”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

清流县| 永定县| 长顺县| 调兵山市| 崇明县| 克什克腾旗| 比如县| 株洲市| 鄯善县| 肃宁县| 巴南区| 邯郸县| 五华县| 淳化县| 徐州市| 宝丰县| 盐津县| 永靖县| 镇赉县| 仁怀市| 乌苏市| 洱源县| 松潘县| 富平县| 阳朔县| 简阳市| 深圳市| 漳浦县| 临江市| 清涧县| 高青县| 宣化县| 天镇县| 雷州市| 闸北区| 谢通门县| 通山县| 松溪县| 泾源县| 尤溪县| 漳浦县|