分區如何在分片數據庫系統中提高性能
譯文譯者 | 李睿
審校 | 孫淑娟
InfluxData公司資深軟件工程師Nga Tran曾在一篇文章中描述了分片數據庫系統來擴展查詢和攝取工作負載的吞吐量和性能。而本文將介紹另一種常用技術,也就是分區,它為分片數據庫在性能和管理方面提供了更多優勢,還將描述如何有效地處理查詢和攝取工作負載的分區,以及如何管理讀取要求完全不同的熱分區和冷分區。
分片 vs. 分區
分片是一種在分布式數據庫系統中拆分數據的方法。每個分片中的數據不必共享CPU或內存等資源,并且可以并行讀取或寫入。
圖1是一個分片數據庫的示例。例如美國50個州的銷售數據被分成4個分片,每個分片包含12個或13個州的數據。通過為每個分片分配一個查詢節點,讀取所有50個州的作業可以在并行運行的這四個節點之間拆分,并且與通過一個節點讀取所有50個州的設置相比,其執行速度將快四倍。
圖1銷售數據分為四個分片,每個分片分配給一個查詢節點
分區是一種將每個分片中的數據拆分為非重疊分區以進行進一步并行處理的方法。這減少了不必要數據的讀取,并允許有效地實施數據保留策略。
在圖2中,每個分片的數據按銷售日進行分區。如果需要創建一個特定日期(例如2022年5月1日)的銷售報告,查詢節點只需要讀取其對應分區2022.05.01的數據。
圖2每個分片的銷售數據進一步拆分為非重疊的日期分區
本文的其余部分將關注分區的影響,并將看到如何有效地管理對熱數據和冷數據的查詢和攝取工作負載的分區。
分區效果
數據分區的三個最常見的好處是數據剪枝、節點內并行性和快速數據刪除。
數據剪枝
數據庫系統可能包含幾年的數據,但大多數查詢只需要讀取最近的數據(例如“最近三天有多少訂單?”)。將數據分區到不重疊的分區中,如圖2所示,可以輕松跳過整個越界分區,并只讀取和處理相關的非常小的數據集以快速返回結果。
節點內并行性
多線程處理和流數據在數據庫系統中對于充分利用可用CPU和內存并獲得最佳性能至關重要。而將數據劃分為小分區可以更輕松地實現每個分區執行一個線程的多線程引擎。對于每個分區,可以產生更多線程來處理該分區內的數據。了解分區統計信息(例如大小和行數)將有助于為特定分區分配最佳CPU和內存量。
快速數據刪除
許多企業只保留最近的數據(例如最近三個月的數據),并希望盡快刪除舊數據。通過在不重疊的時間窗口上對數據進行分區,刪除舊分區變得像刪除文件一樣簡單,無需重新組織數據和中斷其他查詢或攝取活動。如果必須保留所有數據,本文后面的部分將介紹如何以不同方式管理新舊數據,以確保數據庫系統在所有情況下都能提供出色的性能。
存儲和管理分區
針對查詢工作負載進行優化
一個分區已經包含一部分數據,因此不希望將一個分區存儲在許多較小的文件中(或者在內存數據庫的情況下為塊)。一個分區應該只包含一個或幾個文件。
最小化分區中的文件數量有兩個重要的好處。它既減少了讀取數據以執行查詢的I/O操作,又改進了數據編碼/壓縮。改進編碼反過來會降低存儲成本,更重要的是,通過讀取更少的數據來提高查詢執行速度。
針對攝取工作負載進行優化
Naive攝取。為了將一個分區的數據保存在一個文件中以利于上述讀取優化,每次攝取一組數據時,都必須將其解析并拆分為正確的分區,然后合并到其對應分區的現有文件中,如圖3所示。
由于I/O以及混合和編碼分區數據的成本高昂,將新數據與現有數據合并的過程通常需要時間。這將導致向客戶端返回數據已成功攝取的響應以及對新攝取的數據的查詢的長時間延遲,因為它不會立即在存儲中可用。
圖3新數據與現有數據立即合并到同一個文件中的原始攝取
低延遲攝取。為了保持每次攝取的低延遲,可以將過程分為兩個步驟:攝取和壓縮。
攝取
在攝取步驟中,攝取的數據被拆分并寫入自己的文件,如圖4所示。它不會與分區的現有數據合并。一旦攝取的數據成功持久化,攝取客戶端將收到成功信號,并且新攝取的文件將可用于查詢。
如果攝取率很高,許多小文件將累積在分區中,如圖5所示。在這個階段,需要從分區中獲取數據的查詢必須讀取該分區的所有文件。當然,這對查詢性能來說并不理想。如下所述的壓縮步驟將文件的這種積累保持在最低限度。
圖4將新攝取的數據寫入新文件
圖5 在高攝取數據工作負載下,一個分區將累積許多文件
壓縮
壓縮是將一個分區的文件合并成一個或幾個文件的過程,以獲得更好的查詢性能和壓縮。例如,圖6顯示了將分區2022.05.01中的所有文件合并為一個文件,并將分區2022.05.02中的所有文件合并為兩個文件,每個文件小于100MB。
對于不同的系統,關于壓縮頻率和壓縮文件的大小的決定會有所不同,但共同的目標是通過減少I/O(即文件數量)并使文件足夠大以有效壓縮來保持高查詢性能。
圖6 將一個分區的多個文件壓縮成一個或幾個文件
熱分區 vs. 冷分區
經常查詢的分區稱為熱分區,而很少讀取的分區稱為冷分區。在數據庫中,熱分區通常是包含最近數據的分區,例如最近的銷售日期。冷分區通常包含較舊的數據,這些數據不太可能被讀取。
此外,當數據變舊時,通常會以較大的塊進行查詢,例如按月甚至按年進行查詢。以下是一些將數據從熱到冷明確分類的示例:
- 熱:本周的數據。
- 不太熱:前幾周但是當月的數據。
- 冷:來自前幾個月但是本年度的數據。
- 更冷:去年及以前的數據。
為了減少冷熱數據之間的歧義,需要找到兩個問題的答案。首先,需要量化熱、不太熱、冷、更冷,甚至可能越來越冷的數據。其次,需要考慮在讀取冷數據的情況下,如何實現更少的I/O。每個文件代表一天的數據分區,人們不想只是為了獲得去年的銷售收入而去讀取365個文件。
分層分區
圖7所示的分層分區為上述兩個問題提供了答案。本周每一天的數據都存儲在其自己的分區中。本月前幾周的數據按周劃分。本年度前幾個月的數據按月份劃分。更早的數據按年份劃分。
通過定義活動分區來代替當前的日期分區,可以放寬該模型。在活動分區之后到達的所有數據將按日期進行分區,而在活動分區之前的數據將按周、月和年進行分區。這允許系統根據需要保留盡可能多的最近使用的小分區。盡管本文中的所有示例都按時間分區數據,但只要可以為分區及其層次結構定義表達式,非時間分區的工作方式也將類似。
圖7分層分區
分層分區減少了系統中的分區數量,使其更易于管理,并減少了在查詢較大和較舊的塊時需要讀取的分區數量。
分層分區的查詢過程與非分層分區的查詢過程相同,因為它將應用相同的數據剪枝策略來僅讀取相關分區。攝取和壓縮過程會稍微復雜一些,因為在其定義的層次結構中組織分區會更加困難。
聚合分區
許多企業并不想保留舊數據,而是希望保留聚合數據,例如每個月的訂單數量和每種產品的總銷售額。這可以通過聚合數據并按月分區提供支持。但是,由于聚合分區存儲聚合數據,因此它們的架構將與非聚合分區不同,這將導致攝取和查詢的額外工作。有不同的方法來管理這些冷數據和聚合數據,但它們是適合未來的大主題。
文章標題:??Partitioning for performance in a sharding database system??,作者:Nga Tran