Doris 與 ClickHouse 的深度對比及選型建議
轉摘:https://blog.csdn.net/zero__007/article/details/121756413
一、背景介紹
Apache Doris是由百度貢獻的開源MPP分析型資料庫產品,亞秒級查詢響應時間,支援實時資料分析;分散式架構簡潔,易於運維,可以支援10PB以上的超大資料集;可以滿足多種資料分析需求,例如固定歷史報表,實時資料分析,互動式資料分析和探索式資料分析等。
ClickHouse是俄羅斯的搜尋公司Yandex開源的MPP架構的分析引擎,號稱比事務資料庫快100-1000倍,團隊有計算機體系結構的大牛,最大的特色是高效能的向量化執行引擎,而且功能豐富、可靠性高。
京東當前都在大範圍使用這兩種分析引擎,總叢集規模超過3000臺伺服器,涵蓋了交易、流量、線下和大屏等各類場景。本文將結合京東團隊的調研成果和幾年的實踐經驗,對Doris和ClickHouse這兩種分析引擎進行深入對比,驗證廣為流傳的說法,供大家在場景選型或核心研發時提供一個參考,另外對於兩者社群規劃提供一定的借鑑。
二、差異和選擇建議
Doris更優的方面
-
使用更簡單,如建表更簡單,SQL標準支援更好, Join效能更好,導數功能更強大
-
運維更簡單,如靈活的擴縮容能力,故障節點自動恢復,社群提供的支援更好
-
分散式更強,支援事務和冪等性導數,物化檢視自動聚合,查詢自動路由,全面元資料管理
ClickHouse更優的方面
-
效能更佳,匯入效能和單表查詢效能更好,同時可靠性更好
-
功能豐富,非常多的表引擎,更多型別和函式支援,更好的聚合函式以及龐大的優化引數選項
-
叢集管理工具更多,更好多租戶和配額管理,靈活的叢集管理,方便的叢集間遷移工具
那麼兩者之間如何選擇呢?
-
業務場景複雜資料規模巨大,希望投入研發力量做定製開發,選ClickHouse
-
希望一站式的分析解決方案,少量投入研發資源,選擇Doris
另外, Doris源自線上廣告系統,偏交易系統資料分析;ClickHouse起源於網站流量分析服務,偏網際網路資料分析,但是這兩類場景這兩個引擎都可以覆蓋。如果說兩者不那麼強的地方,ClickHouse的問題是使用門檻高、運維成本高和分散式能力太弱,需要較多的定製化和較深的技術實力,Doris的問題是效能差一些可靠性差一些,下面就深入分析兩者的差異。
三、架構分析
從部署運維、分散式能力、資料匯入、查詢、儲存和使用成本等方面進行對比,這部分會涉及到核心中的設計原理、方案和實現,瞭解這些原理會有助於理解上文的結論。
1、部署運維
1)部署和日常運維
部署指部署叢集,安裝相關依賴和核心元件,修改配置檔案,讓叢集正常執行起來;運維指日常叢集版本更新,配置檔案更改、擴縮容等相關事項。叢集所需元件如下:
-
左側是Doris的部署架構圖,JDBC指接入協議,DNS是域名和請求分發系統。Managerment Panel是管控面。Frontend指前端模組簡稱FE,包含了SQL解析、查詢計劃、計劃排程、元資料管理等功能,Backend指後端模組簡稱BE負責儲存層、資料讀取和寫入,另外還有一個BrokerLoad導陣列件最好是單獨部署。所以,Doris一般只需要FE和BE兩個元件。
-
右側是ClickHouse的部署架構圖,ClickHouse本身只有一個模組,就是ClickHouse Server,周邊有兩個模組,如ClickHouseProxy主要是轉發請求、配額限制和容災等,ZooKeeper這塊負責分散式DDL和副本間資料同步,ClickHouseCopier負責叢集和資料遷移,ClickHouse一般需要Server、ZooKeeper和CHProxy三個元件。
-
日常運維如更新版本、更改配置檔案兩者都需要依賴Ansible或者SaltStack來進行批量更新。兩者都有部分配置檔案可以熱更新,不用重啟節點,而且有Session相關引數可以設定可以覆蓋配置檔案。Doris有較多的SQL命令協助運維,比如增加節點,Doris中Add Backend即可,ClickHouse中需要更改配置檔案並下發到各個節點上。
2)多租戶管理
ClickHouse的許可權和Quota的粒度更細,可以很方便的支援多租戶使用共享叢集。比如可以設定查詢記憶體、查詢執行緒數量、查詢超時等,以便來限制查詢的大小;同時結合查詢併發和一定時間視窗內的查詢數量,以便來控制查詢數量。多租戶的方案,對發展中的業務非常友好,因為使用共享叢集資源,可以快速動態調整配額,如果是獨佔叢集資源利用率不高、擴容相對麻煩。
3)叢集遷移
Doris通過內建的backup/restore命令將資料和元資料備份到三方物件儲存或者HDFS上,backup可以通過快照的方式完整匯出一致性的資料和元資料,並且可以按照分割槽來實現增量備份,降低備份的成本。在Doris中,有一種變通的遷移叢集的方法,把新機器分批加入到已有的叢集,然後再把舊機器逐步下線,叢集能夠自動均衡,這個過程視叢集資料量可能會持續數天。
ClickHouse有幾個方法實現資料遷移,資料量大通過自帶的Clickhouse-copier工具進行叢集間的資料拷貝,實現資料的跨叢集遷移,需要手工配置很多資訊,我們做了一些完善和改進;資料量小通過SQL命令remote關鍵字實現跨叢集的資料遷移。而官方對實現其他儲存介質的備份和恢復的推薦是採用檔案系統的snapshot實現,或者可以通過三方工具(https://github.com/AlexAkulov/clickhouse-backup)來實現。
4)擴容/縮容
Doris支援叢集的線上動態擴縮容,通過內建的SQL命令 alter system add/decomission backends 即可進行節點的擴縮容,資料均衡的粒度是tablet,每個tablet大概是數百兆,擴容後表的tablet會自動拷貝到新的BE節點,如果線上擴容,應該小批量去增加BE,避免過於劇烈導致叢集不穩定。
ClickHouse的擴容縮容複雜且繁瑣,目前做不到自動線上操作,需要自研工具支援。擴容時需要部署新的節點,新增新分片和副本到配置檔案中,並在新節點上建立元資料,如果是擴副本資料會自動均衡,如果是擴分片,需要手工去做均衡,或自研相關工具,讓均衡自動進行。
2、分散式能力
1)分散式協議和高可用
Doris在FrontEnd中包含元資料的管理能力,內建了BerkeleyDB JE HA元件,包含選舉策略和副本資料同步,提供了FE的高可用方案。FE中管理的元資料也非常豐富,包含節點、叢集、庫、表和使用者資訊,以及分割槽、Tablet等資料資訊,也包含事務、後臺任務、DDL操作和導數相關任務等資訊。
Doris的 FrontEnd可以部署3個Follwer + n個Oberserver(n>=0)的方式來實現元資料和訪問連線的高可用,Follower參與選主,在有Follwer宕機時,會自動的選舉出新節點保證讀寫高可用,Observer是隻讀的擴充套件節點,可以水平擴充套件實現讀的擴充套件。BE通過多副本來實現高可用,一般來說也採取預設的三副本,寫入的時候採用Quroum協議保證資料一致性。
Doris的元資料和資料多副本儲存的,能自動複製具有自動災備的能力,服務掛了可以自動重啟,壞一塊盤資料自動均衡,小範圍的節點宕機不會影響叢集對外的服務,但宕機後資料均衡過程會消耗叢集資源,引發短時間的負載過高。架構如下圖:
ClickHouse目前版本是基於ZooKeeper來儲存元資料,包含分散式的DDL、表和資料Part資訊,從元資料豐富程度來說稍弱,因為儲存了大量細粒度的檔案資訊,導致ZooKeeper經常出現效能瓶頸,社群也有基於Raft協議的改進計劃。ClickHouse依賴Zookeeper來實現資料的高可用,Zookeeper帶來額外的運維複雜性的同時也有效能問題。
ClickHouse沒有集中的元資料管理,每個節點分別管理,高可用一般依賴業務方來實現。ClickHouse中某個副本節點宕機,對查詢和分散式表的匯入沒有影響,本地表匯入要在導數程式中做災備方案比如選擇健康的副本,對DDL操作是有影響的,需要及時處理。
在分散式能力這塊,Doris在核心側已經實現,使用的代價更低;而ClickHouse需要依賴於外部配套的措施去保障,使用成本較高。
2)事務支援
ACID指事務的原子性、一致性、隔離性和持久化,OLAP的事務體現在幾個方面,一是導數,需要保證導數的原子性,同時也要保證明細資料和物化檢視的資料一致性;二是元資料的變更,需要保證所有節點的元資料統一變更的強一致性;三是在節點間做資料均衡時,需要保證資料的一致性。
Doris提供了匯入的事務支援,可以保證導數的冪等性,比如資料匯入的原子性,如果有其他錯誤會自動回滾,同時相同標籤的資料不會重複匯入。基於匯入事務的功能,Doris還實現了Flink-connector這樣的外部元件可以實現資料匯入不丟不重。兩者均不支援通用TP場景中的BEGIN/END/COMMIT語義的事務,很明顯有事務支援的Doris比無事務支援的ClickHouse要節省很多開發成本,因為在ClickHouse中,這一切都需要外部導數程式來保證。
ClickHouse不支援事務,需要在外部去做各種校驗和檢查,在導數這塊能保證100萬以內的原子性,但是不保證一致性,比如要更新某些欄位或者更新物化檢視,這個操作是後臺非同步的,需要顯示指定關鍵字FINAL來查詢最終資料,而且其他操作沒有事務支援。
DDL操作兩者都是非同步的,但是Doris能保證各個節點元資料的一致性,但ClickHouse中保證不了,會出現區域性節點元資料和其他節點不一致的情況。
3、資料匯入
Doris中有RoutineLoad、BrokerLoad和StreamLoad等豐富內建的導數方式,這些功能非常好用,雖然無法處理複雜的ETL邏輯,但是支援簡單過濾和轉換函式,也能容忍少量的資料異常,同時支援ACID和導數冪等性。
-
Routineload支援消費Kafka的實時資料,按每批條數、匯入間隔和併發數等設定導數引數,用於實時資料的匯入;
-
Brokerload支援從HDFS上匯入資料檔案,用於離線導數,速度不是很快;
-
Streamload是導數的底層介面,更加高階的功能可以外部程式處理後通過Steamload來匯入。
ClickHouse中並沒有後臺導數任務這一概念,它更多的是通過各種引擎去連線到各種儲存系統中,。導數在1048576條以內是原子的,要麼都生效,要麼都失敗,但是沒有類似Doris中事務ID的概念,在Doris中相同的事務ID插入資料是無效的,這也避免了重複的導數,在CH中如果導數重複,只能刪除重新匯入。CH中比較有特色的是既可以寫分散式表又可以寫本地表。
匯入效能因為ClickHouse可以匯入本地表,而且沒有事務的限制,所以匯入效能差不多是節點磁碟寫入的效能,而Doris的導數受限於只能分散式表的匯入,匯入效能差一些。
如果資料量少可以使用OLAP中的導數,資料量大邏輯複雜,一般使用Spark/Flink等外部計算引擎來做ETL和導數功能,主要是導數消耗叢集資源。
4、儲存架構
1)MVCC模型
Doris的儲存部分參考GoogleMesa,採用的MVCC模式,MVCC指Multi-version concurrency control多版本控制,通過版本可以實現事務的兩段提交,可以通過版本進行小檔案合併,也可以在明細表和物化檢視之間實現強一致性。
ClickHouse中也是類似,有兩個操作,一種是Merge合併小的Part檔案到一個大的Part,提升查詢效能避免掃描多個小檔案,合併過程類似上圖。另外一種是Mutation就是在已有的Part中實現資料的變更或元資料的變更,如下圖的SQL:
ALTER TABLE [db.]table DELETE WHERE filter_expr;
ALTER TABLE [db.]table UPDATE column1 = expr1 [, ...] WHERE filter_expr;
- 1
- 2
2)儲存結構
兩者都是列存,列存的好處就是:
-
分析場景中需要讀大量行但是少數幾個列,只需要讀取參與計算的列即可,極大的減低了IO,加速了查詢
-
同一列中的資料屬於同一型別,壓縮效果顯著,節省儲存空間,降低了儲存成本
-
高壓縮比,意味著同等大小的記憶體能夠存放更多資料,系統Cache效果更好
Doris的資料劃分方式是Table、Partition、Bucket/Tablet、Segment幾個部分,其中Partition代表資料的縱向劃分分割槽一般是日期列,Bucket/Tablet一般指資料的橫向切割分桶規則一般為某主鍵, Segment是具體的儲存檔案。Segment中包含資料和索引,資料部分包含多個列的資料按列存放,有三種索引:物理索引、稀疏索引和ZoneMap索引。
ClickHouse中分為DistributeTable、LocalTable、Partition、Shard、Part、Column幾個部分,差不多能和Doris對應起來,區別就是CH中每個Column都對應一組資料檔案和索引檔案,好處就是命中系統Cache效能更高,不好的地方就是IO較高且檔案數量較多,另外CH有Count索引,所以Count時命中索引會比較快。
通過分割槽分桶的方式可以讓使用者自定義資料在叢集中的資料分佈方式,降低資料查詢的掃描量,方便叢集的管理。分割槽作為資料管理的手段, Doris支援按照range分割槽,ClickHouse可以表示式來自定義。Doris可以通過動態分割槽的配置來按照時間自動建立新的分割槽,也可以做冷熱資料的分級儲存。ClickHouse通過distrubute引擎來進行多節點的資料分佈,但是因為缺少bucket這一層,會導致叢集的遷移擴容比較麻煩, Doris通過分桶的配置可以進一步對資料劃分,方便資料的均衡和遷移。
3)表引擎/模型
兩者都有典型的表型別(引擎型別)的支援
-
Doris:可重複的Duplicated Key就是明細表,按維度聚合的Aggregate Key,唯一主鍵Unique Key,UniqueKey這個可以視為AggregateKey的特例,另外在這三種基礎上可以建立Rollup(上卷),可以理解為物化檢視。
-
ClickHouse : 主要是MergeTree表引擎家族,主要是ReplicatedMergeTree帶副本的、ReplacingMergeTree可以更新資料的和AggregatingMergeTree可以聚合資料,另外還有記憶體字典表可以載入資料字典、記憶體表可以加速查詢或獲得更好寫入效能。CH比較特殊地方是分散式表和每個節點的本地表都要單獨建立,物化檢視無法自動路由。
另外,Doris新開發的Primary Key模型,對實時更新場景下的讀效能進行了深度優化,在支援update語義的同時,避免了Unique key的sort merge開銷。在實時update的壓力下,查詢效能跟是Unique key的3-15倍。類似的,相比ClickHouse的ReplicatedMergeTree,也避免了select final/optimize final的問題。
4)資料型別
ClickHouse中存在較多的複雜型別的支援如
Array/Nested/Map/Tuple/Enum等,這些型別能夠滿足一些特性場景,還是比較好用的。
5、資料查詢
1)查詢架構
分散式查詢指查詢分佈在多臺伺服器上的資料,就如同使用一張表一樣,分散式Join比較繁瑣,Doris的分散式Join有Local join,Broadcast join,Shuffle join,Hash join等方式。ClickHouse只有Local和Broadcast兩種Join,這種架構比較簡單,也限制了Join SQL的自由度,變通的方式是通過子查詢和查詢巢狀來實現多級的Join。
Doris和ClickHouse都支援向量化執行,向量化簡單理解就是一批資料一批資料去執行,可以多行併發執行,同時也提升了CPU Cache命中率。在資料庫領域,一直是Codegen和Vectorized並存,如下圖是TPC-H的五個測試SQL,縱軸是查詢時間,Type是編譯執行,TW是向量化執行,可以看出兩者在不同場景下,效能表現不一樣。
2)併發能力
OLAP因為MPP架構,每一個SQL所有節點都會參與計算,以此來加速海量計算,因此一個叢集的併發能力和單臺沒有太大的區別,所以,OLAP和資料庫類似,並不是能夠承擔極高併發的系統。但是也並非毫無辦法,比如通過增加副本數來達到承載較大併發的能力。比如4個分片1個副本,能承擔100QPS,那麼如果要承擔500的QPS,則只需要把副本數擴充套件到5個副本即可。另外一點很重要的是查詢能否利用到Cache,包括ResultCache,Page Cache和CPU Cache,這樣併發還能提升一個很大的臺階。
Doris有兩點比較優勢,一是副本數的設定是在表級別的,只需要把併發大的表設定副本數多一些即可,當然副本數不能超過叢集的節點數,而ClickHouse的副本數設定是叢集級別的。
3)SQL支援
Doris與MySQL語法相容,支援SQL99規範以及部分SQL2003新標準(比如視窗函式,Grouping sets)。
ClickHouse部分支援SQL-2011 標準(https://clickhouse.tech/docs/en/sql-reference/ansi/),但是由於Planner的一些限制,ClickHouse的多表關聯需要對SQL做大量改寫工作,比如需要手動下推條件到子查詢中,所以複雜查詢使用不太方便。
ClickHouse支援支援ODBC、JDBC、HTTP介面,Doris支援JDBC和ODBC介面。
4)聯邦查詢
5)函式支援
6、使用成本
1)使用成本
Doris使用成本低,是一個強一致性元資料的系統,導數功能較為完備,查詢SQL的標準相容好無需額外的工作,彈性伸縮能力要好,而ClickHouse則需要做較多工作:
-
ZooKeeper存在效能瓶頸導致叢集規模不能特別大
-
基本無法做到彈性伸縮,純手工擴縮容工作量巨大且容易出錯
-
故障節點的容忍度較低,出現一個節點故障會引發某些操作失敗
-
導數需要外部保證資料不重不丟,導數失敗需要刪了重導
-
元資料需要自己保證各個節點一致性,偶發性的不一致情況較多
-
分散式表和本地表有兩套表結構,較多使用者難以理解
-
多表Join SQL需要改寫和優化,方言較多幾乎是不相容其他引擎的SQL
所以,在大規模實施ClickHouse時,需要研發一個比較好用的運維繫統的支援,處理大部分的日常運維工作。
2)程式碼框架
Doris整體架構分為FrontEnd和BackEnd,FE由Java編寫,BE是C/C++,通訊部分是BRPC。FE中包含了元資料、SQL Parser、Optimizer、Planner和Coodinator幾個部分,BE中包含寫入、儲存、索引和查詢執行部分。Doris的程式碼風格整體質量是比較高的,風格統一,有較為完善的單測用例,如果要在Doris上做二次開發,則需要熟悉Java或C++。
ClickHouse包含ClickHouse Client/Copier/Server這幾個比較主要的模組,其中Client是日常使用的命令列客戶端,Copier是資料遷移工具,Server是叢集核心服務。Server部分包含Parser、Interpreter、Storage、Database、Function等模組。程式碼整體上是C++11以上的風格,大量使用Poco庫,大量使用較新的語言特性。
因此ClickHouse對二次開發更加友好,技術棧單一,且測試框架完善,模組間互相依賴關係相對較小。
四、效能測試
TPC-DS測試是大資料領域比較常用的一個測試,24張表、99個SQL,可以生成不同容量的資料,京東內部常用來做不同引擎的對比測試。
-
這兩個引擎都無法全部支援99個SQL,不支援的部分我們根據各個引擎不同特點,進行手工SQL改寫讓其能正確執行,Doris改動量較小,ClickHouse的多表關聯幾乎都要改寫;
-
為了簡化測試過程,我們挑選了9個關聯查詢的SQL,然後自己構造了9個單表查詢的SQL,共18個SQL來測試效能;
舉個例子
如下是一個典型的多表關聯例子,在Doris中不需要做改動,但是在ClickHouse中,需要改為多個Global Inner Join來執行, ClickHouse的多表關聯查詢一般都需要改寫。
--Doris/DorisDB SQL 1
select i_item_id, avg(cs_quantity) agg1, avg(cs_list_price) agg2, avg(cs_coupon_amt) agg3, avg(cs_sales_price) agg4
from catalog_sales, customer_demographics, date_dim, item, promotion
where cs_sold_date_sk = d_date_sk and
cs_item_sk = i_item_sk and
cs_bill_cdemo_sk = cd_demo_sk and
cs_promo_sk = p_promo_sk and
cd_gender = 'M' and
cd_marital_status = 'D' and
cd_education_status = 'Advanced Degree' and
(p_channel_email = 'N' or p_channel_event = 'N') and d_year = 1998
group by i_item_id order by i_item_id limit 10;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
--ClickHouse SQL 1
select i_item_id, avg(cs_quantity) agg1, avg(cs_list_price) agg2, avg(cs_coupon_amt) agg3, avg(cs_sales_price) agg4 from catalog_sales_dist
global inner join (select cd_demo_sk from customer_demographics_dist where cd_gender = 'M' and cd_marital_status = 'D' and cd_education_status = 'Advanced Degree' )
on cs_bill_cdemo_sk = cd_demo_sk
global inner join (select d_date_sk from date_dim_dist where d_year = 1998 ) on cs_sold_date_sk = d_date_sk
global inner join ( select i_item_sk, i_item_id from item_dist ) on cs_item_sk = i_item_sk
global inner join ( select p_promo_sk from promotion_dist where p_channel_email = 'N' or p_channel_event = 'N') on cs_promo_sk = p_promo_sk
group by i_item_id order by i_item_id limit 10;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
測試環境
-
硬體:3臺32核/128G記憶體/HDD磁碟的伺服器
-
軟體:Doris 0.13.1、ClickHouse 21.3.13.1
-
配置:3個分片1副本,都是預設配置
測試總結
-
單表效能ClickHouse更好,無論是查詢延時還是併發能力
-
多表效能Doris優勢更明顯,特別是複雜Join和大表Join大表的場景,另外ClickHouse需要改寫SQL有一些工作量
單表延時和併發
單表的SQL都比較簡單,大部分是全表分組group by之後avg/sum/count/count distinct的各種聚合,單表查詢時間如下,可以看出整體上ClickHouse要明顯好一些,同時,為了壓測方便我們找了2個延時低的SQL Single4和Single5測試了一下不同併發下的QPS,發現也是ClickHouse更優一些。
ClickHouse的單表效能好,得益於向量化執行引擎,在資料密集情況下,利用記憶體的PageCache和CPU的L2 Cache可以大大加速查詢過程。
Join的延時和併發
從多表測試來看,Doris在Join6、Join7、Join8、Join9要好一些,Join3兩者差不多,其他情況ClickHouse好一些。同樣,我們挑選了2個延時低的SQL Join8和Join9做了一下併發測試,併發的測試結果和延時表現比較匹配,延時低的SQL測試併發時QPS同樣高。
Doris多表關聯有四種Join方式,BroadCast Join,Shuffle Join/Bucket Shuffle Join和Colocation Join,ClickHouse只有Global Join(就是BroadCast Join)和Local Join(對應Colocation Join),因此在大表Join大表時,要把右表廣播到所有節點,效能可想而知。
Doris的執行計劃對SQL進行了較多的優化,因此多表關聯中的大部分情況,能找到最優的執行方式,因此多表關聯效能較好一些,但是也並不是所有的關聯SQL都要好。
ClickHouse小表不同資料量下延時
通過上面的測試,大家肯定有疑問,不是說ClickHouse的Join效能不行麼,為什麼表現並不差呢?因此,貼一個去年做的一組ClickHouse大小表的測試供大家參考,就是用一個大表關聯查詢不同資料規模的小表,看Join效能情況怎麼樣。橫軸是指小表的不同資料量,縱軸是執行時間。可以看出,因為Join機制不一樣,ClickHouse的延時隨小表資料量加大梯度更大,ClickHouse小表資料量1000萬以內尚可,超過1000萬效能比就比較差了。
五、對比表格
上面的對比,是從大的幾個方面來進行的,下面是比較詳細的對比,綠色指我們覺得比較佔優的部分。
六、未來規劃展望
Apache Doris從測試和使用的過程中看,效能非常不錯,能滿足京東在OLAP場景上的需求,後續會逐步上線到更多業務中使用,同時我們也會積極參與到Apache Doris開源社群建設中來,憑藉京東在OLAP領域深厚的技術積累和實踐經驗,一起把Apache Doris這個專案發展成全球領先的分析型資料庫專案。
ClickHouse在京東也有大規模的使用,在一些極端場景下表現非常出色,零事故支撐了數次大促,京東OLAP團隊也在高可用方面有很多心得,自研了基於Raft的分散式元資料管理服務、線上擴縮容提升彈效能力和強大的管控面降低運維複雜度,未來會在雲原生的OLAP方面繼續努力,把ClickHouse打造為有京東特色的OLAP引擎。
>>>>