TiKV 在京東雲對象存儲元數據管理的實踐

作者介紹:崔燦,京東雲產品研發部專家架構師,目前主要負責京東雲對象存儲產品的工作。

京東雲對象存儲是在 2016 年作爲公有云對外公開的,主要特點是可靠、安全、海量、低成本,應用於包括一些常用的業務場景,比如京東內部的京東商城視頻/圖片雲存儲,面向京東雲公有云外部的開發者的服務,和麪向政府、企業的私有云服務,甚至混合雲服務。

本文將介紹京東雲對象存儲服務的架構演進,以及遷移到 TiKV 的經驗。

一、對象存儲簡介

圖 1 什麼是“對象”

<center>圖 1 什麼是“對象”</center>

首先舉例說明一下這裏的“對象 (Object)”概念。比如我們把一張照片當作一個“對象”,除了照片本身的二進制數據,它還應該包含一些元信息(照片數據長度、上次修改時間等)、涉及用戶的數據(拍攝者、拍攝設備數據等)。對象存儲的特點是這些數據不會頻繁地修改。

如果是數量比較少的圖片存儲,我們可能會用類似 LVM 之類的東西,把一個節點上的多個磁盤使用起來,這種方法一般適用於數量級在 1M ~ 10M 的圖片。隨着業務的增長,圖片會越來越多甚至有視頻存儲,因此我們採用分佈式文件系統來存儲,這種方法是基於 DFS 的架構(如下圖所示)。

圖 2 如何存儲對象(數據量 1B)

<center>圖 2 如何存儲對象(數據量 1B)</center>

這種方法的前提是單機容量受限,必須把數據放在多臺機器上存儲,並且用一個或多個獨立的 node 存儲元數據,並且元數據會維持樹狀目錄的結構,拆分比較困難。但是這個架構一般適合存儲到 10 億級別的對象,同時存在兩個比較大的問題:

  • 數據分佈式存儲在不同的節點上,如果存在一箇中心的 master 節點的數據是相對有限的,那麼這個機器就不太可能無限擴張下去。
  • 元數據管理是樹狀結構,它本身並不適合做分佈式存儲,並且目錄結構需要多次訪問,不適合把它放到 SSD 上,而更適合放在內存裏,然後一般授權一個 master 節點 list。HDFS 基本也是這樣。

那麼如果要求做千億級的對象存儲,如何實現呢?最容易想到的辦法是將元數據分佈式存儲,不再像文件系統中那樣存儲在單獨的機器上,是一個樹狀結構,而是變成一個平坦結構。

二、對象存儲元數據管理系統

回到上面的舉例,針對一個圖片對象我們主要有四類操作:上傳(Put)、下載(Get)、刪除(Delete),Scan。Scan 操作相對比較傳統 ,比如查看當前有多少圖片對象,獲取所有圖片名稱。

1. 元數據管理系統 v1.0

圖 3 如何存儲對象(數據量 100B)

<center>圖 3 如何存儲對象(數據量 100B)</center>

上面是一個最簡單、原始的方案,這裏 Bucket 相當於名字空間(Namespace)。很多人最開始設計的結構也就是這樣的,但後期數據量增長很快的時候會遇到一些問題,如下圖。

圖 4 元數據管理系統 v1.0(1/3)

<center>圖 4 元數據管理系統 v1.0(1/3)</center>

第一個問題是,在初期數據量比較小的時候,可能只分了 4 個 Bucket 存儲,隨着業務增長,需要重新拆分到 400 個 Bucket 中,數據遷移是一個 Rehash 過程,這是一件非常複雜且麻煩的事情。所以,我們在思考對象存儲連續的、跨數量級的無限擴展要怎麼做呢?下圖是一個相對複雜的解決方案,核心思想是把絕大部分數據做靜態處理,因爲靜態的存儲,無論是做遷移還是做拆分,都比較簡單。比如每天都把前一天寫入的數據靜態化,合到歷史數據中去。

圖 5 元數據管理系統 v1.0(2/3)

<center>圖 5 元數據管理系統 v1.0(2/3)</center>

針對第二個問題,如果單個 Bucket 數據量很大,那麼在往 Stable Meta(上圖中黃色部分)做靜態化遷移時需要做深度拆分,單個 Bucket 的對象的數量非常多,在一個數據庫裏面存儲不下來,需要存儲在多個數據庫裏面,再建立一層索引,存儲每個數據庫裏面存儲那個區間的數據。同時,我們在運行的時候其實也會出現一個 Bucket 數量變多的情況,這種是屬於非預期的變多,這種情況下我們的做法是弄了一大堆外部的監控程序,監控 Bucket 的量,在 Bucket 量過大的時候,會主動去觸發表分裂、遷移等一系列流程。

圖 6 元數據管理系統 v1.0(3/3)

<center>圖 6 元數據管理系統 v1.0(3/3)</center>

這個解決方案有兩個明顯的問題,第一數據分佈複雜,管理困難;第二,調度不靈活,給後期維護帶來很大的困難。

圖 7 元數據管理系統改進步目標

<center>圖 7 元數據管理系統改進目標</center>

所以,我們思考了這個事情本質其實是做一個全局有序 KV,並且需要“足夠大”,能夠彈性擴張。這樣系統架構就會變得非常簡單(如上圖所示)。當然最終我們找到了分佈式 KV 數據庫—— TiKV。

2. 基於 TiKV 的元數據管理系統

我們前期調研了很多產品,最終選擇 TiKV 主要原因有以下四點:

  • 全局有序 KV,可輕鬆⽔平擴展,功能上完全能夠滿⾜對象存儲元數據管理的需求。
  • 經過一些測試,性能上很好,能夠滿足要求。
  • 社區活躍,文檔和工具相對比較完善。這一點也很重要,TiKV 目前已經是 CNCF(雲原生計算基金會)的孵化項目,很多功能可以快速開發,產品迭代也很迅速。
  • 相對於 TiDB Server 而言,TiKV 的代碼更加簡單,而且我們後續可以在 TiKV 的基礎上做更多開發工作。

在上線之前,我們主要進行了以下幾方面的測試:

  • 功能測試:測試 TiKV 的基本功能是否滿足業務需求。
  • 性能測試:測試了常規的 QPS、Latency (Avg, TP90, TP99) 等指標。
  • 異常測試:其實我們做數據存儲的同學往往最關注的是各種異常故障的情況,性能倒是其次,而且分佈式存儲相比單機存儲更爲複雜。所以我們測試了各種機器/磁盤/網絡故障,業務異常情況。更進一步的,我們將這些異常情況隨機組合,並在系統內觸發,再驗證系統的正確性。
  • 預發佈環境驗證:在大規模上線之前,我們會在相對不太重要的、實際業務上跑一段時間,收集一些問題和可優化的部分,包括運維上的調優等。

通過上面的測試我們認爲 TiKV 無論是從性能還是系統安全性的角度,都能很好的滿足要求,於是我們在 TiKV 基礎之上,實現了對象元數據管理系統 v2.0,如下圖所示。

圖 8 元數據管理系統 v2.0

<center>圖 8 元數據管理系統 v2.0</center>

將 v1.0 中一堆複雜的數據庫和邏輯結構用 TiKV 替代之後,整個系統變得非常簡潔。

三、業務遷移

很多用戶可能直接將 MySQL 遷移到 TiDB 上,這個遷移過程已經非常成熟,但是由於遷移到 TiKV 前人的經驗比較少,所以我們在遷移過程中也做了很多探索性的工作。

1. 遷移方案

圖 9 遷移方案

<center>圖 9 遷移方案</center>

上圖是我們設計的遷移方案,首先線上的數據都必須雙寫,保證數據安全。第二,我們將存量數據設置爲只讀之後遷移到 TiKV 中,同時遷移過程中的增量數據直接寫入 TiKV,每天將前一日的增量數據做靜態化處理,然後與 MySQL 中的數據對比,驗證數據正確性。另外,如果雙寫失敗,會啓用 MySQL backup。

下面詳細介紹實際操作過程中的相關細節。

2. 切換

在存量數據切換方面,我們首先將存量數據靜態化,簡化遷移、數據對比、回滾的流程;在增量數據切換方面,首先將增量數據雙寫 TiKV & MySQL,並且保證出現異常情況時快速回滾至 MySQL,不影響線上的業務。值得一提的是,由於 TiKV 在測試環境下的驗證結果非常好,所以我們採用 TiKV 作爲雙寫的 Primary。

整個切換 過程分爲三個步驟:

  • 存量數據切換到 TiKV,驗證讀。
  • 增量數據切換到 TiKV,驗證讀寫。
  • 驗證 TiKV 中的數據正確性之後,就下線 MySQL。

3. 驗證

數據驗證過程最大的困難在於增量數據的驗證,因爲增量數據是每天變化的,所以我們雙寫了 MySQL 和 TiKV,並且每天將增量數據進行靜態化處理,用 MySQL 中的記錄來驗證 TiKV 的數據是否可靠(沒有出現數據丟失和錯誤),如下圖所示。

圖 10 雙寫驗證

<center>圖 10 雙寫驗證</center>

因爲同時雙寫 MySQL 和 TiKV 可能會出現一種情況是,寫入 TiKV 就成功了,但是寫入 MySQL 失敗了,這兩個寫入不在同一個事務中,所以不能保證一定同時成功或者失敗,尤其是在業務量比較大的情況下。對於這種不一致的情況,我們會通過業務層的操作記錄,來判斷是由於業務層的問題導致的,還是由 TiKV 導致的。

四、業務現狀及後續優化工作

目前 TiKV 在京東雲對象存儲業務上是 Primary 數據庫,計劃 2019 年年底會把原數據庫下線。總共部署的集羣數量爲 10+,生產環境單集羣 QPS 峯值 4 萬(讀寫 1:1),最大的單集羣數據量 200+億,共有 50 餘萬個 Region,我們元數據管理業務對 Latency 要求比較高,目前 Latency 能保證在 10ms 左右。另外,我們正在測試 TiKV 3.0,預計 2019 年第四季度能夠上線。

針對目前的業務運行情況,我們後續還將做一些優化工作。

第一點是災備,目前我們是在業務層做災備,後續可能會直接在 TiKV 層做災備,也很期待 TiKV 之後的版本中能夠有這方面的功能。

第二點是集羣規模優化,因爲對象存儲是存儲密集型的業務,我們希望壓縮硬件成本,比如可以用到 8T 、10T 的磁盤,或者用更廉價的磁盤,這點我們後續可能 PingCAP 研發同學們一起考慮怎麼優化提升。

第三點是 Region 調度優化,目前 TiKV 的調度整體比較複雜,這對於存儲密集型的業務來說就比較麻煩,尤其是數據量特別大的情況下,我們並不希望有一絲的波動就把數據遷移到其他機器上。

本文整理自崔燦老師在 TiDB TechDay 2019 杭州站上的演講。

原文閱讀https://pingcap.com/cases-cn/user-case-jingdongyun/

更多精彩案例https://pingcap.com/cases-cn/

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