RDS MySQL資料庫代理在讀寫(讀寫分離)模式下提供了三種一致性層級:最終一致性、會話一致性和全域一致性。本文介紹三種一致性層級的準系統和適用情境,協助您根據實際業務需求選擇合適的一致性層級。
背景資訊
RDS MySQL使用Binlog複製來同步主節點和唯讀節點的資料。當主節點提交事務時,產生的Binlog Event會被發送到唯讀節點,唯讀節點通過接收和應用Binlog Event來實現和主節點的資料同步。雖然基於Binlog複製確保了最終一致性,但在高並發或高負載情況下,唯讀節點上的資料可能出現延遲,導致從唯讀節點上讀到的資料不一致。
為瞭解決資料不一致問題,RDS MySQL資料庫代理提供了三種一致性層級:最終一致性、會話一致性和全域一致性。您可以根據業務需求選擇合適的一致性層級。
一致性介紹
最終一致性(預設)
功能介紹
RDS MySQL資料庫代理預設採用最終一致性層級,在Binlog複製不中斷的情況下,讀請求直接發送到唯讀節點。由於唯讀節點的資料在Binlog複製下是最終一致的,因此代理上的讀請求也是最終一致的。RDS MySQL代理支援設定延遲閾值,限制唯讀執行個體的最大延遲時間。一旦唯讀節點的延遲超過該閾值,讀請求將不再被發送到該節點。
此外,複寫延遲可能導致不同唯讀節點上的資料存在差異。例如,在一個會話中連續執行如下查詢,最終查詢結果可能有所不同:
SET AUTOCOMMIT = 1;INSERT INTO t1(id, price) VALUES (111, 96);UPDATE t1 SET price = 100 WHERE id = 111;SELECT price FROM t1;這些查詢的結果可能會因複寫延遲而有所變化。
適用情境
一致性需求較弱,更希望盡量減輕主節點壓力,使更多讀請求路由到唯讀節點時,您可以選擇最終一致性。
會話一致性
功能介紹
為應對最終一致性導致查詢結果不準確的問題,業務系統通常會將讀請求拆分:高一致性要求的讀請求發往主節點,低一致性要求的讀請求發往唯讀節點。然而,這種做法不僅增加了應用複雜度,還會使主節點承擔更多的讀請求,影響讀寫分離的效果。
為瞭解決上述問題,RDS MySQL代理提供了會話一致性。與最終一致性直接將讀請求發送到唯讀節點不同,會話一致性下,代理會記錄前一個更新操作在主節點上的資料位元點(基於GTID確定)。代理僅將讀請求發送到已同步該位點資料的唯讀節點,確保讀請求能查詢到當前會話中已更新的資料,從而保證會話內的資料一致性。
適用情境
單個會話記憶體在一致性依賴,推薦使用會話一致性,該層級對效能影響相對較小而且能滿足大多數應用情境。
全域一致性
功能介紹
在某些應用情境中,不僅會話內部存在邏輯上的因果依賴關係,不同會話之間也存在依賴關係,要求各會話讀取的資料必須完全一致。此時,會話一致性無法滿足需求。RDS MySQL代理通過提供全域一致性來解決這一問題。與會話一致性不同,全域一致性下,代理會在每次讀操作前記錄當前主節點上的資料位元點(基於GTID確定),並僅將讀請求發送到已完成相應資料位元點同步的唯讀節點,確保讀請求能查詢到所有會話已更新的資料,從而保證了全域資料的一致性。
適用情境
會話間存在一致性依賴,並且業務為讀多寫少的情境,建議使用全域一致性。
關於會話一致性和全域一致性的實現原理,請參見附錄:會話一致性和全域一致性實現原理。
選擇一致性層級
一致性層級越高(全域一致性 > 會話一致性 > 最終一致性),讀寫分離效能越低。
一般情況下,推薦使用會話一致性,不僅對效能影響較小,且能滿足大多數應用情境的需求。
如果不同會話間需要較高的一致性,並且寫入壓力不大,可以選擇全域一致性。
一致性層級 | 對讀寫分離效能影響 | 資料一致性強度 | 資料一致性範圍 |
最終一致性 | 無 | 低 | 最終結果一致 |
會話一致性 | 中 | 中 | 單個會話內一致 |
全域一致性 | 高 | 高 | 跨會話一致 |
設定一致性層級
前提條件
資料庫代理的讀寫屬性為讀寫(讀寫分離),詳情請參見設定讀寫屬性和讀權重。
RDS MySQL執行個體版本為8.0或5.7,且核心小版本滿足:
MySQL 5.7需大於等於20210630。
MySQL 8.0需大於等於20210930。
注意事項
當使用會話一致性或全域一致性時,代理需要等待資料位元點同步(最大等待時間為一致性讀逾時時間),這可能導致業務延遲增加。
如果唯讀節點存在複寫延遲,使用全域一致性可能會使更多讀請求路由到主節點,導致主節點負載增大,並進一步增加業務延遲。
一致性層級預設值為最終一致性。
操作步驟
訪問RDS執行個體列表,在上方選擇地區,然後單擊目標執行個體ID。
在左側導覽列,單擊資料庫代理。
在串連資訊地區,在目標代理串連地址的操作列,單擊修改配置。
根據需求選擇一致性層級。
說明當選擇最終一致性或會話一致性層級時,可以按需開啟延遲閾值。預設開啟的延遲閾值為30 s。
當選擇會話一致性或全域一致性層級時,可以按需設定一致性讀逾時時間,如果不設定,預設值為10 ms。
附錄:會話一致性和全域一致性實現原理
為了實現會話一致性和全域一致性,RDS MySQL代理記錄每個唯讀節點的Executed_Gtid_Set(已提交事務集合),以確定每個唯讀節點上的資料位元點(GTID,全域事務號)。在每次讀請求開始前,代理會設定讀請求所需的GTID,並將讀請求路由至已達到該GTID位點的唯讀節點。若唯讀節點未滿足GTID要求,則等待其同步至指定的GTID位點後再進行路由。RDS MySQL代理支援通過設定一致性讀逾時時間來限定最大等待時間,若逾時內無符合GTID位點的唯讀節點,則請求將被發送到主節點。
讀請求所需的GTID根據一致性層級不同而變化:
會話一致性:當前會話中最新執行事務對應的GTID。
全域一致性:當前叢集中最新執行事務對應的GTID。
相關API
API | 描述 |
查詢RDS執行個體資料庫代理詳細資料。 | |
查詢RDS執行個體資料庫代理的串連地址資訊。 | |
修改RDS執行個體資料庫代理串連地址存取原則。 |