Elasticsearch是一款很是流行的日誌檢索和分析工具,尤爲在實時性、擴展性、易用性和全文檢索方面有着很是優異的綜合表現。知乎上有一篇文章,Golion:降維打擊!使用ElasticSearch做爲時序數據庫,而且取得了很是不錯的效果。不少知乎用戶不由詢問,Elasticsearch是否能夠用於海量金融數據的存儲和分析?git
爲此咱們對DolphinDB和Elasticsearch在不一樣規模的金融數據集作了綜合的對比測試。測試的內容包括I/O,磁盤空間佔用,內存消耗,數據庫查詢(過濾查詢和分組統計)4大項。測試結果沒有意外,在金融數據處理領域表現十分搶眼的時序數據庫DolphinDB完勝Elasticsearch。github
DolphinDB database 是一款分析型的分佈式時序數據庫,採用列式存儲,內置流數據處理引擎,並行計算和分佈式計算引擎,並提供分佈式文件系統,支持集羣擴展。DolphinDB以C++編寫,響應速度極快。提供類SQL和Python的腳本語言對數據進行操做。提供其它經常使用編程語言的API,方便與已有應用程序集成。在金融領域中的歷史數據分析建模與實時流數據處理,以及物聯網領域中的海量傳感器數據處理與實時分析等場景中表現出色。數據庫
Elasticsearch是一個基於Lucene的搜索服務器,它是基於本地磁盤存儲數據的分佈式系統,並面向文檔進行存儲。它和傳統的數據庫有如下相似的對比關係:編程
Relational DB =>Databases =>Tables => Rows => Columns服務器
Elasticsearch =>Indices=>Types=>Documents => Fieldsapp
Elasticsearch集羣能夠包含多個索引(Indices),對應DolphinDB的數據庫;每個索引能夠包含多個類型(Types),對應DolphinDB中的表;每個類型包含多個文檔(Documents),對應DolphinDB數據中的行;而後每一個文檔包含多個字段(Fields),對應DolphinDB中的列的概念。編程語言
本次測試的硬件配置以下:分佈式
設備:DELL OptiPlex 7060函數
CPU:Inter® Core™ i7-8700 CPU @ 3.20GHz,6核心12線程工具
內存:32GB
硬盤:2TB機械硬盤
操做系統:Ubuntu 16.04 x64
本次的測試環境爲單服務器下的多節點集羣。爲了在單機環境下最大限度地發揮出二者的性能,須要對DolphinDB以及Elasticsearch進行節點參數的設置。設置DolphinDB的數據節點的個數爲4個,單個數據節點最大可用內存設置爲7 GB。設置Elasticsearch的節點個數爲4個,因爲Elasticsearch基於Lucene,故須要分配必定內存用於Lucene中的段被加載入內存中,這對Elasticsearch的性能也會形成很大的影響,本次測試分配8 GB內存給Lucene,並設置Elasticsearch中的單個節點的最大可用內存爲6 GB,且禁止swapping。
爲了更加全面地測試DolphinDB和Elasticsearch的性能,咱們使用了三個不一樣規模的股票數據集。數據表CN_Stock中包含了從2008.01.01到2017.12.31中國滬深股票的每日報價數據。數據表US_Prices中包含了從1990.01.02到2016.12.30美國股票市場的每日報價數據。數據表TAQ中包含了2007年8月份的4天美國股票市場level1的高頻數據,共60.6 GB。測試數據集的概況以下表所示:
測試數據集在DolphinDB和Elasticsearch中各個字段的數據類型以下所示:
(1)CN_Stock表數據類型映射
(2)US_Prices表數據類型映射
(3)TAQ表數據類型映射
DolphinDB提供了靈活的分區機制,包括值分區,範圍分區,列表分區,哈希分區和組合分區,而Elasticsearch僅支持基於哈希的分片機制。
在DolphinDB中,對於表CN_Stock,按時間每半年做爲一個分區,共分紅了20個分區;對於表US_Prices,按時間每一年做爲一個分區,共分紅27個分區;對於表TAQ,採用日期、股票代碼組合分區方式,共100個分區。副本個數設置爲1。
Elasticsearch僅容許定義分片的個數。對於表CN_Stock和表US_Prices,定義分片個數爲4;對於表TAQ,定義分片個數爲100。副本個數設置爲1。
咱們從數據庫查詢性能、I/O性能、磁盤佔用空間、以及內存消耗等方面對DolphinDB和Elasticsearch進行了對比測試。
DolphinDB腳本語言支持SQL語法,同時還在其基礎上進行了必定程度的擴展,功能更增強大。而在Elasticsearch中,須要安裝插件來進行SQL語句查詢,同時也提供了基於JSON數據格式的DSL(Domain Specific Language特定領域語言)語言來進行查詢,本次測試採用DSL語言。
Elasticsearch的主要應用場景爲搜索引擎,它支持模糊查詢,對於普通的query,Elasticsearch返回的查詢hits默認僅爲10條;對於聚合查詢,其返回的buckets的默認大小也爲10。而DolphinDB中每次查詢返回的結果都是所有的結果,不存在模糊查詢的狀況。
在Elasticsearch的聚合查詢中,返回結果中存在字段doc_count_error_upper_bound以及sum_other_doc_count,二者分別表示沒有在此次聚合中返回、可是可能存在的潛在聚合結果以及此次聚合中沒有統計到的文檔數。這也很好的證實了Elasticsearch默認的對於數據查詢操做僅僅只是對數據庫中的部分數據進行模糊查詢,而不是精確的查詢數據庫中的全部數據記錄。爲了將二者放在公平的環境下進行測試,咱們須要關閉Elasticsearch的模糊查詢,處理的方式是採用Elasticsearch中的scroll接口以及定義buckets的大小來對控制Elasticsearch返回所有的查詢結果。
在本次測試中,使用了DolphinDB腳本完成了DolphinDB的查詢性能測試。使用了Python腳本+DSL來完成Elasticsearch的查詢性能測試。
咱們對三張數據表進行了若干種經常使用的SQL查詢。爲了減少偶然因素對結果的影響,本次查詢性能測試對每種查詢操做均進行10次查詢,而後對總時間取平均值,時間以毫秒爲單位。各個測試數據集的測試腳本和結果以下表所示。
(1)CN_Stock表
DolphinDB中的查詢腳本:
查詢性能測試結果(數據量:5,332,932):
(2)US_Prices表
DolphinDB中的查詢腳本:
查詢性能測試結果(數據量:50,591,907):
(3)TAQ表
DolphinDB中的查詢腳本:
查詢性能測試結果(數據量:1,366,036,384):
對於本次的查詢性能測試,咱們能夠得出如下結論:
(1)在同一張表的全部測試中,DolphinDB的性能都領先Elasticsearch多倍。特別的,對於簡單的過濾查詢,DolphinDB的性能是Elasticsearch的性能的1-2個數量級(見CN_Stock表測試結果的1-四、US_Prices表測試結果的1-4)。
(2)在有關聚合查詢的測試結果中,DolphinDB的性能也都優於Elasticsearch,平均是8~9倍。特別的,按時間分組的聚合查詢中,DolphinDB的性能是Elasticsearch的13-15倍(見CN_Stock表測試結果的5-10,US_Prices表測試結果的5-10)。
(3)在不一樣的數據規模的相同類型的查詢測試中,咱們能夠看出隨着數據規模的上升,Elasticsearch的精確查詢的耗時增加幅度遠大於DolphinDB,DolphinDB在不一樣數據規模下的穩定性優於Elasticsearch。
Elasticsearch提供了_bulk API批量寫入數據的功能。在建立一條新的文檔時,首先須要描述文檔中可能包含的每一個字段的屬性,數據類型(好比 keyword, text, integer 或 date),以及這些字段是否須要被 Lucene 索引或儲存。而後Elasticsearch爲文檔的這些屬性構建相應的映射,並建立倒排索引後造成Lucene中的段。最後經過refresh以及flush機制將倒排索引存儲於磁盤上。其中將內存中的倒排索引flush到磁盤上這一過程是決定Elasticsearch性能的關鍵。值得注意的是,雖然Elasticsearch提供了_bulk API 來批量導入數據,同時也能夠設置index.refresh_interval = -1 以及index. number_of_replicas = 0 來進行導入優化。可是在大批量數據導入的狀況下,當內存中的緩衝區滿的時候,仍然會觸發refresh,而且進行flush將數據存儲到磁盤上,所以優化的效果並非很明顯,Elasticsearch數據導入緩慢是一個很顯著的缺點。
DolphinDB中建立一張分佈式數據表並寫入數據的時候,首先根據分佈式數據表的分區類型決定不一樣分區的數據寫入的數據節點位置。在分區內部,數據是採用列式存儲的方式進行組織,經過節點之間的配合來進行數據的導入與查詢等操做,數據導入很快,性能極高。
下表是二者的數據導入的I/O性能測試結果,從中能夠明顯的觀察到ES/DDB的載入耗時比隨着數據量的上升而增大,特別的,當數據量爲60.6GB時,Elasticsearch導入耗時12個小時以上。數據導入腳本見附錄。
Elasticsearch以其搜索的高效性與時效性著稱。它是基於Lucene而構建起來的分佈式搜索引擎且對source字段的內容進行了壓縮處理,但其內部是爲每一個建立的文檔構建倒排索引,並將倒排索引存儲在磁盤中的。由於在磁盤上須要對每一個文檔添加額外的索引信息,從而須要更大的存儲空間來存放。而DolphinDB並不須要其他的索引信息,真正作到了對原數據的壓縮存儲。測試結果以下表所示。
5.4 內存佔用
爲了更加全面的觀測到DolphinDB與Elasticsearch在執行過程當中的內存佔用狀況,使用Linux命令htop來監視DolphinDB和Elasticsearch的內存佔用狀況(內存總大小爲32GB),結果以下:
(1)Elasticsearch經過須要安裝插件來支持SQL語言,同時其內置的DSL語言是JSON格式,語法比較複雜。而DolphinDB內置了完整的腳本語言,不只支持SQL語言,並且支持命令式、向量化、函數化、元編程、RPC等多種編程範式,能夠輕鬆實現更多的功能。
(2)Elasticsearch的主要用途是提供了一個分佈式多用戶能力的全文搜索引擎,支持模糊查詢,文檔(行)不須要固定結構,不一樣文檔能夠具備不一樣字段集合。而DolphinDB只支持結構化數據。
(3)DolphinDB提供600餘種內置函數,可知足金融領域的歷史數據建模與實時流數據處理,及物聯網領域中的實時監控與數據實時分析處理等不一樣的場景需求。提供時序數據處理須要的領先、滯後、累積窗口、滑動窗口等多種指標的函數,且在性能上進行了優化,性能極優。 於是與Elasticsearch相比,DolphinDB擁有更多的適用場景。
(4)Elasticsearch用於時序數據庫中時並不支持錶鏈接,而DolphinDB不只支持錶鏈接,還對asof join及window join等非同時鏈接方式作了優化。
(5)DolphinDB對數據寫入支持分佈式事務,Elasticsearch不支持事務。
Elasticsearch支持結構化數據和非結構化數據,支持模糊查詢,精確查詢,和聚合計算,適合不少應用場景。可是與DolphinDB這樣專業的時序數據庫相比,不管在功能上和性能上,都有很大的差距。尤爲當數據量急劇膨脹,超過物理內存上限時,內存耗用高、磁盤空間佔用高的缺點暴露出來,對歷史數據計算時性能有明顯的降低。
DolphinDB和Elasticsearch的詳細配置信息、DolphinDB和Elasticsearch的測試代碼以及數據導入腳本見附錄。