<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Hbase、Kudu 和 ClickHouse 全視角對比

          共 9091字,需瀏覽 19分鐘

           ·

          2021-05-23 08:56

          -     前言     -


          Hadoop生態(tài)圈的技術繁多。HDFS一直用來保存底層數據,地位牢固。Hbase作為一款Nosql也是Hadoop生態(tài)圈的核心組件,它海量的存儲能力,優(yōu)秀的隨機讀寫能力,能夠處理一些HDFS不足的地方。Clickhouse是一個用于聯機分析(OLAP)的列式數據庫管理系統(DBMS)。能夠使用SQL查詢實時生成分析數據報告。它同樣擁有優(yōu)秀的數據存儲能力。

          Apache Kudu是Cloudera Manager公司16年發(fā)布的新型分布式存儲系統,結合CDH和Impala使用可以同時解決隨機讀寫和sql化數據分析的問題。分別彌補HDFS靜態(tài)存儲和Hbase Nosql的不足。

          既然可選的技術路線有這么多,本文將從安裝部署、架構組成、基本操作等方面橫向對比一下Hbase、Kudu和Clickhouse。另外這里還引入了幾個大廠的實踐作為例子予以參考。

          -     安裝部署方式對比     -


          具體的安裝步驟不過多贅述,這里只簡要比較安裝過程中需要依賴的外部組件。


          -     Habse 安裝     -


          依賴HDFS作為底層存儲插件 依賴Zookeeper作為元數據存儲插件。

          -     Kudu 安裝     -


          依賴Impala作為輔助分析插件 依賴CDH集群作為管理插件,但是不是必選的,也可以單獨安裝。

          -     ClickHouse 安裝     -


          依賴Zookeeper作為元數據存儲插件和Log Service以及表的 catalog service

          組成架構對比。


          Hbase架構


          Kudu架構

          Clickhouse架構


          綜上所示,Hbase和Kudu都是類似于Master-slave的架構而Clickhouse不存在Master結構,Clickhouse的每臺Server的地位都是等價的,是multi-master模式。不過Hbase和Clickhouse額外增加了一個Zookeeper作為輔助的元數據存儲或者是log server等,而Kudu的元數據是Master管理的,為了避免server頻繁從Master讀取元數據,server會從Master獲取一份元數據到本地,但是會有元數據丟失的風險。

          -     基本操作對比     -


          數據讀寫操作

          ?Hbase讀流程


          ?Hbase寫流程

          ?Kudu

          ?Clickhouse
          Clickhouse是個分析型數據庫。這種場景下,數據一般是不變的,因此Clickhouse對update、delete的支持是比較弱的,實際上并不支持標準的update、delete操作。

          Clickhouse通過alter方式實現更新、刪除,它把update、delete操作叫做mutation(突變)。

          標準SQL的更新、刪除操作是同步的,即客戶端要等服務端反回執(zhí)行結果(通常是int值);而Clickhouse的update、delete是通過異步方式實現的,當執(zhí)行update語句時,服務端立即反回,但是實際上此時數據還沒變,而是排隊等著。

          Mutation具體過程
          首先,使用where條件找到需要修改的分區(qū);然后,重建每個分區(qū),用新的分區(qū)替換舊的,分區(qū)一旦被替換,就不可回退;對于每個分區(qū),可以認為是原子性的;但對于整個mutation,如果涉及多個分區(qū),則不是原子性的。

          ?更新功能不支持更新有關主鍵或分區(qū)鍵的列;
          ?更新操作沒有原子性,即在更新過程中select結果很可能是一部分變了,一部分沒變,從上邊的具體過程就可以知道;
          ?更新是按提交的順序執(zhí)行的;
          ?更新一旦提交,不能撤銷,即使重啟Clickhouse服務,也會繼續(xù)按照system.mutations的順序繼續(xù)執(zhí)行;
          ?已完成更新的條目不會立即刪除,保留條目的數量由finished_mutations_to_keep存儲引擎參數確定。超過數據量時舊的條目會被刪除;
          ?更新可能會卡住,比如update intvalue='abc’這種類型錯誤的更新語句執(zhí)行不過去,那么會一直卡在這里,此時,可以使用KILL MUTATION來取消。

          綜上所示,Hbase隨機讀寫,但是Hbase的update操作不是真的update,它的實際操作是insert一條新的數據,打上不同的timestamp,而老的數據會在有效期之后自動刪除。而Clickhouse干脆就不支持update和delete。

          -     數據查詢操作     -


          ?Hbase
          不支持標準sql,需要集成Phoenix插件。Hbase自身有Scan操作,但是不建議執(zhí)行,一般會全量掃描導致集群崩潰。

          ?Kudu
          與Impala集成實現查詢。

          ?Clickhouse
          自身有優(yōu)良的查詢性能。

          HBASE在滴滴出行的應用場景和最佳實踐

          HBase在滴滴主要存放了以下四種數據類型:
          ?統計結果、報表類數據:主要是運營、運力情況、收入等結果,通常需要配合Phoenix進行SQL查詢。數據量較小,對查詢的靈活性要求高,延遲要求一般。

          ?原始事實類數據:如訂單、司機乘客的GPS軌跡、日志等,主要用作在線和離線的數據供給。數據量大,對一致性和可用性要求高,延遲敏感,實時寫入,單點或批量查詢。

          ?中間結果數據:指模型訓練所需要的數據等。數據量大,可用性和一致性要求一般,對批量查詢時的吞吐量要求高。

          ?線上系統的備份數據:用戶把原始數據存在了其他關系數據庫或文件服務,把HBase作為一個異地容災的方案。

          -     訂單事件     -


          近期訂單的查詢會落在Redis,超過一定時間范圍,或者當Redis不可用時,查詢會落在HBase上。業(yè)務方的需求如下:

          ?在線查詢訂單生命周期的各個狀態(tài),包括status、event_type、order_detail等信息。主要的查詢來自于客服系統;

          ?在線歷史訂單詳情查詢。上層會有Redis來存儲近期的訂單,當Redis不可用或者查詢范圍超出Redis,查詢會直接落到HBase;

          ?離線對訂單的狀態(tài)進行分析?寫入滿足每秒10K的事件,讀取滿足每秒1K的事件,數據要求在5s內可用。


          按照這些要求,我們對Rowkey做出了下面的設計,都是很典型的scan場景。

          ?訂單狀態(tài)表
          Rowkey:reverse(order_id) + (MAX_LONG - TS)
          Columns:該訂單各種狀態(tài)。

          ?訂單歷史表
          Rowkey:reverse(passenger_id | driver_id) + (MAX_LONG - TS)
          Columns:用戶在時間范圍內的訂單及其他信息。

          -     司機乘客軌跡     -


          舉幾個使用場景上的例子:用戶查看歷史訂單時,地圖上顯示所經過的路線;發(fā)生司乘糾紛,客服調用訂單軌跡復現場景;地圖部門用戶分析道路擁堵情況。


          用戶們提出的需求:

          ?滿足App用戶或者后端分析人員的實時或準實時軌跡坐標查詢;

          ?滿足離線大規(guī)模的軌跡分析;

          ?滿足給出一個指定的地理范圍,取出范圍內所有用戶的軌跡或范圍內出現過的用戶。其中,關于第三個需求,地理位置查詢,我們知道MongoDB對于這種地理索引有源生的支持,但是在滴滴這種量級的情況下可能會發(fā)生存儲瓶頸,HBase存儲和擴展性上沒有壓力但是沒有內置類似MongoDB地理位置索引的功能,沒有就需要我們自己實現。通過調研,了解到關于地理索引有一套比較通用的GeohHash算法 。把GeoHash和其他一些需要被索引的維度拼裝成Rowkey,真實的GPS點為Value,在這個基礎上封裝成客戶端,并且在客戶端內部對查詢邏輯和查詢策略做出速度上的大幅優(yōu)化,這樣就把HBase變成了一個MongoDB一樣支持地理位置索引的數據庫。如果查詢范圍非常大(比如進行省級別的分析),還額外提供了MR的獲取數據的入口。

          兩種查詢場景的Rowkey設計如下:

          ?單個用戶按訂單或時間段查詢:reverse(user_id) + (Integer.MAX_LONG-TS/1000);
          ?給定范圍內的軌跡查詢:reverse(geohash) + ts/1000 + user_id。


          -     ETA     -


          ETA是指每次選好起始和目的地后,提示出的預估時間和價格。提示的預估到達時間和價格,最初版本是離線方式運行,后來改版通過HBase實現實時效果,把HBase當成一個KeyValue緩存,帶來了減少訓練時間、可多城市并行、減少人工干預的好處。整個ETA的過程如下:

          1.模型訓練通過Spark Job,每30分鐘對各個城市訓練一次;
          2.模型訓練第一階段,在5分鐘內,按照設定條件從HBase讀取所有城市數據;
          3.模型訓練第二階段在25分鐘內完成ETA的計算;
          4.HBase中的數據每隔一段時間會持久化至HDFS中,供新模型測試和新的特征提取。

          Rowkey:salting+cited+type0+type1+type2+TS Column:order, feature


          -     監(jiān)控工具 DCM     -


          用于監(jiān)控Hadoop集群的資源使用(Namenode,Yarn container使用等),關系數據庫在時間維度過程以后會產生各種性能問題,同時我們又希望可以通過SQL做一些分析查詢,所以使用Phoenix,使用采集程序定時錄入數據,生產成報表,存入HBase,可以在秒級別返回查詢結果,最后在前端做展示:


          -     小結     -


          在滴滴推廣和實踐HBase的工作中,我們認為至關重要的兩點是幫助用戶做出良好的表結構設計和資源的控制。有了這兩個前提之后,后續(xù)出現問題的概率會大大降低。良好的表結構設計需要用戶對HBase的實現有一個清晰的認識,大多數業(yè)務用戶把更多精力放在了業(yè)務邏輯上,對架構實現知之甚少,這就需要平臺管理者去不斷幫助和引導,有了好的開端和成功案例后,通過這些用戶再去向其他的業(yè)務方推廣。

          資源隔離控制則幫助我們有效減少集群的數量,降低運維成本,讓平臺管理者從多集群無止盡的管理工作中解放出來,將更多精力投入到組件社區(qū)跟進和平臺管理系統的研發(fā)工作中,使業(yè)務和平臺都進入一個良性循環(huán),提升用戶的使用體驗,更好地支持公司業(yè)務的發(fā)展。

          網易考拉基于KUDU構建實時流量數倉實踐

          Kudu不但提供了行級的插入、更新、刪除API,同時也提供了接近Parquet性能的批量掃描操作。使用同一份存儲,既可以進行隨機讀寫,也可以滿足數據分析的要求。

          實時流/業(yè)務數據寫入

          可以使用Spark Streaming 提供的KafkaUtils.createDirectStream方法來創(chuàng)建一個對應topic的Dstream。這種方法topic的offset將完全由我們自己控制:

          private val stream = KafkaUtils.createDirectStream[String, String](
          ssc,
          PreferConsistent,
          Subscribe[String, String](topics, kafkaParams)
          )

          寫入Kudu分以下幾個步驟:

          ?獲取kafka offset
          ?創(chuàng)建KuduContext
          ?定義寫入Kudu表的schema
          ?按照解析邏輯解析流量日志并構建DataFrame
          ?將df插入Kudu并提交offset

          val offsetRanges = rdd.asInstanceOf[HasOffsetRanges].offsetRanges

          val spark = SparkSession.builder.config(rdd.sparkContext.getConf).getOrCreate()
          val kuduContext = new KuduContext(kuduMaster, spark.sparkContext)

          val flowDf = spark.createDataFrame(rdd.map(r =&gt; {
          processFlowLine(r.value)
          }).filter(row =&gt; if (row.get(0) == null) false else true), schema)
          kuduContext.upsertRows(flowDf, "impala::kaola_kudu_internal.dwd_kl_flw_app_rt")

          stream.asInstanceOf[CanCommitOffsets].commitAsync(offsetRanges)



          -     寫入性能測試     -


          Kudu寫入表: haitao_dev_log.dwd_kl_flw_app_rt,分片: 240個,Spark Streaming調度間隔: 15s。


          可以發(fā)現75%的任務都在1s完成,有少數任務跑的較慢但整體在2s都跑完了,這里需要注意一種極端情況,由于Spark的默認配置并發(fā)數是1,如果有一個進程遲遲沒有跑完(一般是數據分布不均)那么后面的任務將會排隊,直到最初的任務跑完才會去調度下一個任務。這樣會造成資源浪費,多個空閑的executor會一直等待最后一個executor,流量日志不要求順序插入,因此我們可以加大任務的并發(fā)數。具體參數設置:

          spark.streaming.concurrentJobs = N


          -     小結     -


          目前實時寫入Kudu的流量日志在每日數十億條,寫入量在TB級,而且已有實時流量拆解等業(yè)務依賴Kudu的底層流量數據,接下來將會有更多的業(yè)務線遷移至Kudu以滿足不同維度下的分析需求。

          攜程CLICKHOUSE日志分析實踐

          結合攜程的日志分析場景,日志進入ES前已經格式化成JSON,同一類日志有統一的Schema,符合ClickHouse Table的模式;日志查詢的時候,一般按照某一維度統計數量、總量、均值等,符合ClickHouse面向列式存儲的使用場景。偶爾有少量的場景需要對字符串進行模糊查詢,也是先經過一些條件過濾掉大量數據后,再對少量數據進行模糊匹配,ClickHouse也能很好的勝任。另外我們發(fā)現90%以上的日志沒有使用ES的全文索引特性,因此我們決定嘗試用ClickHouse來處理日志。

          消費數據到CLICKHOUSE


          我們使用gohangout消費數據到ClickHouse,關于數據寫入的幾點建議:

          ?采用輪詢的方式寫ClickHouse集群的所有服務器,保證數據基本均勻分布。

          ?大批次低頻率的寫入,減少parts數量,減少服務器merge,避免Too many parts異常。通過兩個閾值控制數據的寫入量和頻次,超過10w記錄寫一次或者30s寫一次。

          ?寫本地表,不要寫分布式表,因為分布式表接收到數據后會將數據拆分成多個parts,并轉發(fā)數據到其它服務器,會引起服務器間網絡流量增加、服務器merge的工作量增加,導致寫入速度變慢,并且增加了Too many parts的可能性。

          ?建表時考慮partition的設置,之前遇到過有人將partition設置為timestamp,導致插入數據一直報Too many parts的異常。我們一般按天分partition。
          ?主鍵和索引的設置、數據的亂序等也會導致寫入變慢。

          -     數據展示     -


          我們調研了像Supperset、Metabase、Grafana等幾個工具,最終還是決定采用在Kibana3上開發(fā)支持ClickHouse實現圖表展示。主要原因是Kibana3這種強大的數據過濾功能,很多系統都不具備,另外也考慮到遷移到其他系統成本較高,用戶短期內難以適應。

          -     查詢優(yōu)化     -


          Kibana中的Table Panel用于顯示日志的明細數據,一般查詢最近1小時所有字段的數據,最終只展示前500條記錄。這種場景對于ClickHouse來說非常不友好。

          針對這個問題,我們將table Panel的查詢分兩次進行:第一次查詢單位時間間隔的數據量,根據最終顯示的數據量計算出合理查詢的時間范圍;第二次根據修正后的時間范圍,結合Table Panel中配置的默認顯示的Column查詢明細數據。

          經過這些優(yōu)化,查詢的時間可以縮短到原來的1/60,查詢的列可以減少50%,最終查詢數據量減少到原來的1/120;ClickHouse提供了多種近似計算的方法,用于提供相對較高準確性的同時減少計算量;使用MATERIALIZED VIEW或者MATERIALIZED COLUMN將計算量放在平常完成,也能有效降低查詢的數據量和計算量。

          -     ClickHouse 基本運維     -


          總體來說ClickHouse的運維比ES簡單,主要包括以下幾個方面的工作:

          ?新日志的接入、性能優(yōu)化;

          ?過期日志的清理,我們通過一個定時任務每天刪除過期日志的partition;

          ?ClickHouse的監(jiān)控,使用ClickHouse-exporter+VictoriaMetrics+Grafana的實現;

          ?數據遷移,通過ClickHouse分布式表的特性我們一般不搬遷歷史數據,只要將新的數據接入新集群,然后通過分布式表跨集群查詢。隨著時間的推移,歷史數據會被清理下線,當老集群數據全部下線后,新老集群的遷移就完成了。確實需要遷移數據時,采用ClickHouse_copier或者復制數據的方式實現。

          ?常見問題處理:
          慢查詢,通過kill query終止慢查詢的執(zhí)行,并通過前面提到的優(yōu)化方案進行優(yōu)化
          Too many parts異常:Too many parts異常是由于寫入的part過多part的merge速度跟不上產生的速度,導致part過多的原因主要包括幾個方面:

          ?設置不合理

          ?小批量、高頻次寫ClickHouse?寫的是ClickHouse的分布式表

          ?ClickHouse設置的merge線程數太少了

          ? 無法啟動:之前遇到過ClickHouse無法啟動的問題,主要包括兩個方面:

          - 文件系統損壞,通過修復文件系統可以解決
          - 某一個表的數據異常導致ClickHouse加載失敗,可以刪除異常數據后啟動,也可以把異常的文件搬到detached目錄,等ClickHouse起來后再attach文件恢復數據

          將日志從ES遷移到ClickHouse可以節(jié)省更多的服務器資源,總體運維成本更低,而且提升了查詢速度,特別是當用戶在緊急排障的時候,這種查詢速度的成倍提升,對用戶的使用體驗有明顯的改善。

          但是ClickHouse畢竟不是ES,在很多業(yè)務場景中ES仍然不可替代;ClickHouse也不僅只能處理日志,進一步深入研究ClickHouse,讓ClickHouse在更多領域發(fā)揮更大的價值,是我們一直努力的方向。

          -     總結    -


          這里簡單總結一下三者的特點。

          首先說一下Hbase與Kudu,可以說是Kudu師承Hbase,架構是類似的master-slave結構。Hbase的物理模型是master和regionserver,regionserver存儲的是region,region里邊很有很多store,一個store對應一個列簇,一個store中有一個memstore和多個storefile,store的底層是hfile,hfile是hadoop的二進制文件,其中HFile和HLog是Hbase兩大文件存儲格式,HFile用于存儲數據,HLog保證可以寫入到HFile中。

          Kudu的物理模型是master和tserver,其中table根據hash和range分區(qū),分為多個tablet存儲到tserver中,tablet分為leader和follower,leader負責寫請求,follower負責讀請求,總結來說,一個ts可以服務多個tablet,一個tablet可以被多個ts服務(基于tablet的分區(qū),最低為2個分區(qū))。

          而Clickhouse的特點在于它號稱最快的查詢性能,雖然也能存儲數據,但并不是他的強項,而且Clickhouse還不能update/delete數據。

          最后從下面幾個維度來對比一下Hbase、Kudu和Clickhouse。


          所以Hbase更適合非結構化的數據存儲;在既要求隨機讀寫又要求實時更新的場景,Kudu+Impala可以很好的勝任,當然再結合CDH就更好了,瓶頸并不在Kudu,而在Impala的Apache部署。如果只要求靜態(tài)數據的極速查詢能力,Clickhouse則更好。


          作者:super_chenzhou

          來源:

          https://blog.csdn.net/qq_37067752/article/details/107686978

          瀏覽 75
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产亲子乱XXXXinin | 污污网站在线观看 | 99精品成人免费毛片无码 | 人妻人人操| www.久青草精品 |