基於雲上分散式NoSQL的海量氣象數據存儲和查詢方案

前言

氣象數據是一類典型的大數據,具有數據量大、時效性高、數據種類豐富等特點。氣象數據中大量的數據是時空數據,記錄了時間和空間範圍內各個點的各個物理量的觀測量或者模擬量,每天產生的數據量常在幾十TB到上百TB的規模,且在爆發性增長。如何存儲和高效的查詢這些氣象數據越來越成為一個難題。

傳統的方案常常採用關係型資料庫加文件系統的方式實現這類氣象數據的存儲和實時查詢,這種方案在可擴展性、可維護性和性能上都有一些缺陷,隨著數據規模的增大缺點越來越明顯。最近幾年,學界和業界開始不約而同的轉向利用分散式NoSQL存儲來解決海量氣象數據的存儲和實時查詢問題,相比之前的方案,可以支撐更大規模的數據量並提供更好的查詢性能,並且在穩定性、可管理性等方面,也得到了顯著的提升。

另一方面,利用雲計算的資源來解決氣象大數據的解析、存儲、查詢與分析也成為一種趨勢和方向。雲上有著豐富的產品服務和彈性的計算資源,可以在雲上完成一整套的氣象數據處理工作流:利用雲上的分散式存儲進行氣象數據的存儲和實時查詢,利用大數據計算服務進行氣象數據的分析和加工,利用各種應用服務搭建氣象平台與應用。

因此,今天越來越多的氣象領域科研人員,以及海洋、地震等等領域的科研人員,開始了解雲計算,了解分散式存儲,並思考如何基於這些服務,進行海量氣象數據的存儲和查詢方案設計。本文會基於表格存儲(TableStore, 原OTS)在氣象領域的解決方案的探索,介紹如何使用表格存儲解決海量氣象數據的存儲和實時查詢難題。

氣象數據的特點和查詢方式

這一章會介紹一下氣象數據(主要是模式數據)的特點,以及幾種查詢方式,並由此引出為了實現海量氣象數據的存儲和實時查詢,我們需要解決哪些問題。

模式數據

氣象數據中非常重要的一部分數據是模式數據,用於數值模式預報。模式數據是由高性能計算機根據地面、高空、衛星等感測器上的實時觀測數據通過物理方程計算得出的,產生模式數據的系統是一套龐大的計算系統,一般各個發達國家的氣象機構都會有自己的一套模式系統。

模式系統每天會計算幾次,每次生成幾百個物理量在未來一段時間(比如240小時)的不同海拔高度下的一系列經緯度網格預報數據,網格上的每個點代表這個高度這個經緯度上未來某時刻某個物理量的預報數值。

模式數據具有多維特點

模式數據具有明顯的多維特點,以模式系統每次產生的數據為例,包含以下五個維度:

1. 物理量,或者稱為要素:溫度、濕度、風向、風速等等。

2. 預報時效:未來3小時、6小時、9小時、72小時等等。

3. 高度。

4. 經度。

5. 緯度。

當我們固定某一要素某一預報時效,那麼高度、經度、緯度就構成一個三維網格數據,如下圖所示(圖片來自互聯網)。每個格點代表了一個三維空間上的點,上面的數值為該點在某一預報時效(比如未來三小時)下,某一物理量(比如溫度)的預報值。

假設一個三維格點空間包含10個不同高度的平面,每個平面為一個2880 x 570的格點,每個格點保存一個4位元組數據,那麼這三維的數據量為2880 x 570 x 4 x 10, 大約64MB。這僅僅是某個模式系統對某個物理量某一時效下的一次預報,可見模式數據的總量是非常大的。

模式數據的查詢方式

預報員會通過頁面的形式瀏覽各種模式數據,並進行數值模式預報。這個頁面需要提供多種模式數據的查詢方式,比如:

  1. 查詢一個經緯度平面的格點數據:比如未來三小時全球地面溫度的格點數據,或者未來三小時浙江省地面溫度數據。
  2. 查詢某個格點的時間序列數據:比如阿里雲公司所在地未來3小時、未來6小時、一直到未來72小時的溫度。
  3. 查詢不同物理量的數據:比如查詢某一預報時效、某一高度、某一點的全部物理量的預報數據。
  4. 查詢不同模式系統產生的數據:比如同時查詢歐洲中心的某一模式數據和中國氣象機構產生的對應數據等。

查詢方式不限於以上幾種,本文重點分析前兩種較為典型的查詢方式,即「查詢一個經緯度平面的格點數據」和「查詢某個格點的時間序列數據」。

方案要解決哪些問題

首先是存儲方面的問題。海量的氣象數據必須採用多台伺服器進行存儲,問題在於如何選擇或者構建一個分散式存儲系統來保障數據可靠性、可管理性和系統可維護性。

然後是查詢的問題。預報員在進行氣象預報時,需要快速的瀏覽大量的氣象數據,才能高效準確的進行氣象預報。因此,各種查詢操作的延遲要很低,必須在毫秒級。上面提到,數據是分布在多台機器之中的,為了實現毫秒級的延遲,必須滿足以下兩點:

1. 能夠根據查詢條件,高效的定位到要查詢的數據。

2. 定位到數據之後,需要高效的篩選出本次查詢所需的數據。比如查詢某個點的時間序列數據,需要只篩選出該點的數據。

下面我們來看傳統方式和分散式NoSQL方式分別如何解決該問題。

傳統的氣象數據存儲查詢方案

由於多維氣象數據具有數據量大的特點,所以傳統的存儲方式是文件系統,而非資料庫。在文件系統中,每個維度作為一個目錄,形成一個樹形的目錄結構,數據文件作為樹的葉子節點,如下圖所示。

上圖只是一個示意圖,實際存儲時數據的層次關係和目錄結構設計會因地而異,不同的研究機構會採用不同的目錄結構設計。一個需要考慮的問題是,一個數據文件需要控制在多大,即一個數據文件要保存多少維度信息的數據。如果每個文件都很小,文件系統中就會有大量的小文件,導致定位文件的延遲增加,維護這些小文件的負擔也較大。如果每個文件都較大,那麼就要避免在查詢時讀取整個文件,導致延遲很高。

下面我們來看這種方案分別如何解決存儲和查詢問題。對於存儲,這種方案會人為的將不同類型的數據劃分到不同的伺服器上,實現數據的分散式保存,每台機器的目錄結構都如上圖所示。為了維護某種類型的數據對應哪台機器,常採用關係型資料庫進行記錄,或者使用配置文件的方式。

對於數據的查詢,這種方案常會先從關係型資料庫中獲取要查詢的數據文件所在的機器和文件系統路徑,然後訪問對應機器上的agent進行查詢。這個agent會訪問本地文件系統,讀取數據文件,並篩選和處理出用戶所需的數據。這個agent是必不可少的,其作用是在本地先對數據進行一遍篩選和處理,以減少傳輸的網路流量。

這裡我們可以舉一個例子,假設我們要獲取某個點在某一高度的未來72小時的時間序列數據,預報時效間隔3小時,那麼其實只是獲取24個數值。問題在於這24個數值涉及的數據文件可能很大,可能達到幾百MB的級別,因為其中的冗餘數據太多了,其他的經緯度格點,其他高度的數據我們都是不關心的。本地agent在讀取數據時,如果數據採用特定的文件格式,比如NetCDF,可以只讀取一個大文件中的一部分,起到優化效果。

這種模式的缺點也很明顯:

1. 人為的將不同類型的數據存儲在不同機器上,需要解決數據可靠性和可用性的問題,帶來很大的維護負擔。

2. 數據種類和存儲節點的對應關係是確定好的,在新增或者刪減數據時需要人為進行調整,可擴展性較差。

3. 為了優化查詢性能,必須開發一個agent程序,啟動在存儲節點上。這個程序負責從數據文件中篩選出符合條件的一小部分數據,假設數據文件採用NetCDF格式存儲,本地agent可以只讀取文件中的一部分內容,減少讀盤的延遲。這種定製化的方案帶來了一些開發維護成本,同時這個agent也難以集成到現有的成熟的分散式存儲系統中,即這是一種基於本地文件系統和NetCDF文件格式的特定優化。

使用表格存儲進行氣象數據存儲和查詢的方案

表格存儲(TableStore)是一款雲上的分散式NoSQL數據存儲服務,支持高並發的數據讀寫和PB級別的數據存儲能力,提供毫秒級的讀取性能。通過上面對傳統方案的分析,我們對海量氣象數據的存儲和查詢已經有了一定認識,那麼表格存儲如何解決其中的問題呢?

首先,表格存儲是一種分散式NoSQL存儲服務,數據本身會分散到不同的機器上,單集群可以支撐10PB的數據規模,這就解決了存儲的問題。

其次,表格存儲支持快速的單行查詢和範圍查詢,從數據模型上可以認為是一個巨大的SortedMap。即使表中擁有幾百億、幾萬億行數據,單行數據的定位速度並不會下降,這就解決了文件系統在大量小文件時定位慢的問題。

從查詢的角度來看,越高效準確的定位到數據,讀取以及返回的冗餘數據越少,查詢效率越高。那麼我們可以把表格存儲中一行或者一列的數據大小控制在一個恰當的粒度,以此來滿足各種查詢方式的需求。實踐中已經驗證,這種方式可以帶來非常優秀的性能。下面具體來看存儲方案的設計。

存儲方案設計

表格存儲的數據模型如下圖所示,每行數據分為主鍵和屬性列,通過主鍵來標示一行數據。

下文中的方案重點來講主鍵列和屬性列如何設計,並且如何實現兩種典型的查詢方式, 即「查詢一個經緯度平面的格點數據」和「查詢某個格點的時間序列數據」。

方案一

對於氣象中的某種模式數據Data,我們暫且用下面的方式表示:

Data = F(物理量、起報時間、高度、預報時效、經度、緯度)

我們可以把前四個維度作為主鍵(PrimaryKey,簡稱PK),後兩個維度的數據作為屬性列保存,表示為:

Row(物理量、起報時間、高度、預報時效) = F(經度、維度)

PK = (物理量、起報時間、高度、預報時效)

Data = F(經度、維度) = 二維的經緯度格點數據(我們採用binary格式存儲在屬性列中)

Meta = 一些其他的輔助信息,比如數據是否壓縮等等。

那麼 Row(PK) = (Data, Meta, 其他屬性列), Table = SortedMap(Rows), 如下圖所示。

這種方式下,對於查詢「一個經緯度平面的格點數據」, 那麼只需要把物理量、起報時間、高度、預報時效這些信息拼成主鍵,然後通過表格存儲的GetRow介面讀取一行數據即可,如果一次要獲取多個經緯度平面的數據,可以通過BatchGetRow介面一次讀取多行數據。讀取完成後,客戶端需要解析出屬性列中存儲的二進位數據,因為氣象數據的壓縮率較高,這種方式下推薦對數據進行壓縮。

設計這種方案時很重要的考慮因素是,一行存儲多大粒度的數據。這裡一行只存儲一個經緯度平面的數據,以2880 x 570的float數據為例為例,數據量為2880 x 570 x 4=6.3MB數據,壓縮後數據量更小。這個粒度對於存儲和查詢都較為合適,而且氣象中大部分查詢請求也是讀取一個平面。

但是這種方案有一個缺點,對於「查詢某個格點的時間序列數據」,必須先讀取出一個完整的經緯度格點數據,然後篩選出所需的一個格點。因為獲取的冗餘數據太多,所以對這個查詢場景不能提供很好的性能。由此我們引出方案二。

方案二

為了滿足「查詢某個格點的時間序列數據」的需求,我們想到通過對數據再切分,來減小數據的粒度,縮小冗餘數據的查詢和返回。為了縮小數據的粒度,我們把一行中的一個經緯度平面再切分為100個方格,存儲在100個屬性列中。下圖是一個切分的例子,我們把一個481 x 641的平面,切分成很多49 x 65的方格,每個方格的數據保存為一列,列名為Data_x_y, (x, y)是這個方格的左上角坐標。

此時, Row(PK) = (Data_x1_y1, Data_x2_y2, Data_x3_y3, ... , Meta)

切分示意圖如下:

這種方式下,對於「查詢某個格點的時間序列數據」,我們先根據切分方式算出這個格點落在哪個屬性列中,然後設置只讀取該屬性列,然後使用BatchGetRow介面批量讀取不同預報時效的數據,即可獲取並篩選出「這個格點的時間序列數據」。相比方案一,這裡讀取的數據量縮小了100倍,性能得到了巨大的提升。

如果讀取的不是某個格點,而是讀取一部分區域的數據。那麼可以先算出這個區域涉及哪些小方格,只讀取這些小方格的數據,也可以大量的減少冗餘數據的讀取。

如果需要讀取整個平面,方案一和方案二都可以滿足。方案一的好處在於數據放在一起可以獲得較好的壓縮率,因此業務上可以考慮綜合使用方案一和方案二,還是只使用方案二。

方案優缺點

採用表格存儲的方案之後,新的查詢方式如下圖所示:

這種方案的優點可以總結一下:

1. 高可靠和高可用保障,可維護性和可擴展性強。採用成熟的分散式NoSQL系統,相比人為的管理多台伺服器的文件系統,可靠性和可用性有巨大提升。可擴展性強,針對不同類型的模式數據,都可以方便的納入這一系統中來。

2. 彈性的存儲和計算資源。使用公共雲上的表格存儲服務,只需要按量付費,大大的節約了成本,並且可以應對短期的容量或訪問高峰。

3. 性能優異,架構簡單。實際測試中,上述方案的性能遠優於傳統方案。同時,傳統方案需要在服務端啟動一個agent來優化讀取性能,在表格存儲的方案中已經不再需要開發類似的agent,架構更加簡單,分層清晰。

這種方案的缺點在於,氣象系統的開發工程師需要對分散式NoSQL較為了解,特別是在進行方案二的實現時,需要對數據進行切分,有一些開發上的複雜度。

總結

本文針對氣象領域中海量模式數據的存儲和查詢問題,分別介紹了傳統方案和採用表格存儲的方案,並對方案優缺點進行了一些總結。我們看到,利用分散式系統和雲計算服務來解決各行各業的大數據問題已經越來越成為一種趨勢。本文只是拋磚引玉,相信今後能夠看到更多更優雅的行業解決方案在雲上落地。

原文

更多技術乾貨敬請關注云棲社區知乎機構號:阿里云云棲社區 - 知乎

推薦閱讀:

#研發解決方案#數據開放實驗室:再戰即席查詢和數據開放
大數據學習計劃(不斷改善)
消費金融大數據、決策與場景如何做?
2017北京雲棲大會拉開帷幕,Clouder Lab動手實驗室受開發者歡迎
史無前例開放!阿里內部集群管理系統Sigma混布數據

TAG:大数据 | NoSQL | 分布式存储 |