MySQL主從復制(五):讀寫分離

一主多從架構主要應用場景:讀寫分離。讀寫分離的主要目標是分攤主庫的壓力。

讀寫分離架構


讀寫分離架構一

架構一結構圖:

這種結構模式下,一般會把數據庫的連接信息放在客戶端的連接層,由客戶端主動做負載均衡。也就是說由客戶端來選擇后端數據庫進行查詢。

讀寫分離架構二

架構二結構圖:

該架構模式下,在MySQL和客戶端之間有一個中間代理層proxy, 客戶端只連接proxy, 由proxy根據請求類型和上下文決定請求的分發路由。

兩種架構的區別

1)客戶端直連方案

因為少了一層proxy轉發, 所以查詢性能稍微好一點兒, 并且整體架構簡單, 排查問題更方便。 但是這種方案, 由于要了解后端部署細節, 所以在出現主備切換、 庫遷移等操作的時候, 客戶端都會感知到, 并且需要調整數據庫連接信息。

你可能會覺得這樣客戶端也太麻煩了, 信息大量冗余, 架構很丑。 其實也未必, 一般采用這樣的架構, 一定會伴隨一個負責管理后端的組件, 比如Zookeeper, 盡量讓業務端只專注于業務邏輯開發。

2)帶proxy架構

帶proxy的架構, 對客戶端比較友好。 客戶端不需要關注后端細節, 連接維護、 后端信息維護等工作, 都是由proxy完成的。 但這樣的話, 對后端維護團隊的要求會更高。 而且, proxy也需要有高可用架構。 因此, 帶proxy架構的整體就相對比較復雜。

注:無論使用哪種架構都會遇到主從延遲問題(即在從庫上會讀到系統的一個過期狀態),且主從延遲是不能100%避免的。

問:處理主從延遲有哪些方案?

答:主從延遲處理方案有以下幾種:

  • 強制走主庫方案
  • Sleep方案
  • 判斷主備無延遲方案
  • 配合semi-sync方案
  • 等主庫位點方案
  • 等GTID方案

下面對這幾種方案詳細介紹。

強制走主庫方案


強制走主庫方案思路:對查詢請求進行分類,對于必須要拿到最新結果的請求,強制將其發到主庫上。對于可以讀到舊數據的請求,才將其發到從庫上。

這個方案最大的問題在于, 有時候你會碰到“所有查詢都不能是過期讀”的需求, 比如一些金融類的業務。 這樣的話, 你就要放棄讀寫分離, 所有讀寫壓力都在主庫, 等同于放棄了擴展性。

盡管如此,該方案仍是用的最多的一種方案。

Sleep方案


Sleep方案思路:主庫更新后, 讀從庫之前先sleep一下。 具體的方案就是, 類似于執行一條select sleep(1)命令。

注:這個方案的假設是, 大多數情況下主備延遲在1秒之內, 做一個sleep可以有很大概率拿到最新的數據。

示例:

以賣家發布商品為例, 商品發布后, 用Ajax(Asynchronous JavaScript + XML, 異步JavaScript和XML) 直接把客戶端輸入的內容作為“新的商品”顯示在頁面上, 而不是真正地去數據庫做查詢。

這樣, 賣家就可以通過這個顯示, 來確認產品已經發布成功了。 等到賣家再刷新頁面, 去查看商品的時候, 其實已經過了一段時間, 也就達到了sleep的目的, 進而也就解決了過期讀的問題。

但從嚴格意義上來說,這個方案存在不精確問題。這個不精確主要包含兩層意思:

1)假設一個查詢請求原本可以在0.5s就可以在從庫上拿到正確結果,此時也會等1s。

2)如果延遲超過1s,還是會出現主從延遲。

判斷主備無延遲方案


確保備庫無延遲,通常有以下三種做法:

查看seconds_behind_master確保主備無延遲

每次從庫執行查詢請求前,先執行show slave status\G判斷seconds_behind_master是否已經等于0。 如果還不等于0 , 那就必須等到這個參數變為0才能執行查詢請求。注:seconds_behind_master的單位是秒。show slave status\G結果的部分截圖:

對比位點確保主備無延遲

1)Master_Log_File和Read_Master_Log_Pos, 表示的是讀到的主庫的最新位點。

2)Relay_Master_Log_File和Exec_Master_Log_Pos, 表示的是備庫執行的最新位點。

如果Master_Log_File和Relay_Master_Log_File、 Read_Master_Log_Pos和Exec_Master_Log_Pos這兩組值完全相同, 就表示接收到的日志已經同步完成。

show slave status\G結果部分截圖:

對比GTID集合確保主備無延遲

1)Auto_Position=1 , 表示這對主備關系使用了GTID協議。

2)Retrieved_Gtid_Set, 是備庫收到的所有日志的GTID集合。

3)Executed_Gtid_Set, 是備庫所有已經執行完成的GTID集合。

如果這兩個集合相同, 也表示備庫接收到的日志都已經同步完成。

可見, 對比位點和對比GTID這兩種方法, 都要比判斷seconds_behind_master是否為0更準確。

show slave status\G結果部分截圖:

問:在執行查詢請求之前, 先判斷從庫是否同步完成的方法, 相比于sleep方案, 準確度確實提升了不少, 但還是沒有達到“精確”的程度。 為什么這么說呢?

一個事務的binlog在主備庫之間的狀態:

1)主庫執行完成, 寫入binlog, 并反饋給客戶端。

2)binlog被從主庫發送給備庫, 備庫收到。

3)在備庫執行binlog完成。

上面判斷主備無延遲的邏輯, 是“備庫收到的日志都執行完成了”。 但是, 從binlog在主備之間狀態的分析中, 不難看出還有一部分日志, 處于客戶端已經收到提交確認, 而備庫還沒收到日志的狀態。

示例場景如下:

這時, 主庫上執行完成了三個事務trx1、 trx2和trx3, 其中:

1)trx1和trx2已經傳到從庫, 并且已經執行完成了。

2)trx3在主庫執行完成, 并且已經回復給客戶端, 但是還沒有傳到從庫中。

如果這時候你在從庫B上執行查詢請求, 按照我們上面的邏輯, 從庫認為已經沒有同步延遲, 但還是查不到trx3的。 嚴格地說, 就是出現了主從延遲。

配合semi-sync方案


該方案可以解決“對比GTID集合確保主備無延遲”中提到的不“精確”問題。

semi-sync replication(半同步復制)主備間的狀態:

1)事務提交的時候,主庫把binlog發給從庫。

2)從庫收到binlog后,給主庫返回一個ack,表示收到了。

3)主庫收到這個ack后,才能給客戶端返回“事務完成”的確認。

也就是說,如果啟用了semi-sync, 就表示所有給客戶端發送過確認的事務, 都確保了備庫已經收到了這個日志。

問1:如果主庫掉電的時候,有些binlog還來不及發給從庫,會不會導致系統數據丟失?

1)如果使用的是普通的異步復制模式,則有可能會丟失數據。

2)如果使用的是semi-sync+位點判斷的方案,則可以解決數據丟失問題。

需要注意的是,semi-sync+位點判斷的方案,只對一主一備的場景成立。在一主多從場景中,主庫只要等到一個從庫的ack,就會開始給客戶端返回確認。此時,在從庫上執行查詢請求,有以下兩種情況:

1)如果查詢落在這個響應了ack的從庫上,能夠確保讀到最新數據。

2)如果查詢落到其它從庫上,他們可能還沒有收到最新的日志,就可能會產生主從延遲。

注:如果在業務高峰期, 主庫的位點或者GTID集合更新很快, 那么上面的兩個位點等值判斷就會一直不成立, 很可能出現從庫上遲遲無法響應查詢請求的情況。

問2:當發起一個查詢請求后,如果要求得到準確結果,是否需要等到“主備完全同步”,才能執行查詢請求?

答:不需要。

示例如下:

圖中備庫B下的虛線框, 分別表示relaylog(備庫執行的最新位點)和binlog中的事務。 可以看到, 圖中從狀態1 到狀態4, 一直處于延遲一個事務的狀態。

備庫B一直到狀態4都和主庫A存在延遲, 如果用上面必須等到無延遲才能查詢的方案, select語句直到狀態4都不能被執行。

但是, 其實客戶端是在發完trx1更新后發起的select語句, 我們只需要確保trx1已經執行完成就可以執行select語句了。 也就是說, 如果在狀態3執行查詢請求, 得到的就是預期結果了。

semi-sync+主備無延遲方案,存在兩個問題:

1)一主多從的時候, 在某些從庫執行查詢請求會存在主從延遲問題。

2)在持續延遲的情況下, 可能出現過度等待的問題。

等主庫位點方案


該方案能解決“semi-sync+主備無延遲方案”存在的兩個問題。

下面先來看一條命令:

select master_pos_wait(file, pos[, timeout]);

這條命令的邏輯如下:

1)它是在從庫執行的。

2)參數file和pos指的是主庫上的文件名和位置。

3)timeout可選, 設置為正整數N表示這個函數最多等待N秒。

這條命令返回結果如下:

1)如果執行期間, 備庫同步線程發生異常, 則返回NULL。

2)如果等待超過N秒, 就返回-1。

3)如果剛開始執行的時候, 就發現已經執行過這個位置了, 則返回0。

4)如果返回的是一個正整數M, 表示從命令開始執行, 到應用完file和pos表示的binlog位置, 執行了多少事務。

對于上圖中先執行trx1, 再執行一個查詢請求的邏輯, 要保證能夠查到正確的數據, 我們可以使用這個邏輯:

1)trx1事務更新完成后, 馬上執行show master status得到當前主庫執行到的File和Position。

2)選定一個從庫執行查詢語句。

3)在從庫上執行select master_pos_wait(File, Position, 1)。

4)如果返回值是>=0的正整數, 則在這個從庫執行查詢語句。

5)否則, 到主庫執行查詢語句。

上述邏輯流程圖:

這里我們假設, 這條select查詢最多在從庫上等待1秒。 那么, 如果1秒內master_pos_wait返回一個大于等于0的整數, 就確保了從庫上執行的這個查詢結果一定包含了trx1的數據。

步驟5到主庫執行查詢語句, 是這類方案常用的退化機制(兜底方案)。 因為從庫的延遲時間不可控, 不能無限等待, 所以如果等待超時, 就應該放棄, 然后到主庫去查。

GTID方案


MySQL中同樣提供了一個類似的命令:

select wait_for_executed_gtid_set(gtid_set, 1);

這條命令的邏輯是:

1)等待, 直到這個庫執行的事務中包含傳入的gtid_set, 返回0。

2)超時返回1。

在前面等位點的方案中, 我們執行完事務后, 還要主動去主庫執行show master status。 而MySQL 5.7.6版本開始, 允許在執行完更新類事務后, 把這個事務的GTID返回給客戶端, 這樣等GTID的方案就可以減少一次查詢。

等GTID的執行流程:

1)trx1事務更新完成后, 從返回包直接獲取這個事務的GTID, 記為gtid1。

2)選定一個從庫執行查詢語句。

3)在從庫上執行 select wait_for_executed_gtid_set(gtid1, 1)。

4)如果返回值是0, 則在這個從庫執行查詢語句。

5)否則, 到主庫執行查詢語句。

上述邏輯流程圖:

問:怎么能夠讓MySQL在執行事務后, 返回包中帶上GTID呢?

答:把參數session_track_gtids設置為OWN_GTID, 然后通過API接口mysql_session_track_get_first從返回包解析出GTID的值即可。

小結:思考題


思考:假設你的系統采用了等GTID的方案, 現在你要對主庫的一張大表做DDL,在做讀寫分離時可能會出現什么情況呢? 為了避免這種情況, 你會怎么做呢?

假設,這條語句在主庫上要執行10分鐘,提交后傳到備庫就要10分鐘(典型的大事務)。那么,在主庫DDL之后再提交的事務的GTID,去備庫查的時候,就會等10分鐘才出現。

這樣,這個讀寫分離機制在這10分鐘之內都會超時,然后走主庫。

這種預期內的操作,應該在業務低峰期的時候,確保主庫能夠支持所有業務查詢,然后把讀請求都切到主庫,再在主庫上做DDL。等備庫延遲追上以后,再把讀請求切回備庫。

通過這個思考題,我主要想讓關注的是,大事務對等位點方案的影響。

當然了,使用gh-ost方案來解決這個問題也是不錯的選擇。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/14482.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/14482.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/14482.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

RabbitMQ 消息隊列安裝及入門

市面常見消息隊列中間件對比 技術名稱吞吐量 /IO/并發時效性(類似延遲)消息到達時間可用性可靠性優勢應用場景activemq萬級高高高簡單易學中小型企業、項目rabbitmq萬級極高(微秒)高極高生態好(基本什么語言都支持&am…

為什么MySQL推薦使用utf8mb4代替utf8?

前言 在MySQL數據庫的世界里,字符集的選擇直接影響著數據的存儲和檢索方式,尤其是對于多語言支持至關重要的應用而言。近年來,utf8mb4字符集逐漸成為MySQL中存儲Unicode字符的標準選擇,逐步取代了傳統的utf8字符集。本文將詳細探…

leetcode124 二叉樹中的最大路徑和-dp

題目 二叉樹中的 路徑 被定義為一條節點序列,序列中每對相鄰節點之間都存在一條邊。同一個節點在一條路徑序列中 至多出現一次 。該路徑 至少包含一個 節點,且不一定經過根節點。 路徑和 是路徑中各節點值的總和。 給你一個二叉樹的根節點 root &…

【Crypto】Rabbit

文章目錄 一、Rabbit解題感悟 一、Rabbit 題目提示很明顯是Rabbit加密,直接解 小小flag,拿下! 解題感悟 提示的太明顯了

redis核心面試題二(實戰優化)

文章目錄 10. redis配置mysql實戰優化[重要]11. redis之緩存擊穿、緩存穿透、緩存雪崩12. redis實現分布式session 10. redis配置mysql實戰優化[重要] // 最初實現OverrideTransactionalpublic Product createProduct(Product product) {productRepo.saveAndFlush(product);je…

MQTT 5.0 報文解析 05:DISCONNECT

歡迎閱讀 MQTT 5.0 報文系列 的第五篇文章。在上一篇中,我們已經介紹了 MQTT 5.0 的 PINGREQ 和 PINGRESP 報文。現在,我們將介紹下一個控制報文:DISCONNECT。 在 MQTT 中,客戶端和服務端可以在斷開網絡連接前向對端發送一個 DIS…

手把手教你搭建一個花店小程序商城

如果你是一位花店店主,想要為你的生意搭建一個精美的小程序商城,以下是你將遵循的五個步驟。 步驟1:登錄喬拓云平臺進入后臺 首先,你需要登錄喬拓云平臺的后臺管理頁面。你可以在電腦或移動設備上的瀏覽器中輸入喬拓云的官方網站…

2024.5.26 機器學習周報

目錄 引言 Abstract 文獻閱讀 1、題目 2、引言 3、創新點 4、Motivation 5、naive Lite-HRNet 6、Lite-HRNet 7、實驗 深度學習 解讀SAM(Segment Anything Model) 1、SAM Task 2、SAM Model 2.1、Patch Embedding 2.2、Positiona Embedding 2.3、Transformer …

移動端適配:vw適配方案

vw (Viewport Width) 是一種長度單位,代表視口寬度的百分比。1vw 等于視口寬度的1%。在網頁設計和前端開發中,vw 單位常用于實現響應式設計和屏幕適配,尤其是針對不同尺寸和分辨率的移動設備。 為什么使用vw適配? 響應式: 使用v…

互聯網醫院開發:引領智慧醫療新時代

隨著科技的迅猛發展和互聯網的普及,傳統醫療模式正在迎來一場深刻的變革。互聯網醫院的崛起,打破了時間和空間的限制,為患者和醫療機構帶來了更加便捷、高效、安全的醫療服務體驗。本文將從技術角度深入探討互聯網醫院的開發,包括…

【openpcdet中yaml文件的DATA_AUGMENTOR學習】

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 文章目錄 前言一、代碼二、詳細解釋DISABLE_AUG_LISTAUG_CONFIG_LIST1. gt_sampling2. random_world_flip3. random_world_rotation4. random_world_scaling 總結 前言 提示…

多線程(八)

一、wait和notify 等待 通知 機制 和join的用途類似,多個線程之間隨機調度,引入 wait notify 就是為了能夠從應用層面上,干預到多個不同線程代碼的執行順序.( 這里說的干預,不是影響系統的線程調度策略 內核里的線程調度,仍然是無序的. 相當于是在應用程序…

Pod容器資源限制和探針

目錄 一、資源限制 1.Pod和容器的資源請求和限制 2.CPU 資源單位 案例一 案例二 二、健康檢查,又稱為探針(Probe) 1.探針的三種規則 2.Probe支持三種檢查方法 3.探測獲得的三種結果 案例一:exec 案例二:htt…

OneMO同行 心級服務:中移物聯OneMO模組助力客戶終端寒冷環境下的穩定運行

中移物聯OneMO模組以客戶為中心,基于中國移動心級服務要求,開展“OneMO同行 心級服務 標定一流”高標服務主題活動,升級“服務內容““服務方式”和“服務意識”,為行業客戶提供全新的服務體驗。 近日,某車載監控設備…

Hive語法學習總結

Hive SQL語法學習總結 hive參數庫操作1.創建庫2.具體案例3.庫的其他操作 表和庫的路徑演示表的操作創建表插入數據 hive參數 一 hive常用交互命令hive -e sql語句hive -f sql文件 //文件中是sql語句二 參數的設置方式一:在客戶端中設置參數(當次有效)set 參數名參…

ACM實訓第十七天

Is It A Tree? 問題 考試時應該做不出來,果斷放棄 樹是一種眾所周知的數據結構,它要么是空的(null, void, nothing),要么是一個或的集合滿足以下屬性的節點之間有向邊連接的節點較多。 ?只有一個節點,稱為根節點,它…

【Crypto】摩絲

文章目錄 一、摩斯解題感悟 一、摩斯 很明顯莫爾斯密碼 iloveyou還挺浪漫 小小flag,拿下 解題感悟 莫爾斯密碼這種題還是比較明顯的

【董曉算法】競賽常用知識之圖論3(最近公共祖先)

前言: 本系列是學習了董曉老師所講的知識點做的筆記 董曉算法的個人空間-董曉算法個人主頁-嗶哩嗶哩視頻 (bilibili.com) 動態規劃系列(還沒學完) 【董曉算法】動態規劃之線性DP問題-CSDN博客 【董曉算法】動態規劃之背包DP問題&#xff…

智能鎖千千萬,誰是你的NO.1,親身實測凱迪仕傳奇大師K70旗艦新品

智能鎖千千萬,誰是你的NO.1。歡迎來到智哪兒評測室,這次我們為大家帶來了凱迪仕傳奇大師K70系列的一款重磅新品。 在科技的浪潮中,家居安全領域正經歷著前所未有的變革。智能鎖越來越成為家的安全守護神,以及智能生活的得力助手。…

Android 11 Framework實時監聽Activity堆棧變化

核心類 Framework中有一個類SystemActivityMonitoringService專門用于監控Activity堆棧變化,屬于隱藏Api,應用側無法調用。此類位于 packages/services/Car/service/src/com/android/car/SystemActivityMonitoringService.java 方法 void registerTa…