數據庫-索引的壞處,事務的級別,分佈式事務的原理。

一、數據庫索引的壞處

索引是完全獨立於基礎數據之外的一部分數據。假 設在Table ta 中的Column ca 創建了索引 idx_ta_ca,那麼任何更新 Column ca 的操作,MySQL在更新表中 Column ca的同時,都須要更新Column ca 的索引數據,調整因爲更新帶來鍵值變化的索引信息。而如果沒有對 Column ca 進行索引,MySQL要做的僅僅是更新表中 Column ca 的信息。這樣,最明顯的資源消耗就是增加了更新所帶來的 IO 量和調整索引所致的計算量。此外,Column ca 的索引idx_ta_ca須要佔用存儲空間,而且隨着 Table ta 數據量的增加,idx_ta_ca 所佔用的空間也會不斷增加,所以索引還會帶來存儲空間資源消耗的增加。

 

較頻繁的作爲查詢條件的字段應該創建索引

唯一性太差的字段不適合單獨創建索引,即使頻繁作爲查詢條件

唯一性太差的字段主要是指哪些呢?如狀態字段、類型字段等這些字段中存放的數據可能總共就是那麼幾個或幾十個值重複使用,每個值都會存在於成千上萬 或更多的記錄中。對於這類字段,完全沒有必要創建單獨的索引。因爲即使創建了索引,MySQL Query Optimizer 大多數時候也不會去選擇使用,如果什麼時候 MySQL Query Optimizer選擇了這種索引,那麼非常遺憾地告訴你,這可能會帶來極大的性能問題。由於索引字段中每個值都含有大量的記錄,那麼存儲引擎在根據索引 訪問數據的時候會帶來大量的隨機IO,甚至有些時候還會出現大量的重複IO。

 

二、數據庫事務

在介紹分佈式事務之前,先簡單瞭解下數據庫事務。

數據庫事務(Database Transaction) :是指作爲單個邏輯工作單元執行的一系列操作,要麼完全地執行,要麼完全地不執行。

事務具有ACID四個特性:

1、原子性(Atomic):事務必須是原子工作單元,對於其修改數據,要麼全部成功,要麼全部失敗。

2、一致性(Consistent):事務在完成時,必須使所有的數據都保持一致狀態。

3、隔離性(Insulation):由併發事務所作的修改必須與任何其它併發事務所作的修改隔離。

4、持久性(Duration):事務完成之後,它對於系統的影響是永久性的。

三、分佈式事務

在分佈式系統中,不止使用一個數據庫,比如訂單系統使用db_order數據庫,產品系統使用的是db_product數據庫,在訂單系統中只能保證訂單相關操作的事務,在產品系統中只能保證產品相關操作的事務。比如:如果在訂單系統中進行生成訂單、扣減庫存的業務,如果出現異常,那麼創建訂單的事務會回滾,而扣減庫存的事務則不會,因爲本地事務是不能誇數據庫的。跨庫的事務就屬於分佈式事務。

把分佈式系統中兩個相關操作看成是一個單元,比如創建訂單和修改庫存的操作,該單元要麼一起成功,要麼一起失敗,這就是分佈式事務。

關於分佈式事務你不得不知的兩個理論:

1、CAP定理

CAP原則又稱CAP定理,指的是在一個分佈式系統中,WEB服務無法同時滿足以下3個特性:

  • 一致性(Consistency) : 在分佈式系統中數據一旦更新,所有數據變動都是同步的

  • 可用性(Availability) : 好的響應性能,每個操作都必須有預期的響應結束

  • 分區容錯性(Partition tolerance) : 在網絡分區的情況下,即使出現單個節點無法可用,系統依然正常對外提供服務

首先在分佈式系統中,橫向擴展策略依賴於數據分區,所以一般會在一致性和可用性上做出犧牲。

2、BASE理論

BASE理論中的三個特性:

  • Basically Available(基本可用)

  • Soft state(軟狀態)

  • Eventually consistent(最終一致性)

三個特性分別指的是:

(1)基本可用是指分佈式系統在出現不可預知的故障的時候,允許損失部分可用性——但請注意,這絕不等價於系統不可用。

(2)軟狀態,和硬狀態對應,是指允許系統中的數據存在中間狀態,並認爲該中間狀態的存在不會影響系統的整體可用性,即允許系統不同節點的數據副本之間進行數據同步的過程存在延時。

(3)最終一致性強調的是系統所有的數據副本,在經過一段時間的同步後,最終能夠達到一個一致的狀態。因此,最終一致性的本質是需要系統保證最終數據能夠達到一致,而不需要試試保證系統數據的強一致性。

BASE理論是對CAP中的一致性和可用性進行一個權衡的結果,理論的核心思想就是:我們無法做到強一致,但每個應用都可以根據自身的業務特點,採用適當的方式來使系統達到最終一致性(Eventual consistency)。

三、分佈式事務解決方案

主要介紹目前主流的兩種分佈式事務解決方案:

1、TCC-補償型事務解決方案

TCC指的是Try(嘗試)、Confirm(確認)、Cancle(取消),其核心思想是:針對每個操作,都要註冊一個與其對應的確認和補償(撤銷)操作。它分爲三個階段:

  • Try 階段主要是對業務系統做檢測及資源預留

  • Confirm 階段主要是對業務系統做確認提交,Try階段執行成功並開始執行 Confirm階段時,默認 Confirm階段是不會出錯的。即:只要Try成功,Confirm一定成功。

  • Cancel 階段主要是在業務執行錯誤,需要回滾的狀態下執行的業務取消,預留資源釋放。

舉個例子,假入 Bob 要向 Smith 轉賬,思路大概是:

1、首先在 Try 階段,要先調用遠程接口把 Smith 和 Bob 的錢給凍結起來。

2、在 Confirm 階段,執行遠程調用的轉賬的操作,轉賬成功進行解凍。

3、如果第2步執行成功,那麼轉賬成功,如果第二步執行失敗,則調用遠程凍結接口對應的解凍方法 (Cancel)。

優點: 跟兩階段提交(2PC)比起來,實現以及流程相對簡單了一些,但數據的一致性比2PC也要差一些

缺點: 缺點還是比較明顯的,在2,3步中都有可能失敗。TCC屬於應用層的一種補償方式,所以需要程序員在實現的時候多寫很多補償的代碼,在一些場景中,一些業務流程可能用TCC不太好定義及處理。

2、基於可靠消息的最終一致性解決方案

舉例說明:訂單系統創建訂單成功後、產品系統扣減相應庫存

訂單系統流程圖如下:

enter image description here

1.創建訂單之前,創建預發送消息,保存到消息表中,此時消息狀態爲:未發送

2.創建訂單,如果創建訂單失敗則將消息表預發送消息刪除

3.創建訂單成功後,修改消息表預發送消息狀態爲發送中,併發送消息至mq

4.如果發送消息失敗,則訂單回滾並刪除消息表消息;發送成功則萬事大吉

產品系統流程圖如下:

enter image description here

1.從mq消息中間件中監聽並消費消息,將json消息轉爲訂單對象

2.根據消息編號查詢該消息是否已被消費,保證冪等性

3.如果消息未被消費(即存在此消息),則產品表扣減庫存;如果已經消費(不存在此消息),則不做處理

4.產品表扣減庫存成功,則刪除此消息;扣減失敗,則不做處理

5.定時任務會定時掃描消息表中超時未被消費的消息,然後嘗試重發,如果超過最大重試次數後仍未被消費,則記錄日誌並通知工作人員進行人工補償操作

基於可靠消息的分佈式事務雖然不能保證結果的強一致,但是可以通過可靠消息使得結果最終一致

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章