本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
Amazon QLDB 并发模型
重要
支援結束通知:現有客戶將能夠使用 Amazon,QLDB直到 2025 年 7 月 31 日終止支援為止。有關更多詳細信息,請參閱將 Amazon QLDB 分類帳遷移到 Amazon Aurora 郵政. SQL
Amazon QLDB 旨在滿足高效能線上交易處理 (OLTP) 工作負載的需求。QLDB支持SQL類似查詢功能,並提供完整的ACID事務。此外,QLDB資料項目也是文件,提供結構描述彈性和直覺式資料建模。以日誌為核心,您可以使用QLDB存取資料所有變更的完整且可驗證的歷史記錄,並視需要將一致性交易串流至其他資料服務。
樂觀並發控制
在中QLDB,並發控制使用樂觀並發控制()OCC來實現。OCC運作的原則是,多個交易可以經常完成而不會相互干擾。
使用中的事務QLDB不會獲取數據庫資源的鎖定OCC,並以完全可序列化隔離進行操作。QLDB以序號方式執行並行異動,使其產生的效果與順序啟動這些異動的效果相同。
認可之前,每個交易都會執行驗證檢查,以確保沒有其他認可的交易已修改它所存取的資料。如果此檢查顯示發生衝突的修改,或資料狀態變更,則會拒絕認可交易。但是,可以重新啟動交易。
當交易寫入時QLDB,OCC模型的驗證檢查會QLDB自行實作。如果交易由於的驗證階段失敗而無法寫入日誌OCC,則會QLDB傳回應用程式層。OccConflictException
應用程式軟體負責確保交易重新啟動。應用模組應中止被拒絕的交易,然後從一開始重試整個交易。
若要瞭解QLDB驅動程式如何處理和重試OCC衝突及其他暫時性例外狀況,請參閱了解 Amazon 中的驅動程序的重試政策 QLDB。
使用索引來避免全表掃描
在中QLDB,每個 PartiQL 陳述式 (包括每個SELECT
查詢) 都會在交易中處理,且受到交易逾時限制的限制。
最佳做法是,您應該執行含有述WHERE
詞子句的陳述式,以篩選索引欄位或文件 ID。QLDB索引欄位上需要相等運算子才能有效率地查詢文件;例如,WHERE indexedField = 123
或WHERE indexedField
IN (456, 789)
。
如果沒有此索引查找,則QLDB需要在閱讀文檔時進行全表掃描。這可能會導致查詢延遲和交易逾時,也會增加與競爭交易OCC發生衝突的可能性。
例如,假設名Vehicle
為的資料表僅在VIN
欄位上有索引。它包含以下文件。
VIN | Make | 模型 | 顏色 |
---|---|---|---|
"1N4AL11D75C109151" |
"Audi" |
"A5" |
"Silver" |
"KM8SRDHF6EU074761" |
"Tesla" |
"Model S" |
"Blue" |
"3HGGK5G53FM761765" |
"Ducati" |
"Monster 1200" |
"Yellow" |
"1HVBBAANXWH544237" |
"Ford" |
"F 150" |
"Black" |
"1C4RJFAG0FC625797" |
"Mercedes" |
"CLK 350" |
"White" |
兩個名為 Alice 和 Bob 的並發用戶正在使用分類帳中的同一個表。他們想要更新兩個不同的文件,如下所示。
愛麗絲:
UPDATE Vehicle AS v
SET v.Color = 'Blue'
WHERE v.VIN = '1N4AL11D75C109151'
鮑勃:
UPDATE Vehicle AS v
SET v.Color = 'Red'
WHERE v.Make = 'Tesla' AND v.Model = 'Model S'
假設愛麗絲和鮑勃在同一時間開始他們的交易。Alice 的UPDATE
陳述式會在VIN
欄位上進行索引查找,因此只需要讀取該文件即可。愛麗絲完成並成功提交她的交易第一。
Bob 的陳述式會篩選非索引欄位,因此它會執行資料表掃描並遇到OccConflictException
. 這是因為 Alice 認可的交易修改了 Bob 陳述式所存取的資料,其中包括表格中的每個文件,而不僅僅是 Bob 正在更新的文件。
插入OCC衝突
OCC衝突可以包括新插入的文件,而不僅僅是先前存在的文件。考慮下圖,其中兩個並發用戶(愛麗絲和鮑勃)正在使用分類帳中的同一個表。他們都希望只在謂詞值尚不存在的情況下插入一個新文檔。
![Amazon QLDB 樂觀並發控制(OCC)圖顯示了兩個並發用戶之間的衝突異常的示例。](images/occ-example.png)
在此範例中,Alice 和 Bob 都會在單一交易中執行下列SELECT
和INSERT
陳述式。他們的應用程式只會在INSERT
陳述式未傳回任何結果時執行SELECT
陳述式。
SELECT * FROM Vehicle v WHERE v.VIN = 'ABCDE12345EXAMPLE'
INSERT INTO Vehicle VALUE
{
'VIN' : 'ABCDE12345EXAMPLE',
'Type' : 'Wagon',
'Year' : 2019,
'Make' : 'Subaru',
'Model' : 'Outback',
'Color' : 'Gray'
}
假設愛麗絲和鮑勃在同一時間開始他們的交易。他們的兩個SELECT
查詢都不會返回與 a VIN
的現有文檔ABCDE12345EXAMPLE
。因此,他們的應用程序繼續INSERT
聲明。
愛麗絲完成並成功提交她的交易第一。然後,鮑勃試圖提交他的事務,但QLDB拒絕它並拋出一個OccConflictException
. 這是因為 Alice 認可的交易修改了 Bob SELECT
查詢的結果集,並在認可 Bob 的交易之前OCC偵測到此衝突。
這個事務示例需要SELECT
查詢是冪等的。然後 Bob 可以從一開始就重試他的整個交易。但他的下一個SELECT
查詢將返回愛麗絲插入的文檔,所以鮑勃的應用程序將無法運行INSERT
.
使交易冪等
上一節中的插入交易也是冪等交易的範例。換句話說,多次運行相同的事務會產生相同的結果。如果 Bob 在INSERT
沒有先檢查特定項目是否VIN
已存在的情況下執行,則表格最終可能會出現具有重複VIN
值的文件。
除了OCC衝突之外,請考慮其他重試案例。例如,可能在伺服器端QLDB成功提交交易,但用戶端在等待回應時逾時。最佳做法是將寫入交易設為冪等,以避免在並發或重試的情況下出現任何意外的副作用。
密文衝突 OCC
QLDB防止同一分錄區塊上的修訂並行編輯。假設兩個並行使用者 (Alice 和 Bob) 想要編輯分類帳中相同區塊上確認的兩個不同文件修訂版本的範例。首先,Alice 透過執行REDACT_REVISION
預存程序來要求編輯一個修訂,如下所示。
EXEC REDACT_REVISION `{strandId:"JdxjkR9bSYB5jMHWcI464T", sequenceNo:17}`, '5PLf9SXwndd63lPaSIa0O6', 'ADR2Ll1fGsU4Jr4EqTdnQF'
然後,當 Alice 的請求仍在處理中時,Bob 要求編輯另一個修訂版本,如下所示。
EXEC REDACT_REVISION `{strandId:"JdxjkR9bSYB5jMHWcI464T", sequenceNo:17}`, '8F0TPCmdNQ6JTRpiLj2TmW', '05K8zpGYWynDlEOK5afDRc'
QLDB拒絕 Bob 的請求,OccConflictException
即使他們試圖編輯兩個不同的文檔修訂版。這是因為 Bob 的修訂與 Alice 正在編輯的修訂位於同一個區塊上。Alice 的請求完成處理後,Bob 可以重試其密文請求。
同樣地,如果兩個並行異動嘗試編輯相同的修訂版本,則只能處理一個請求。另一個要求失敗,並出現OCC衝突例外狀況,直到密文完成為止。之後,任何編輯相同版本的請求都會導致錯誤,指出修訂已經編輯過。
管理並行工作階
如果您有使用關聯式資料庫管理系統 (RDBMS) 的經驗,您可能熟悉並行連線限制。QLDB不具有傳統RDBMS連接的相同概念,因為事務與HTTP請求和響應消息一起運行。
在中QLDB,類似的概念是使用中的工作階段。工作階段在概念上與使用者登入類似,它會管理您對總帳之資料交易請求的相關資訊。使用中的工作階段是主動執行交易的工作階段。它也可以是最近完成交易的工作階段,服務預期會立即啟動另一個交易。QLDB每個會話支持一個主動運行的事務。
在中定義每個分類帳的並行作用中階段作業限制Amazon 的配額和限制 QLDB。達到此限制之後,任何嘗試啟動交易的工作階段都會導致 error (LimitExceededException
)。
有關會話的生命週期以及QLDB驅動程序如何在運行數據交易時處理會話的信息,請參閱驅動程式的工作階段管理。如需使用QLDB驅動程式在應用程式中設定工作階段集區的最佳實務,請參閱 Amazon QLDB 驅動程式建議配置對 QldbDriver 象中的。