開源IndexR:如何對上千億的數據進行秒級探索式分析
在當前信息大爆炸的時代,“大數據”已成為互聯網行業人人談論的熱詞和話題,比如近幾年快速發展的基于大數據進行精準用戶定向的程序化廣告,以及去年馬云提出的利用大數據重塑商品的生產 - 流量 - 銷售流程的“新零售”模式等。大數據已經滲透到眾多的行業,為許多企業帶來了變革性影響。那么,何為“大數據”呢?大數據(Big Data),可以簡單的理解為無法在一定時間范圍內用常規手段進行處理的海量數據集合。所有企業的業務分析都是基于數據的,每家企業對數據的收集、整合及處理能力在一定程度上決定了企業的業務發展水平。因此,提升數據分析性能也是當前許多企業共同面臨的重大挑戰。
行業現狀
目前,行業中的大數據分析架構一般使用基于 Hadoop 體系的分布式計算引擎 + 分布式存儲系統架構(如下圖)。
Hadoop 體系的架構特點是上層解決計算問題,下層解決存儲問題。它可以讓開發者在不了解分布式底層細節的情況下,進行分布式程序的開發。但是,這種架構同時也存在一些問題:
1.整合工作量大
分布式存儲目前的標準比較統一,一般使用 HDFS。HDFS 能有效解決海量數據的存儲問題,并且有多種方便的工具鏈。但是,分布式計算引擎為了適應不同場景,會有不同特性的數據倉庫工具,僅 Apache 就有 Hive、Spark、Drill、Impala、Presto 等產品,除此之外,還有獨立于 Hadoop 體系之外其它產品項目(如 ClickHouse、Kudu、Druid 等)。由于每個產品都有各自的特性,當需要利用多個產品來解決不同問題時,就需要額外的整合工作,降低了工作效率。
2.數據交換速度慢
由于計算層必然是駐于內存的,從存儲層到計算層的速度限制就成了系統的普遍瓶頸。有些系統為了加快速度全部使用內存存儲(比如內存數據庫、基于 Spark 的 SnappyData),這種方式在數據量較大時會造成巨大的成本壓力,因此目前還遠未成為主流。
3.數據實時分析性差
由于文件系統的天然限制,數據一般是批量導入系統的。導入的時間會依據數據量的大小而有所不同,在數據量較大時常會出現入庫滯后現象,從而影響了數據分析的及時性。
因此,我們需要一個可以充分解決以上問題的大數據儲存格式,也就是筆者接下來要為大家介紹的 IndexR 開源大數據存儲數據庫。
IndexR 簡介
IndexR 是一個開源的大數據存儲格式(下載地址 https://github.com/shunfei/indexr),于 2017 年 1 月初正式開源,目前已經更新至 0.5.0 版本。IndexR 旨在通過添加索引、優化編碼方式、提高 IO 效率等各種優化方式來提高計算層和存儲層的數據交換效率,從而提升整體性能。同時,IndexR 可以接收實時數據,并對上層提供統一的數據接口。數據一旦到達 IndexR 系統即可立刻進行數據分析。
架構剖析
基于 IndexR 系統的典型架構示例如下:
1.IndexR 為上層計算引擎提供數據,相當于對 IO 層做了整體的性能加速,提升了系統的分析能力。
2.IndexR 為下層數據存儲解決了在線分析和數據調用的問題,同時還能解決實時數據和歷史數據的分割問題。
- IndexR 能實時拉取 Kafka 的數據流,并打包上傳到 HDFS。整個數據層對于計算層是透明的。IndexR 通過結合實時數據和歷史數據,保證了數據分析的實時性。
- 數據存放于 HDFS,不同的分析工具可同時分析同一份數據。
- 利用 Hadoop、Drill、Spark 等的分布式、高可用、可擴展特點,解決海量數據場景的分析問題。
使用場景
IndexR 從開源至今,歷經不同團隊從調研、測試到***部署生產環境的實踐,已獲得了國內外數十家團隊的認可(如尼爾森、佰安信息等),包括廣告、電商、AI 等領域的大型互聯網公司和創業團隊以及政府、咨詢、物流等擁有超大數據集且對數據質量有極高要求的行業。其中:尼爾森(Nielsen-CCData)使用 IndexR 產品服務全面支撐了其六大產品線的核心業務,應對海量數據的在線監測、治理、分析以及復雜多變的智能化數據產品輸出,專注于全媒體與受眾研究業務。佰安信息則使用 IndexR 產品服務進行公共信息的明細查詢與統計分析,單表數據量近 2 千億,每日入庫近 4 億條數據。
下面列舉幾種常見的使用場景:
- 替換 Parquet 等存儲格式:利用 IndexR 的性能和索引優勢,加速查詢系統。
- 替換 Druid 等分布式系統:利用 IndexR 實現實時入庫,進行多維數據分析。
- 替換 MySQL、Oracle 等業務數據庫,或 ES、Solr 等搜索引擎:把統計分析工作移交到 IndexR 系統,通過模塊分離,提高服務能力。
- 結合其他開源工具(如 Drill,搭建 OLAP 查詢系統):IndexR 基于 Hadoop 生態的特點及支持實時入庫、高效查詢的優勢,能夠滿足當前或未來對于 OLAP 系統的實時分析海量數據、線性擴展、高可用、多功能、業務靈活等多種需求。數據分析不再被純預計算的局限性所困擾,且在線分析和離線分析可以使用同一份數據,提高了數據利用率并降低了成本。
- 作為數據倉庫的存儲格式:利用 IndexR 存放海量歷史數據,同時支持海量數據的實時入庫。數據使用方式包括明細查詢、在原始數據上做分析查詢和定期的預處理腳本。
IndexR 特性
IndexR 具有六大特性:自帶索引、靈活性強、實時性高、速度快、省資源、預聚合。
1. 自帶索引:存儲格式自帶索引。
IndexR 包含三層索引,即粗糙集索引(Rough Set Index)、內索引(Inner Index)和可選的外索引(Outer Index)。
目前的 On Hadoop 存儲格式如 ORC、Parquet 等都沒有真正的索引,只靠分區和利用一些簡單的統計特征如***最小值等大概滿足離線分析的需求。在服務在線業務時 On Hadoop 就顯得非常力不從心,需要從磁盤中讀取大量無用數據。事實上并不是每次查詢都需要獲取全部數據,特別是 Ad-hoc 類型的查詢。而 IndexR 通過多層索引的設計,不僅極大地提高了 IO 效率,只讀取部分有效數據,而且把索引的額外開銷降到了***。
一般傳統數據庫系統的索引設計是通過索引直接***具體的數據行,但這種方式只適用于 OLTP 場景,即每次查詢只獲取少量數據,在 OLAP 場景下并不適合。OLAP 場景下每次查詢可能要涉及上萬甚至上億行數據,這樣的索引設計開銷極大(內存、IO、CPU),并會帶來磁盤隨機讀的問題,很多時候還不如直接對原始數據進行掃描更加快速。
IndexR 的索引設計是分層的。打個比喻,如果要定位全國具體的某個街道,傳統的方式是把“省市 - 街道”組成一個索引,而 IndexR 是通過把“街道”映射在相應的“省市”的集合(Pack)里,然后再在具體的集合了里做細致的索引。
- Rough Set Index - 粗糙集索引的工作方式類似于熟知的 Bloom Filter,它的特點是成本極低,速度超快,幾乎不會對查詢有性能損耗。IndexR 數據格式通過粗糙集索引快速定位區域塊,所以并不依賴分區。
- Outer Index - 外索引目前使用倒排索引和 Bitmap,它的優點是支持豐富的過濾條件,并且非常適合做交、并運算。IndexR 對倒排索引的使用方式做了優化,避免了在 Scan 場景下大量隨機讀或者巨大內存使用的問題,并且把 Bitmap 的 merge 操作做了加速處理,不會出現范圍條件(大于、小于)下的大量 merge 問題。
- Inner Index - 內索引由具體的 Pack 內部編碼特性決定,支持在壓縮狀態下對數據進行過濾。具體查詢時 IndexR 先進行粗糙集索引過濾,再對剩下的數據集進行倒排索引過濾,然后把***的 Pack 直接加載入內存,對其進行高效的細致查詢。這種方式解決了分布式架構、海量數據場景下索引困難的問題,避免了隨機讀問題,不管是在需要大范圍掃描還是少量數據查詢都更加高效。
2. 靈活性強:雙存儲模式,適應不同場景。
- vlt 模式 - 默認模式,適用于絕大部分場景。特點是速度極快,遍歷速度比 Parquet 快 2~4 倍,支持倒排索引,且隨機查詢性能優越。默認情況下文件大小是 Parquet 的 75%。
- basic 模式 - 壓縮率極高,可達 10:1,一般文件大小是 Parquet 的 1/3。并且仍然保持非常高的讀取性能,優于其他開源格式。適用于存放超大量歷史數據,并支持隨時快速訪問。
3. 實時性高:支持流式導入,實時分析。
目前的 Hadoop 生態對于實時的數據分析還是比較困難。Storm、Spark Streaming 等系統屬于對數據進行預計算,在業務頻繁改動或需要對原始數據進行啟發式分析(Ad-hoc)的情況下沒法滿足需求。而 Druid、Kudu 等系統雖然支持實時寫入,但其體系自成,在實際運用中常會出現部署、整合甚至性能方面的問題。
IndexR 支持實時數據寫入,比如從 Kafka 導入,并且數據到達系統之后可以立刻被分析。它與 Hadoop 生態的無縫整合也使得它在業務設計上非常靈活。目前 IndexR 單表單節點入庫速度每秒超過 3w 條數據,入庫速度會隨著節點數量呈線性增加,每個表使用單獨線程,表間互不影響。此外,對于 OLAP 型的多維分析場景,IndexR 還支持實時、離線預聚合處理,將指標基于維度進行預先組織,大大減少了數據量,數據分析更加快速。
4. 速度快:媲美內存數據庫。
IndexR 使用深度優化的編碼方式,大大加快了數據解析,甚至可以媲美一些內存數據庫。它的數據組織形式根據向量化執行的特點定制,把全部數據存放于堆外內存,并且優化到各個 byte 的組織方式,把 JVM 的 GC 和虛函數開銷降到***。
IndexR 是基于 Hadoop 的數據格式,意味著文件存放于 HDFS,這樣可以非常方便地利用 HDFS 本身的高可用特性保證數據安全,并且可以方便的使用 Hadoop 生態上的所有分析工具。IndexR 對基于 HDFS 的文件讀取做了大量的優化,把計算盡量分發到離數據最近的本地節點,HDFS 層的開銷基本被剔除,與直接讀取本地數據無異。
以下是使用 TPC-H 數據集,IndexR 與 Parquet 格式在相同的 Drill 集群上做的一個性能對比。
***表 lineitem 數據總量 6 億,5 個節點,節點配置 [Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz] x 2, RAM 64G(實際使用約 12G), HDD STATA with 7200RPM。
IndexR 與 Parquet 的 Hive 表 schema 都沒有設置 TBLPROPERTIES,使用默認參數。
- 單項性能對比
柱狀圖:
- 使用 TPC-H 標準測試 SQL,SQL 內容可以在 http://www.tpc.org/tpch/ 上獲取(貼出來太長了),覆蓋了包 Join、子查詢等常見統計分析查詢 SQL,where 條件***的數據量一般超過***表的 50%。其中 Q2,Q15 等 SQL 由于 Drill 不支持沒有顯示。
柱狀圖:
5. 省資源:減少內存使用量
為了避免 Java 中對象和抽象的開銷,IndexR 的代碼大量使用了 Code C In Java 的編程風格(調侃),通過內存結構而非接口進行解耦。緊湊的內存結構減少了尋址開銷,且非常利于優化 JVM 的運行。IndexR 在保證了高性能、有效索引的基礎上極大地節省了內存,與使用 Parquet 格式查詢時的內存使用量差不多,不會出現像 CarbonData 需要配置超大內存的情況。但是為什么不直接使用 C 或者 C++ 呢?因為目前 Hadoop 生態最適合的開發語言還是基于 JVM,JVM 語言可與其他系統無縫集成,在工具鏈支持方面也是最全面的。
6. 易整合:深度整合 Hadoop 生態。
IndexR 通過與 Hadoop 生態的深度整合,適合用來搭建海量數據場景下的數據倉庫。
IndexR 與行業通用方案對比:
- Parquet,ORC - 他們與 IndexR 一樣都屬于存儲格式,功能上比較類似。目前 IndexR 還不支持較復雜的數據格式,但額外支持索引、實時導入、預聚合等特性。
- CarbonData - CarbonData 也是用于大數據分析場景的數據格式,并且支持索引,官方文檔稱適用于大量數據掃描和少量數據查詢的場景,與 IndexR 在存儲格式上的定位非常相近。同樣 IndexR 還額外支持實時導入、預聚合等特性。筆者嘗試使用 CarbonData 與 IndexR 在相同的 Hadoop 集群上做性能對比,發現 CarbonData 的表現不穩定,特別是 Q9 和 Q10,以下是測試結果,歡迎同行討論。
使用以上測試相同集群,CarbonData 1.1.0, Hadoop 2.5.2, Spark 2.1.0. Spark 啟動參數:bin/spark-submit --class org.apache.carbondata.spark.thriftserver.CarbonThriftServer --num-executors 5 --executor-cores 10 --executor-memory 31G carbonlib/carbondata_2.11-1.1.0-shade-hadoop2.2.0.jar hdfs://rttest/user/hive/warehouse/carbon.storeCarbonData 表 schema 沒有設置 TBLPROPERTIES,使用默認參數。
- Druid - Druid 屬于時間序列數據庫,支持流式導入、實時預聚合,適用于 OLAP 場景。從架構上,IndexR 基于 Hadoop,上層使用第三方查詢引擎,而 Druid 只是把文件備份到 Hadoop,數據讀取并不經過 Hadoop。IndexR 系統支持完整的 SQL,而 Druid 使用自定義 JSON 查詢語句,不支持 SQL(目前有實驗 feature,但是支持非常有限),無法做 JOIN、UNION 等操作。此外,IndexR 還額外支持表結構更新,且過期數據不會丟棄,在運維方面也更加簡單。
- Kudu、ClickHouse - IndexR 和他們都可以用來做 OLAP 分析。Kudu 支持 OLTP 的大部分操作,包括數據插入、更新、刪除等;IndexR 和 ClickHouse 數據只能使用 append 的模式,并且不支持在線更新,目前只能使用分區管理。Kudu 和 ClickHouse 都獨立于 Hadoop 生態之外。