pos機數據超時,MySQL主從數據不一致

 新聞資訊  |   2023-04-24 09:45  |  投稿人:pos機之家

網上有很多關于pos機數據超時,MySQL主從數據不一致的知識,也有很多人為大家解答關于pos機數據超時的問題,今天pos機之家(www.bangarufamily.com)為大家整理了關于這方面的知識,讓我們一起來看下吧!

本文目錄一覽:

1、pos機數據超時

pos機數據超時

主從數據不一致問題

先介紹下問題產生的背景。

在MySQL 一主多從的架構中,主要有兩種,一種是通過客戶端直連,一種是通過代理 prxoy 間接連接。

客戶端直連模式下一般會把數據庫的連接信息放在客戶端的連接層,客戶端做負載均衡,由客戶端來選擇后端數據庫進行查詢。通過代理的模式下 MySQL 和客戶端之間有一個中間代理層 proxy,客戶端直連接 proxy, 由 proxy 根據請求類型和上下文決定請求的分發路由。

客戶端直連和帶 proxy 的讀寫分離架構,各有哪些特點。

客戶端直連方案,整體架構簡單,排查問題方便。但是這種方案,由于要了解后端部署細節,所以在出現主備切換、庫遷移等操作的時候,處理起來比較麻煩,對開發人員要求高。直連 proxy 的架構,對客戶端比較友好??蛻舳瞬恍枰P注后端細節,但是 proxy 也需要有高可用架構,架構更復雜,對運維團隊要求更高。

目前趨勢是直連 proxy 的方向發展,具體取舍取決于自身情況。

帶來的問題

無論哪種架構,都會遇到主從數據不一致的問題:由于主從同步可能存在延遲,客戶端執行完一個更新事務后馬上發起查詢,如果查詢選擇的是從庫的話,就有可能讀到剛剛的事務更新之前的狀態。如何解決呢?

在進行讀寫分離的同時,解決主從同步中數據不一致的問題,主要有幾種思路,一是從業務層面解決,二是從檢測主從同步的差異上解決,三也是最根本的方式——從主從之間數據復制方式解決。按照這三種指導思想,我總結了一下有以下幾種方案。

全部走主庫方案

先說一種最為廣泛使用的方案,也就是二狗的回答。

如果是在同一數據庫中對數據進行更新的時候,可以對記錄加寫鎖,這樣在讀取的時候就不會發生數據不一致的情況。所以我們可以根據業務場景來做區分。如果是需要寫完之后必須讀區到準確數據的場景,可以直接全部走主庫,比如訂單支付、金融業務等強一致性場景;如果業務允許讀到舊數據,可以在讀的時候查詢從庫。

這樣的話你可能覺得并沒有真正解決主從不一致的問題,但其實在實際生產中,大多數情況下都這么解決的。優點是簡單成本低,不需要復雜架構。缺點也很明顯,如果業務一致性要求很高,很多讀都會在主庫進行,并沒有真正的讀寫分離減輕主庫壓力,讀寫分離成了擺設。

延遲查詢方案

比如主庫更新一條數據以后,查詢從庫數據的時候后端接口可以線sleep一段時間,比如絕大多數主從同步都可以在1s內完成,那就可以sleep一秒鐘的時間?;蛘咭部梢匝舆t查詢邏輯放在前端,比如訂單支付完成后,可以前端延遲一秒再發起Ajax請求。

缺點是并不能數據保證完全準確,如果數據同步延遲大于一秒則主從依舊不一致;另一個是造成接口響應時間變長,甚至造成服務的吞吐量降低,對于不需要等待1s的場景,也必須等待夠1s。

判斷主備無延遲方案

在構建MySQL主從架構的文章里提過一些關于主從搭建以及狀態查看的具體操作,具體請看下面這篇文章

快速入門Mycat及主從搭建指南

后文將要提到的關于判斷主備延遲的關鍵參數便是從 status 的結果中獲得的。

1.判斷Seconds_Behind_Master

通過 show slave status 可以拿到 Seconds_Behind_Master 的值,表示主備延遲的時間長短。判斷 Seconds_Behind_Master 是否為 0,如果不等于0,就等到這個參數為0時再執行查詢。但是這個延遲時間的單位為秒,所以可能產生一秒內的誤差。

2.判斷同步binlog 位置

在同步時通過文件名+文件位置就可以定位到binlog文件正在同步的位置。Master_Log_FileRead_Master_Log_Pos,表示的是讀到的主庫的最新位點;Relay_Master_Log_FileExec_Master_Log_Pos,表示的是備庫執行的最新位點。

3.判斷GTID相同

GITD在全局唯一,并且可以動過GTID來定位binlog位置,所以也可以用來判斷主備是否有延遲

什么是GTID?

GTID特性是5.6加入的一個強大的特性,全稱是Global transaction Identifier。MySQL會為每一個DML/DDL操作增加一個唯一標記叫做GTID,這個標記在整個復制環境中都是唯一的。主從環境中主庫的DUMP線程可以直接通過GTID定位到需要發送的binary log位置,而不再需要指定binary log的文件名和位置,因此切換極為方便。關于DUMP線程是如何通過GTID定位到binary log位置的,我們將在第17節進行討論。

Auto_Position=1 ,表示這對主備關系使用了 GTID 協議。Retrieved_Gtid_Set,是備庫收到的所有日志的 GTID 集合;Executed_Gtid_Set,是備庫所有已經執行完成的 GTID 集合。對比這兩個集合對應的GTID相同就表示主備之間無延遲。

但是需要說明的是,這里的無延遲,指的其實是從庫收到主庫的數據已經全部執行結束。但可能有種情況,客戶端已經收到數據,而對應的binlog并沒有收到,這種情況下從庫是不知道的。

如何解決這個問題呢?

我們現在的困境是不知道主庫到底有沒有新執行的數據,從庫有沒有把最新binlog收到并且執行,那如果主庫執行完SQL我就拿到最新binlog位點呢?還有另一種思路,之所以產生這種情況,是因為5.7版本mysql默認采用了異步復制的方式。如果想要數據更精確,就有必要在復制方式上做出改變。

對于這兩種思路又產生了后面幾種解決方案。

從庫等指定位點或GTID方案

對于前面提到的思路,剛好MySQL有這樣一個命令。

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

這條命令是在從庫執行的,參數 file 和 pos 指的是主庫上的文件名和位置,timeout 可選,設置為正整數 N 表示這個函數最多等待 N 秒。這個命令正常返回的結果是一個正整數 M,表示從命令開始執行,到應用完 file 和 pos 表示的 binlog 位置,執行了多少事務。

這樣就產生了一個方案。

主庫事務更新完成后,馬上執行 show master status 得到當前主庫執行到的 File 和 Position。選定一個從庫執行查詢語句。在從庫上執行 select master_pos_wait(File, Position, 1)。如果返回值是 >=0 的正整數,則在這個從庫執行查詢語句,否則,到主庫執行查詢語句。

同樣的對于判斷位點,可有一套判斷GTID的方案。

select wait_for_executed_gtid_set(gtid_set, 1);

邏輯與前者相同,只需要等待GTID到指定數字即可,這里大家舉一反三,不做贅述。

復制方式

下面就開始介紹關于復制方式方面的思路,從這些復制方式中,你會找到關于解決主備延遲問題的更優思路。先介紹一下異步復制模式。

異步復制

異步模式就是客戶端提交 COMMIT 之后不需要等從庫返回任何結果,而是直接將結果返回給客戶端,這樣做的好處是不會影響主庫寫的效率,但可能會存在主庫宕機,而 Binlog 還沒有同步到從庫的情況,也就是此時的主庫和從庫數據不一致。這時候從從庫中選擇一個作為新主,那么新主則可能缺少原來主服務器中已提交的事務。所以,這種復制模式下的數據一致性是最弱的。

默認情況下,MySQL就是異步復制的模式。

半同步復制(增強半同步復制)

在MySQL5.5中加入了半同步復制(semisynchronous replication),主庫上的事務在存儲引擎層提交之后,需要等待從庫返回ACK信號。并且在接收到從庫返回ACK信號或者等待超時才會返回給客戶端一個提交結果。但是這樣會造成其他會話可以讀取到這些記錄,因為此時事務已經提交,這就造成了幻讀。

在MySQL5.7中進一步對半同步復制做了增強,將等待從庫返回ACK信號的時間點提前了,新特性中主庫上的事務會在存儲引擎層提交之前一直等待從庫返回ACK信號。這就意味著,在主庫crash的情況下,所有在主庫上已經提交的事務已經被復制到至少一個從庫上,這就解決了幻讀的問題,數據的一致性獲得了極大提升。

但是缺點也很明顯,會造成同步過程多了一次網絡連接,降低主庫的寫吞吐量。在 MySQL5.7 版本中還增加了rpl_semi_sync_master_wait_for_slave_count參數 ,可以對從庫的應答數量進行設置,默認為 1,也就是說只要有 1 個從庫進行了響應,就可以返回給客戶端。在1主1從情況下,這接近同步復制,如果使用semi-sync+位點判斷方案,這樣我們前面提到的主從數據不一致問題引刃而解,但是如果多從還是有可能出現不一致的情況。

MGR 組復制

MySQL在5.7.17 版本中引入了組復制技術,簡稱 MGR(MySQL Group Replication),這種復制技術是基于 分布式一致性協議Paxos 協議的,實現了分布式下數據的最終一致性。

A transaction received by Source 1 is executed. Source 1 then sends a message to the replication group, consisting of itself, Source 2, and Source 3. When all three members have reached consensus, they certify the transaction. Source 1 then writes the transaction to its binary log, commits it, and sends a response to the client application. Sources 2 and 3 write the transaction to their relay logs, then apply it, write it to the binary log, and commit it.

MGR 由若干個節點共同組成一個復制組,一個寫事務的提交,必須經過組內大多數節點(N / 2 + 1)決議并通過,才能得以提交。如上圖所示,由3個節點組成一個復制組,Consensus層為一致性協議層,在事務提交過程中,發生組間通訊,由2個節點決議(certify)通過這個事務,事務才能夠最終得以提交并響應,其實就是過半投票。

而針對只讀(RO)事務則不需要經過組內同意,直接 COMMIT 即可。在一個復制組內有多個節點組成,它們各自維護了自己的數據副本,并且在一致性協議層實現了原子消息和全局有序消息,從而保證組內數據的一致性。雖然半同步復制部分解決了一致性問題,但只能在簡單架構下比如一主一從,MGR才真正解決了這個問題,并且MGR可以在多主的復雜情況下有效保證數據的一致性。

總結

總結一下,解決主從復制延遲一共可以有如下7種思路:

讀寫走主庫方案延遲查詢方案判斷主備無延遲方案判斷同步位點方案等待同步位點方案半同步復制方案+等待位點組復制MGR方案

其實在實際生產中,這些方案是可以混合使用的,因為一致性越強就意味著性能越低。比如業務不在乎是否查詢到過期數據就可以直接查詢從庫,如果需要的一致性強可以選擇后幾種方案。

以上就是關于pos機數據超時,MySQL主從數據不一致的知識,后面我們會繼續為大家整理關于pos機數據超時的知識,希望能夠幫助到大家!

轉發請帶上網址:http://www.bangarufamily.com/news/32619.html

你可能會喜歡:

版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 babsan@163.com 舉報,一經查實,本站將立刻刪除。