全部產品
Search
文件中心

PolarDB:一致性層級

更新時間:Jul 06, 2024

PolarDB PostgreSQL版(相容Oracle)提供了兩種一致性層級(一致性是指ACID特性中的Consistency特性):最終一致性、會話一致性,滿足您在不同情境下對一致性層級的要求。

問題與解決方案

PolarDB具有主從複製簡單易用的特點,通過把主庫的WAL非同步地傳輸到備庫並即時應用,一方面可以實現高可用,另一方面備庫也可以提供查詢,來減輕對主庫的壓力。雖然備庫可以提供查詢,但存在以下問題:

  • 問題1:主庫和備庫一般提供兩個不同的訪問地址,在訪問不同庫時,需要在應用程式上修改成對應庫的地址,對應用有侵入。
  • 問題2:資料的複製是非同步。用戶端提交commit並且成功之後,資料可能還沒有同步到唯讀節點。因此備庫的資料並不是最新的而是有延遲的,無法保證查詢的一致性。

為瞭解決第一個問題,PolarDB引入了讀寫分離代理功能。一般的實現是,代理會偽造成PolarDB與應用程式建立好串連,解析發送進來的每一條SQL,如果是UPDATE、DELETE、INSERT、CREATE等寫操作則直接發往主庫,如果是SELECT則發送到備庫。

3

但讀寫分離還是無法解決由於延遲導致的查詢不一致問題。當資料庫負載很高時,例如對大表執行DDL(如加欄位)操作或大批量插入資料的時候,延遲會非常嚴重,從而導致無法從唯讀節點中讀取最新資料。

PolarDB採用了非同步物理複製方式實現了主節點和唯讀節點間的資料同步。主節點的資料更新後,相關的更新會應用到唯讀節點,具體的延遲時間與寫入壓力有關(一般在毫秒層級),通過非同步複製的方式確保了主節點和唯讀節點間資料的最終一致。PolarDB提供了如下兩種一致性層級,滿足您在不同情境下對一致性層級的要求:

說明 如何修改一致性層級,請參見設定資料庫代理

最終一致性

  • 功能介紹
    PolarDB是讀寫分離的架構,傳統的讀寫分離只提供最終一致性的保證,主從複寫延遲會導致從不同節點查詢到的結果不同,例如在一個會話內連續執行如下查詢,最後的SELECT結果可能會不同(具體的訪問結果由主從複製的延遲決定)。
    INSERT INTO t1(id, price) VALUES(111, 96);
    UPDATE t1 SET price = 100 WHERE id=111;
    SELECT price FROM t1;
  • 適用情境

    若需要減輕主節點壓力,讓盡量多的讀請求路由到唯讀節點,您可以選擇最終一致性。

會話一致性

  • 功能介紹

    針對最終一致性導致查詢結果不同的問題,通常需要將業務進行拆分,將一致性要求高的請求直接發往主節點,而可以接受最終一致性的請求則通過讀寫分離發往唯讀節點。這既增加了主節點的壓力,影響讀寫分離的效果,又增加了應用開發的負擔。

    為解決上述問題,PolarDB提供了會話一致性(也稱因果一致性)。會話一致性保證了同一個會話內,一定能夠查詢到讀請求執行前已更新的資料,確保了資料單調性。

    PolarDB的鏈路中介層做讀寫分離的同時,中介層會追蹤各個節點已經應用的Redo日誌位點,即日誌序號(Log Sequence Number,簡稱LSN)。同時每次資料更新時PolarDB會記錄此次更新的位點為Session LSN。當有新請求到來時,PolarDB會比較Session LSN和當前各個節點的LSN,僅將請求發往LSN大於或等於Session LSN的節點,從而保證了會話一致性。表面上看該方案可能導致主節點壓力大,但是因為PolarDB是物理複製,速度極快。

    4

    在上述情境中,當更新完成後,返回用戶端結果時複製就同步在進行,而當下一個讀請求到來時,主節點和唯讀節點之間的資料複製極有可能已經完成。且大多數應用情境都是讀多寫少,所以經驗證在該機制下既保證了會話一致性,又保證了讀寫分離負載平衡的效果。

  • 適用情境

    PolarDB的一致性層級越高,對主庫的壓力越大,叢集效能也越低。推薦使用會話一致性,該層級對效能影響很小而且能滿足絕大多數應用情境的需求。

一致性層級選擇最佳實務

  • PolarDB一致性層級越高,叢集效能越低。推薦使用會話一致性,該層級對效能影響很小而且能滿足絕大多數應用情境的需求。
  • 若對不同會話間的一致性需求較高,可以選擇如下方案:
    使用HINT將特定查詢強制發送至主節點執行。
    /*FORCE_MASTER*/ select * from user;
    說明
    • 若您需要通過MySQL官方命令列執行上述Hint語句,請在命令列中加上-c參數,否則該Hint會被MySQL官方命令列過濾導致Hint失效,具體請參見MySQL官方命令列
    • Hint的路由優先順序最高,不受一致性層級和事務拆分的約束,使用前請進行評估。
    • Hint語句裡不要有改變環境變數的語句,例如/*FORCE_SLAVE*/ set names utf8;等,這類語句可能導致後續的業務出錯。