數據庫怎麼選擇?終於有人講明白了

作者 | Alex Petrov

所有數據庫管理系統的主要工作都是可靠地存儲數據並使其對用戶可用。我們使用數據庫作爲數據的主要來源,幫助我們在應用程序的不同部分之間共享數據。我們使用數據庫,而不是在每次創建新應用程序時尋找存儲和檢索信息的方法,也不是每次都去發明一種組織數據的新方法。這樣一來,我們就可以專注於應用程序邏輯而不是基礎設施。

數據庫是模塊化的系統,由多個部分組成:接受請求的傳輸層、決定以最高效方式運行查詢的查詢處理器、執行操作的執行引擎以及存儲引擎。

存儲引擎(或數據庫引擎)是數據庫的一個軟件組件,它負責在內存和磁盤上存儲、檢索和管理數據,而設計它的目的是長久保存每個節點的數據[REED78]。數據庫可以響應複雜的查詢,存儲引擎則會更細粒度地看待數據並提供一組簡單的數據操作API,允許用戶創建、更新、刪除和檢索數據記錄。從某個角度來看,數據庫是構建在存儲引擎之上的應用程序,它提供了表結構(schema)、查詢語言、索引、事務和許多其他有用的特性。

爲了獲得靈活性,鍵和值都可以是沒有預設格式的任意字節序列。它們的排序和表示語義是在更高級別的子系統中定義的。例如,你可以在一個表中使用int32(32位整數)作爲鍵,而在另一個表中使用ascii(ASCII字符串);從存儲引擎的角度來看,這兩個鍵都只是序列化的條目。

BerkeleyDB、LevelDB(及其後代RocksDB)、LMDB(及其後代libmdbx、Sophia和HaloDB)等存儲引擎的開發都與它們現在所嵌入的數據庫彼此獨立。使用可插拔的存儲引擎使數據庫開發人員能夠使用現有存儲引擎來構建數據庫系統,並將精力集中在其他子系統上。

同時,數據庫系統組件之間清晰的解耦爲切換不同引擎提供了機會,這些引擎可能分別適用於特定的用例。例如:流行的數據庫MySQL有幾個存儲引擎,包括InnoDB、MyISAM和RocksDB(在MyRocks發行版中),而MongoDB則允許在WiredTiger、內存以及(現已棄用的)MMAPv1存儲引擎之間進行切換。

 

數據庫的比較

 

對數據庫系統的選擇將會產生長期的影響。如果選擇的數據庫不合適(因其導致性能問題、一致性問題或運維上的挑戰),那麼我們最好在開發週期的早期就發現這一點,因爲遷移到不同的系統可能並非易事,甚至在某些情況下,你還需要對應用程序的代碼進行重大的修改。

每個數據庫系統都有優點和缺點。爲了降低進行高成本遷移的風險,你可以在選擇數據庫上投入一些時間,以確保其具備滿足應用程序需求的能力。

試圖根據數據庫的組件(例如:使用的存儲引擎,數據共享、複製和分佈的方式等)、它們的排名(ThoughtWorks等諮詢機構或諸如DB-Engines和Database of Databases等數據庫比較網站所呈現的流行度值)或實現語言(C、Java或Go等)來比較數據庫,可能導致無效和不成熟的結論。這些方法只能用於高層次上的比較,並且可能出現例如在HBase和SQLite之間進行選擇這樣粗糙的對比。因此,即使只是對每個數據庫的工作原理和內部結構有粗淺瞭解,這些瞭解也可以很好地幫助你得出一個更可靠的結論。

每一次比較都應該從清晰界定的目標開始,因爲哪怕是最小的偏差都可能使整個調查完全無效。如果你正在找尋一個非常適合當下(或者未來)的工作負載的數據庫,那麼你所能做的最好的事情就是在不同的數據庫系統上模擬這些工作負載、測量對你很重要的那些性能指標,並比較結果。有些問題(特別是性能和可伸縮性方面的問題)只有在一段時間後或隨着容量的增長才會開始顯現出來。爲了發現潛在的問題,最好在儘可能接近真實生產環境的環境中進行長期的運行測試。

模擬現實世界中的工作負載不僅能幫助你瞭解數據庫的運行方式,還能幫助你學習如何操作與調試數據庫,並瞭解其社區的友好程度和能提供幫助的程度。數據庫的選擇總是這些因素的組合,而性能通常並不是最重要的方面:使用保存數據緩慢的數據庫通常比使用會快速丟失數據的數據庫要好得多。

要比較數據庫,非常詳細地理解用例並定義當前和預期的變量是有幫助的,例如:

  • 表結構和記錄大小

  • 客戶端數量

  • 查詢類型和訪問模式

  • 讀寫查詢速率

  • 任何這些變量中的預期變化

明確這些變量可以幫助回答以下問題:

  • 數據庫支持所需的查詢嗎?

  • 數據庫能夠處理我們計劃存儲的數據量嗎?

  • 單個節點可以處理的讀寫操作有多少?

  • 一個系統計劃要有多少個節點?

  • 鑑於預期的增長率,我們如何擴展集羣?

  • 維護過程是什麼?

在回答了這些問題之後,你可以構建一個測試集羣並模擬你的工作負載。大多數數據庫已經有了壓測工具,可以用來重現特定的用例。如果沒有標準的壓測工具用來在數據庫生態系統中生成現實中的隨機工作負載,那麼這可能是一個危險的信號。如果有什麼東西讓你無法使用數據庫自帶的工具,那麼你可以嘗試一個現有的通用工具,或者從零開始實現一個。

如果測試結果理想,那麼進一步熟悉數據庫代碼可能會有更大的幫助。爲了閱讀源代碼,首先要了解數據庫的各個部分、如何查找不同組件的源代碼,然後瀏覽這些組件。即使僅對數據庫代碼庫有一個粗略的瞭解,也有助於你更好地理解它產生的日誌和配置參數,並幫助你在使用數據庫的應用程序中,甚至在數據庫代碼本身發現問題。

有些人以爲,可以將數據庫當作黑匣子而無須瞭解其中的內容是件好事。但實踐往往表明,這樣做遲早會碰到bug、服務中斷、性能倒退或其他問題。你最好爲這些問題做好準備,如果你瞭解並且理解數據庫的內部結構,就可以減少業務風險且更有可能快速地恢復。

用於基準測試、性能評估和比較的一個流行工具是Yahoo! Cloud Serving Benchmark(YCSB)。YCSB提供了一個框架和一組可應用於不同數據存儲的公共工作負載集。就像任何通用的東西一樣,你應該小心使用這個工具,因爲使用它很容易得出錯誤的結論。爲了進行公平的比較並做出明智的決定,你需要投入足夠的時間來了解數據庫將在何種實際環境下運行,並相應地調整基準測試的內容。

TPC-C基準

事務處理性能委員會(Transaction Processing Performance Council,TPC)提供了一組數據庫廠商用來比較和宣傳其產品性能的基準。TPC-C是一個聯機事務處理(OLTP)基準,它是隻讀事務和更新事務的混合,用於模擬常見的應用程序工作負載。

該基準關注的是執行的併發事務的性能和正確性。主要性能指標是吞吐量:數據庫系統每分鐘能夠處理的事務數。其需要執行事務具備ACID屬性並符合基準本身定義的屬性集。

此基準不專注於任何特定的業務部門,但提供了對大多數適用OLTP數據庫的應用都很重要的抽象操作集。它包括幾個表和實體,如倉庫、庫存、客戶和訂單,並指定了表佈局、可以對錶執行的事務的細節、表的最小行數和數據持久性約束。

這並不意味着基準測試只能用於比較數據庫。基準可用於定義和測試服務級別協議注1的詳細信息、瞭解系統要求以及容量規劃等。你在使用數據庫之前對它瞭解得越多,在生產環境中運行數據庫時節省的時間就越多。

選擇數據庫是一個長期的決定,最好跟蹤新發布的版本,瞭解到底發生了什麼變化及其原因,並制定升級策略。新版本通常包含對bug和安全問題的改進及修復,但也可能會引入新的bug、性能退化或意外行爲,因此在部署新版本之前測試新版本也是至關重要的。查看數據庫開發者以前是如何處理升級的,可能會讓你對將來的情況有一個很好的瞭解。過去的順利升級並不能保證未來的升級也會如此順利,但過去複雜的升級可能也是未來升級亦會不容易的標誌。

 

理解權衡取捨

 

作爲用戶,我們可以看到數據庫在不同條件下的行爲,但是在使用數據庫時,我們必須做出選擇來直接影響其行爲。

設計一個存儲引擎肯定比僅實現一個教科書上的數據結構要複雜得多:很難在一開始就將許多細節和邊界情況處理正確。我們需要設計物理數據佈局和組織指針、決定序列化格式、瞭解數據將如何被進行垃圾收集、存儲引擎如何適應整個數據庫系統的語義、探索如何使其在併發環境中工作,以及最後確保在任何情況下都不會丟失任何數據。

不僅有許多事情需要決定,而且這些決定中的大多數都涉及權衡取捨。例如,如果按數據插入數據庫的順序保存,我們就可以更快地存儲它們;但是如果按字典順序檢索它們,我們就必須在將結果返回給客戶端之前對它們進行重新排序。正如你將在本書中看到的那樣,存儲引擎設計有許多不同的方法,每個實現都有它自己的優點和缺點。

在研究不同的存儲引擎時,我們會討論它們的優點和缺點。如果對於每個可以想到的用例都有一個絕對最優的存儲引擎,那麼人人都一定會使用它。但是並不存在這樣的儲存引擎,因此我們需要根據服務的工作負載和用例進行明智的選擇。

市面上有許多存儲引擎,它們使用各種數據結構並且用不同的語言實現—從低級語言(如C)到高級語言(如Java)。所有存儲引擎都面臨相同的挑戰和限制。可以將其與城市規劃相類比:我們爲特定的人口數量構建一座城市,並選擇是在高度上還是面積上對這座城市進行擴展。這兩種情況都可以將同樣數量的人放入該城市,但這些方法導致了截然不同的生活方式。當在高度上建設城市時,人們住在公寓裏,人口密度可能導致面積較小地區的交通流量增加;而在一個面積更大且更分散的城市中,人們更有可能住在大房子裏,但通勤則需要走更遠的路。

類似地,存儲引擎的開發人員所做的設計決策使它們更適合於不同的情況:有些對低讀寫延遲進行了優化,有些則試圖最大化存儲密度(每個節點存儲的數據量),而有些則專注於運維上的簡單性。

在《數據庫系統內幕》的小結中,你可以找到可用於實現的完整算法和其他附加參考。閱讀本書可以使你爲高效地利用這些資料而做好準備,並使你對其中所述概念的現有替代辦法有紮實的理解。

本文摘編於《數據庫系統內幕》,經出版方授權發佈。

推薦閱讀

真香,朕在看了!

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