在大規模系統中使用Scala
本文是關于在大規模數據儲存及分析系統中使用Sacla 系列文章中的第一篇。
在過去幾年間,已經有多個項目使用了 Scala 進行大規模數據儲存及分析平臺的設計。
BBC在設計公司內部的RDF數據儲存系統時就使用了Scala以及 Scalatra HTTP框架,這套內部系統可用于查詢BBC新聞與體育所有文章中的鏈接數據。
在整個2014年間,業界對于 Apache Spark 的興趣達到了一個高峰,這是一套使用Scala編寫的數據分析工具。Spark中包含了一套由 Spray 編寫的HTTP接口,它的后端使用了 Akka 用于并行處理。
邁凱倫應用技術 (MAT)在他們的數據分析平臺中也使用了Scala、Scalatra和Akka,作為整個平臺的構建基礎。
為什么這些項目會選擇Scala呢?
為了找到這一問題背后的原因,我們與來自MAT的高級軟件工程師Andrew Jayne進行了一次對話,了解了后者使用Scala創建一個自定義的高性能數據儲存系統的經驗。
邁凱倫應用技術位于倫敦附近,它源自于母公司邁凱倫幾十年以來在F1賽車方面的經驗。從母公司分離之后,MAT也將F1的相關經驗應用在 其它產業 上。
由于MAT深厚的F1背景,因此它們在根據數據進行分析以及進行快速決策方面具備很強的技術實力,例如它們的時間序列數據存儲系統能夠分析一場 F1賽事中車輛的數據流。不過,他們也發現這套序列分析技術在與傳感器設備相結合的情況下,往往能夠應用在賽車之外的其它許多場景中:他們已經對制造業、傳輸業、能源業以及醫療保健行業的部門提出了這項建議。
為了支持MAT的這項咨詢工作,他們的工程師創建了一個序列數據平臺,運行于 AWS 之上。
InfoQ:你是否能為我們概述一下MAT序列數據儲存系統的作用是什么,以及如何使用它?
Jayne :這是一個大容量、高性能的排序式鍵-值存儲系統,它能夠保存讀-寫的一致性,并且具有一個專門為實時及歷史序列數據(根據時間、距離、深度等進行索引)設計的特性集。它允許我們以一種版本控制的方式進行微批量及批量處理,并且可以通過某個REST API對我們的數據分析平臺的輸入與輸出的所有序列進行持久化。這方面有一個例子,我們正在為葛蘭素史克(GSK)設計對漸凍癥(ALS)患者進行監控與分析的系統,這是基于傳感器設備的,通過臨床實驗,讓我們能夠得到在實驗中患者的病癥得到改善,或產生惡化的反饋信息。
InfoQ: MAT序列數據存儲系統是否是用于分析F1相關的時間序列數據的目的,還是更為一般性的目的而存在的?
Jayne :設計這套系統的目的是作為一種一般性的解決方案,對序列數據進行保存與查詢,它基于我們在賽車運動、競技體育、醫療以及能源行業的經驗。我們在這些項目中都面臨著類似的問題,因此急需一種存儲方案,它能夠保持數據完整性,同時又能幫助我們解決這些問題。比方說,如果你的數據來自于某個產生了時鐘漂移的設備,你該怎么做?如果出于帶寬的限制,使得上傳的數據只具有較低的分辨率,那么我們又該如何確保數據的高精度?如果在一段長時間的網絡斷線之后,某個數據源又開始發送數據,那么又會發生什么情況?
InfoQ:這套系統主要針對怎樣的數據集,目標的數據量是什么?
Jayne :它可以用于n維的數值數據,其中包含一個數值型的、嚴格增長的鍵。目前我們的用例除了我們的數據分析結果之外,還包含病患監控設備的傳感器數據、鉆井作業以及數據中心。
InfoQ:為什么選擇Scala?你的技術背景是從Java轉移而來的嗎?這門語言有什么地方吸引了你?
Jayne :整個團隊具有多種語言的背景。在2012之前,我們使用了Java、C#和MATLAB。隨著Typesafe Stack 2.0發布之后,我們就開始采用Scala作為我們的服務以及web應用程序的后端語言。
當時Scala最吸引我們的地方在于它的可伸縮性,例如可以通過使用Actor、不可變對象以及函數式編程簡化并發處理。此外還有一些原因,比如能夠以更加算術式的語法表達程序、模式匹配,并且能夠減少樣板代碼。不過,如果要犧牲Java的互操作性,那我們也不可能會選擇Scala。函數式編程的方式非常新穎、痛快,也為我們展現了更多創新的機會。這個選項很符合團隊的文化與心態。
InfoQ:為什么這套系統沒有選擇Java?
Jayne :我們已經有了一個用Java編寫并基于Hadoop的組件。雖然我們也可以在這個組件的基礎上打造新系統,但其它所有后臺組件都是用Scala編寫的。我們將此看做一次開展研究工作的好機會,很快我們就明白,要支持我們所設計的架構,可以選擇的類庫與技術有哪些了。基于這些研究的經驗,我們意識到可以用函數式編程簡化我們的現有功能。雖然Java很易于使用,但它的語法過于啰嗦,會妨礙我們保持代碼清晰度的意圖。我們已經在商業項目中使用Scala有很多年了,我們發現能夠與創建這門語言以及核心類庫的人們進行交流是很有價值的。
InfoQ :其它的一些時間序列數據庫(TSDB )缺少了什么功能?為什么沒有選擇 KairosDb 、 Druid 、 InfluxDb 、 OpenTSDB ,或其它任何一種現有的TSDB ?
Jayne :對于我們的業務來說,數據完整性與數據管理是至關重要的,并且我們需要對這些數據進行某些程度的保證,以符合代碼端的期望。僅僅實現備份與記錄日志是不夠的。受到了Git的影響,我們最終設計了一套數據儲存系統,它具有基于提交的版本控制能力,以及基于樹狀的組織結構。
我們的驗收場景也提出了額外的挑戰,例如:
- 原子性 —— 不允許在查詢系統時返回不一致的狀態。
- 一致性與正確性 —— 查詢應當是可重復的,并且始終返回一致的、正確的數據。
- 接近實時的寫操作 —— 支持每秒幾百萬次寫入操作(數據來自于高頻率及可變頻率的傳感器),并且在數據寫入后的幾秒鐘之內就可用于查詢。
- 查詢性能 —— 通過在整個頻道中提供可預測且快速的查詢,支持能夠感知延遲的數據分析能力,包括:
- 數據準備(即插值),
- 子集(即窗口、范圍、偏移、限制),
- 聚合(即平均值、最小值、最大值等等),
- 預測(即推斷、回歸、關聯)
- 語言無關性 —— 使用REST API與ETag緩存。
- 通用的數據格式 —— 數據應當與現有的工具兼容,例如CSV、JSON等等。
- 部署復雜性 —— 系統應當使用現有的云端基礎設施(AWS),并且能夠以最小的代價創建新的數據存儲。
這些需求中有很大一部分已經在現有的TSDB中已經得到解決,其中某些TSDB對這些問題的解決方案更為出色。但是,我們所需的某些查詢是其它數據庫所不支持的,也很難對其進行改進。主流的TSDB都是在其它數據庫系統的基礎上創建的(例如HBase),它們的復雜性已經超出了我們的用例的需求。通過使用一種更簡化的、量身訂做的存儲機制,并利用分布式特性,我們就能夠對數據的組織進行優化,更適用于我們所執行的查詢。這種方式也讓系統管理員的工作量以及運行時的成本減至最小。最重要的是,其它數據庫都無法提供這種對數據的版本控制機制,而我們在開發與生產環境中都需要這種機制。
InfoQ:說到REST API,你在項目中使用了Scalatra作為REST HTTP接口,原因是什么?
Jayne :Scalatra的維護工作做得很好,它的發布策略也很明智,我們之前在使用其它框架時曾在這一點上吃過虧。這個框架有一套十分簡單的領域特定語言(DSL),我們只需要進行很少的工作,即請求處理與測試。并且它還能夠使用我們選擇的其它類庫,進行諸如序列化等工作。Scalatra能夠簡單地部署到某個servlet容器中是它的一大優點,并且它的性能也十分出色。
InfoQ:你提到了Actor。那么Akka這個選擇在實際運行中效果如何?我聽說某些人對它愛不釋手,而另一些人則表示自從他們遠離了Akka之后,代碼就變得簡單了許多倍。那么使用它的挑戰又來自于哪里呢?
Jayne :我們在數據儲存系統中使用Akka管理異步的請求,因為一個請求的生命周期中的大部分都是進行I/O操作。它目前還不是一種基于事件的I/O技術,但我們認為Akka的優點在于它的調度器以及對棧溢出的處理。
我們使用了actor模型將某一問題分解為多個子系統集,每個子系統維護自己的狀態,負責自己的可伸縮性。由于在設計時就考慮到了默認的分布式架構,因此你可以利用它的位置透明性特征實現縱向與橫向的擴展。不過,由于失去了正式的接口,這一點也讓我們產生了動搖,因為這意味著我們將失去編譯器檢查的優勢。一種妥協方案是使用正規的協議,讓actor保持簡潔,并讓這些協議在我們的設計與測試中明確地表現出來。編寫清晰的、簡明的測試不是一件簡單的事,而在任何并發系統中進行調試都是一個很大的挑戰。
InfoQ:這套數據庫能夠在多個節點間進行集群化嗎?它的橫向擴展能力如何?這一點與你們選擇了Scala的決定是否有關,還是說無論使用哪一種語言結果都一樣呢?
Jayne :目前來說,它僅在數據處理量以及故障轉移方面做到了可伸縮性,因為API終結點與數據的位置是在一起的。接下來在改善可伸縮性方面的工作是移除這一限制,這樣我們就可以在REST API端使用一種靈活的負載均衡器,并將其從數據儲存層中分解出去。
使用Scala進行開發的速度是非常之快的,并且使用函數式編程能夠讓許多最復雜的處理過程也變得十分清晰。默認的不可變性也鼓勵更清晰的編程模式,并且更容易實現對系統的原子性與一致性的強制實施。不過,在Java中也沒有什么不能做到的,只是我們覺得Scala是最適合我們團隊的工具。
關于作者
Dave Hrycyszyn 是 Head London 的技術總監,這是一家位于英國的數字產品與服務代理商。Dave是 《Scalatra in Action》 一書的作者之一,也是創建 Scalatra 這個微框架的團隊的成員之一。他在自己的博客 constructiveproof.com 上撰寫了大量有關于Scala、API和與數據相關的主題文章。
查看英文原文: Scala in Large Scale Systems