做數(shù)據(jù)倉庫的同學(xué)會面臨三大問題:性能座咆、穩(wěn)定性痢艺、準確性,歸根結(jié)底還是性能問題介陶;框架的天花板以及sql復(fù)雜度堤舒、計算資源的緊張都會導(dǎo)致數(shù)據(jù)倉庫的性能受到挑戰(zhàn),隨著業(yè)務(wù)的積累哺呜,性能的問題變的越來越明顯舌缤,性能差直接導(dǎo)致整個數(shù)倉集群的穩(wěn)定性差,經(jīng)常出問題的數(shù)倉自然也就會數(shù)據(jù)不準某残,所以解決上述3個問題国撵,應(yīng)優(yōu)先解決性能問題。
介紹
SnappyData是一個基于內(nèi)存的數(shù)據(jù)庫玻墅,和redis不同的是SnappyData以數(shù)據(jù)分析為主介牙,可以處理一定的并發(fā)量,但不建議太高澳厢,100%支持hive sql环础,但聚合速度比hive快數(shù)百上甚至千倍囚似,自帶spark(指定的spark版本) ,是一款支持delete/update(性能不是很高)操作的OLAP庫线得。
背景
隨著易企秀業(yè)務(wù)的發(fā)展饶唤,大量的分析需求&報表需求接踵而至,產(chǎn)品和運營同學(xué)對數(shù)據(jù)分析的要求越來越高贯钩、對數(shù)據(jù)分析延遲越來越低募狂,之前通過由數(shù)據(jù)產(chǎn)品梳理業(yè)務(wù)指定分析指標,再由研發(fā)進行完成計算的方式已不能勝任角雷,需要重新重視數(shù)據(jù)倉庫的重要性祸穷。
這里采用的優(yōu)化方案是SnappyData + CBoard,通過jdbc連接SnappyData進行業(yè)務(wù)數(shù)據(jù)實時交互分析谓罗。其中CBoard是一個開源的自助分析BI系統(tǒng)粱哼,簡單的分組排序需求季二,產(chǎn)品和運營同學(xué)可以在上面托拉拽實現(xiàn)檩咱,從此研發(fā)同學(xué)不用加班加點疲于完成各種定制化報表了、大量釋放了研發(fā)同學(xué)的寶貴時間胯舷;SnappyData是一個開源的內(nèi)存型OLAP分析數(shù)據(jù)庫刻蚯,支持列式與行式存儲,目前我們絕大部分數(shù)據(jù)分析業(yè)務(wù)都能秒出桑嘶,支持adhoc, 100%兼容spark算子與sql操作炊汹,可通過spark 任務(wù)快速實現(xiàn)HDFS或者hive中的數(shù)據(jù)導(dǎo)入到SnappyData幔亥。
常見OLAP對比
數(shù)據(jù)庫 | 響應(yīng)時間 | 并發(fā)能力 | 社區(qū) | 處理能力 | 分析能力 | 缺點 |
---|---|---|---|---|---|---|
Impala | 慢 | 低 | 適中 | 支持的數(shù)據(jù)規(guī)模大 | 支持標準SQL以及多表join和窗口函數(shù) | 性能差怀酷、不實時 |
Kylin | 快 | 高 | 活躍 | 支持的數(shù)據(jù)規(guī)模大 | 性能高蚌成,支持標準SQL | 需要預(yù)計算魁淳、不支持多表關(guān)聯(lián) |
Druid | 快 | 高 | 活躍 | 支持的數(shù)據(jù)規(guī)模大 | 性能高具帮,但SQL支持弱 | 不支持adhoc囱桨、吃內(nèi)存 |
ES | 特快 | 中 | 活躍 | 支持的數(shù)據(jù)規(guī)模小 | 性能高膛檀,但SQL支持弱 | 僅支持單表的分組聚合排序芒粹、統(tǒng)計結(jié)果會有<1%的誤差 |
ClickHouse | 中 | 中 | 不活躍 | 支持的數(shù)據(jù)規(guī)模一般 | 性能中盈蛮,但SQL支持弱 | 擴展性弱废菱、多表關(guān)聯(lián)弱 |
Doris | 快 | 中 | 適中 | 支持的數(shù)據(jù)規(guī)模大 | 除update和delete外的標準SQL | 還在孵化階段、不兼容hadoop生態(tài) |
SnappyData | 快 | 中 | 不活躍 | 支持的數(shù)據(jù)規(guī)模中等 | 完全兼容spark sql,支持update與delete操作 | 穩(wěn)定性差抖誉、存在OOM的風(fēng)險 |
個人測試:在億級別單表查詢分析 ES都是最快的殊轴,基本都是毫秒級響應(yīng),但數(shù)據(jù)是抽樣預(yù)估出來的不是很準袒炉;SnappyData是綜合表現(xiàn)最好的旁理,雖然snappydata的社區(qū)并不活躍,但個人覺得官網(wǎng)提供的一手資料已經(jīng)足夠了我磁,即便snappydata穩(wěn)定性稍差但易用性和性能做的真是太誘人了
應(yīng)用
這里以一個簡單例子講解SnappyData的使用:將現(xiàn)有日志數(shù)據(jù)導(dǎo)入到SnappyData孽文,實現(xiàn)用戶多維度自助分析淹接。
- 安裝
1、官網(wǎng)下載最新的SnappyData文件 叛溢,
2塑悼、分發(fā)在20臺hadoop nodemanager節(jié)點上
3、
啟動 locator(任意兩臺):
./sbin/snappy-locator.sh start -peer-discovery-address=hadoop011 -peer-discovery-port=8888 -dir=/data/work/snappydata-1.1.0-bin/data/locator_1 -heap-size=1024m -locators=hadoop010:8888
啟動 lead(任意兩臺):
./sbin/snappy-lead.sh start -dir=/data/work/snappydata-1.1.0-bin/data/lead_1 -heap-size=4096m -spark.ui.port=2480 -locators=hadoop011:8888,hadoop010:8888 -spark.executor.cores=20
啟動 server(所有節(jié)點):
./sbin/snappy-server.sh start -dir=/data/work/snappydata-1.1.0-bin/data/server_1 -heap-size=8096m -locators=hadoop010:8888,hadoop011:8888
4楷掉、監(jiān)控
瀏覽器輸入如下地址
http://hadoop010.eqxiu.com:2480/dashboard/
-
導(dǎo)入日志數(shù)據(jù)
因為我們的按天日志數(shù)據(jù)都在hdfs上厢蒜,以parquet格式壓縮存儲,這里我們使用spark腳本進行ETL數(shù)據(jù)遷移烹植,命令如下:
val snappy = new org.apache.spark.sql.SnappySession(spark.sparkContext)
val df = spark.read.parquet("/data/merge/tracker_view/page_view/201906/01")
#如果數(shù)據(jù)在hive表中 則
val df = spark.read.table("tab_name")
val sn = snappy.createDataFrame(df.rdd, df.schema)
#第一次執(zhí)行saveAsTable 會自動在SnappyData中創(chuàng)建對應(yīng)的表
sn.write.format("column").saveAsTable("tracker_view")
#之后每天增量執(zhí)行
sn.write.format("column").insertInto("tracker_view")
也可以手動先創(chuàng)建表 斑鸦,然后再導(dǎo)入數(shù)據(jù)
CREATE TABLE CUSTOMER (
C_1 INTEGER NOT NULL,
...
...
)
USING COLUMN OPTIONS (BUCKETS '10', PARTITION_BY 'C_1')
其它參數(shù)說明
1、COLOCATE_WITH:COLOCATE_WITH {exist_table}語法的含義是對于新建的表草雕,與exist_table具有相同的分區(qū)鍵巷屿,且相同的BUCKETS數(shù)據(jù)量;數(shù)據(jù)存儲本地化墩虹,這樣做的好處是當2個表發(fā)生基于key的join時嘱巾,那些非常耗資源的hash join就不用跨節(jié)點進行數(shù)據(jù)傳輸(廣播),而是在本地進行join诫钓。這個設(shè)計思路非常像關(guān)系型數(shù)據(jù)庫Oracle中的cluster存儲旬昭。這種數(shù)據(jù)存儲本地化的特點,也是SnappyData在做join時比Spark快很多的原因之一菌湃。
2问拘、PARTITION_BY:PARTITION_BY {COLUMN}語法的含義是按某列進行分區(qū),當然也可以指定多個列作為組合惧所。行表如果沒有指定分區(qū)鍵骤坐,那么將是一張全局復(fù)制表;列表如果沒有指定下愈,那么內(nèi)部也會有個默認的分區(qū)纽绍。列表中的分區(qū)遵循Spark Catalyst的hash分區(qū),使得join時最小化shuffle驰唬。
3顶岸、BUCKETS:分區(qū)的個數(shù)。默認是128個叫编,最小的數(shù)據(jù)存儲單元辖佣。本地存儲,這個值可以設(shè)置為集群core數(shù)量的2倍搓逾。
4卷谈、REDUNDANCY:分區(qū)的副本數(shù),如果設(shè)置為0霞篡,表示沒有副本世蔗;如果設(shè)置大于0端逼,則會為partition創(chuàng)建對應(yīng)的副本數(shù),以防止member失敗污淋,達到數(shù)據(jù)的高可用性的目的顶滩。
5、EVICTION_BY:驅(qū)逐寸爆,很像Flink window中的eviction設(shè)置礁鲁。列表上默認的參數(shù)值是LRUHEAPPERCENT,根據(jù)LRU算法達到閥值時赁豆,開始將內(nèi)存中的較“冷”的數(shù)據(jù)溢出到本地磁盤:SnappyStore存儲仅醇。
6、PERSISTENCE:持久化魔种。默認是允許持久化的析二,數(shù)據(jù)會從內(nèi)存中持久化到本地SnappyStore存儲中,當重啟memeber時节预,SnappyData會自動從本地的SnappyStore存儲中恢復(fù)數(shù)據(jù)叶摄。
7、OVERFLOW:溢出心铃,默認是true准谚,即允許溢出。如果沒有指定PERSISTENCE去扣,且將OVERFLOW設(shè)置為false,那么當失敗時樊破,內(nèi)存中的數(shù)據(jù)將被丟失愉棱。
8、DISKSTORE:為持久化的數(shù)據(jù)或溢出的數(shù)據(jù)提供持久化目錄哲戚”蓟可以通過CREATE DISKSTORE為表提前創(chuàng)建出本地文件目錄,可以指定文件顺少、配置數(shù)據(jù)收縮朋其、配置數(shù)據(jù)異步到磁盤的頻率等等.
9、EXPIRE:過期時間脆炎。為了提高內(nèi)存使用率梅猿,對于很老的歷史數(shù)據(jù),可以通過設(shè)置過期時間使得超過閥值的行數(shù)據(jù)過期秒裕。但是過期參數(shù)只適合行表袱蚓。
10、COLUMN_BATCH_SIZE:剛才提到了几蜻,delta row buffer的batch大小喇潘,默認24MB体斩。超過閥值就會寫到列表。
11颖低、COLUMN_MAX_DELTA_ROWS:delta row buffer的最大行數(shù)絮吵,默認10000行。超過閥值會寫到列表忱屑。
-
測試
下面分組聚合在億級別數(shù)據(jù)量上1-2秒完成
select pro,count(distinct c_i) cn from tracker_view group by pro order by cn desc limit 11
小結(jié)
在做SnappyData搭建過程中也遇到了不少坑源武,這里就不一一列舉了,因為這不是一篇填坑的文章想幻,大家使用過程中有遇到問題也歡迎留言粱栖。
經(jīng)測試,我們最大的兩張業(yè)務(wù)表 作品(上億)+用戶(千萬) 關(guān)聯(lián)分析脏毯,可秒出闹究;使用過程中發(fā)現(xiàn)靈活性足夠了,但穩(wěn)定性稍差一些食店,建議在一些對穩(wěn)定性要求不高渣淤、時效性要求很高的內(nèi)部分析場景中使用。