本文根據(jù)上海久耶大數(shù)據(jù)研發(fā)工程師武基鵬在中國(guó)HBase技術(shù)社區(qū)第四屆MeetUp上海站中分享的《基于HBase實(shí)時(shí)數(shù)倉(cāng)探索實(shí)踐》編輯整理而成。 今天從六個(gè)方面介紹,,首先是久耶第一代離線數(shù)倉(cāng)以及第二代實(shí)時(shí)數(shù)倉(cāng),。接下來(lái)介紹下公司業(yè)務(wù)場(chǎng)景和業(yè)務(wù)開發(fā),基于HBase的開發(fā)流程,然后介紹下公司CDH集群,,介紹下CDH集群調(diào)優(yōu)監(jiān)控,。最后分享兩個(gè)生產(chǎn)案例,。 第一代離線數(shù)倉(cāng)是在去年三月份上線,,主要是基于OMS和WMS,由于分庫(kù)分表,,大約有十幾個(gè)庫(kù),。前期通過(guò)SQOOP進(jìn)行數(shù)據(jù)抽取,后來(lái)由于SQOOP的一些問(wèn)題采用了阿里開源的DataX,時(shí)間粒度使用腳本調(diào)度實(shí)現(xiàn)T+1模式抽取到Hive,。作分析時(shí)采用Apache的Kylin,將數(shù)據(jù)直接存入HBase中,最初數(shù)倉(cāng)建立用于數(shù)表查詢,用的是Superset,,后面也用了Saiku,。六個(gè)月就被淘汰,,因?yàn)殡x線數(shù)倉(cāng)有個(gè)問(wèn)題,,業(yè)務(wù)部分要查詢數(shù)據(jù),但是你的時(shí)間粒度是昨天的,業(yè)務(wù)部分需要看當(dāng)天一段時(shí)間內(nèi)的數(shù)據(jù),離線是無(wú)法滿足,。 接下來(lái)在另一個(gè)集群構(gòu)建實(shí)時(shí)數(shù)倉(cāng),其選型主要有兩個(gè),第一個(gè)是實(shí)時(shí),實(shí)時(shí)采集利用Maxwell,直接采集公司數(shù)據(jù)庫(kù)MySQL,將數(shù)據(jù)直接以json格式發(fā)送到kafka,,數(shù)倉(cāng)存儲(chǔ)選型是HBase,。 為什么選擇Maxwell呢,,第一個(gè)它能夠使用“select * from Table”進(jìn)行bootstrapping初始化數(shù)據(jù),,在大數(shù)據(jù)構(gòu)建時(shí)可以利用Maxwell進(jìn)行全表掃描,,這句SQL會(huì)自動(dòng)觸發(fā)Maxwell某個(gè)線程進(jìn)行數(shù)據(jù)拉取。第二個(gè)Maxwell支持?jǐn)帱c(diǎn)還原功能,,大數(shù)據(jù)平臺(tái)架構(gòu)不光考慮到高可靠,、高性能,,也要保證數(shù)據(jù)零丟失,它支持記錄MySQL的post日志進(jìn)行數(shù)據(jù)還原,,這是當(dāng)初選擇最重要的原因,。第三個(gè)Maxwell將數(shù)據(jù)從MySQL發(fā)送到Kafka,Kafka是分區(qū)的,,如何保證全局有序是個(gè)問(wèn)題,。它能保證這個(gè)特性,,支持database, table, primary key, or column的拼接,將數(shù)據(jù)發(fā)送到某個(gè)分區(qū),;比如一條業(yè)務(wù)數(shù)據(jù)在業(yè)務(wù)系統(tǒng)先在insert再做update再做delete,,Kafka會(huì)將這三者發(fā)送到三個(gè)分區(qū),key值為空不會(huì)記錄,,在銷毀時(shí)用sparkstreaming可能會(huì)以delete,、update、insert順序,,會(huì)造成數(shù)據(jù)紊亂,。我們希望將這些特征數(shù)據(jù)發(fā)送到Kafka一個(gè)分區(qū),而Kafka單分區(qū)是有序的,。第四個(gè)Maxwell也會(huì)將這些數(shù)據(jù)發(fā)送到后端,,當(dāng)業(yè)務(wù)數(shù)據(jù)的表需要升級(jí),,如加索引、加字段,,可以通過(guò)alert語(yǔ)句解析捕獲,進(jìn)行同步更新到HBase中,。因此基于這四點(diǎn)要求選擇了Maxwell,沒(méi)有選擇當(dāng)前其他開源產(chǎn)品。 接下來(lái)講一下為什么選擇HBase而不選擇pudu等產(chǎn)品,。第一個(gè)是HBase是分布式,、可縮的,。第二個(gè)是隨機(jī)的讀和寫,,第三個(gè)HBase支持百萬(wàn)列,。第三個(gè)介紹下為什么要選擇Phoenix,首先原因是支持SQL,,利用原生HBase進(jìn)行查詢,、代碼分析比較吃力。第二個(gè)我們構(gòu)建的表是鹽表,,能夠解決熱點(diǎn)問(wèn)題,避免一個(gè)節(jié)點(diǎn)很繁忙另一個(gè)節(jié)點(diǎn)很閑,。第三Phoenix支持二級(jí)索引,由于表是鹽表(分區(qū)),索引也是分區(qū)的,。第四個(gè)支持Spark,可以直接將表傳入Phoenix而不用通過(guò)HBase,,有利于傳統(tǒng)開發(fā)人員轉(zhuǎn)型,而不用專注于底層HBase,。 基于CDH HBase版本構(gòu)建Phoenix版本歷程,,phoenix-for-cloudera-4.9,、HBase-1.2、cdh5.9,,這個(gè)存在問(wèn)題,然后采用apache-phoenix-4.11.0、HBase-1.2,最后采用phoenix-for-cloudera-4.10,、HBase-1.2,、cdh5.12。cdh5.11的郵件配置存在bug,。 進(jìn)行編譯的原因是去年Phoenix官方是不支持CDH版本,,目前是支持的。編譯時(shí)將pom文件,,改為CDH支持,然后改生產(chǎn)需要的Spark版本,。修復(fù)SYSTEM.MUTEX表在分布式的計(jì)算時(shí),,多次創(chuàng)建錯(cuò)誤。QueryServicesOptions.java文件修改參數(shù)DEFAULT_IS_NAMESPACE_MAPPING_ENABLED=true,。Phoenix存在一個(gè)問(wèn)題就是時(shí)區(qū),,比如一條上午十點(diǎn)的業(yè)務(wù)數(shù)據(jù)在Phoenix周轉(zhuǎn)下,時(shí)間數(shù)據(jù)會(huì)減一個(gè)8小時(shí),。修改DateUtil.java文件timezone為”Asia/Shanghai”,,但是讀寫兩種只解決了一種,而業(yè)務(wù)代碼開發(fā)需要經(jīng)過(guò)Phoenix架構(gòu)JDBC,,數(shù)據(jù)還是會(huì)出錯(cuò),,上面只解決了查詢,后來(lái)采用下面改動(dòng),,然后編譯,。 上圖是實(shí)時(shí)數(shù)倉(cāng)架構(gòu)圖,主要的存儲(chǔ)層還是以HBase為主,。第一層業(yè)務(wù)系統(tǒng)數(shù)據(jù)庫(kù)在阿里云平臺(tái)上,,有OMS、WMS,,Report DB是OMS和WMS的重復(fù),,將里面的數(shù)據(jù)全部同步于一臺(tái)機(jī)器,使用的就是Maxwell,,其支持白名單和黑名單,。業(yè)務(wù)平臺(tái)的表可能有兩三百個(gè),大數(shù)據(jù)平臺(tái)的計(jì)算可能只需要100多個(gè),,可以添加白名單,,有些表的數(shù)據(jù)就可以不用過(guò)來(lái)了。這些數(shù)據(jù)通過(guò)Json發(fā)送到Kafka,,然后通過(guò)Spark streaming去消費(fèi)Kafka,,通過(guò)JDBC寫入HBase。表不是通過(guò)Phoenix語(yǔ)句創(chuàng)建,不關(guān)心底層HBase,,只需要通過(guò)Phoenix像MYSQL一樣查詢即可,。同時(shí)會(huì)將計(jì)算結(jié)果存儲(chǔ)到Redis,久耶慧策應(yīng)用也會(huì)將數(shù)據(jù)寫入ES里面,。中間一層就是常見(jiàn)應(yīng)用開發(fā),,如Spark Streaming、Spark SQl,,也用Python和R語(yǔ)言,。調(diào)度平臺(tái)起先用的是Azkaban,然后是Airflow,,最后用的是Oozie,。上圖藍(lán)色是實(shí)時(shí)大屏,紅色是全球倉(cāng)庫(kù),,大約有四十幾個(gè),,數(shù)據(jù)綁定用的是saiKU,將Phoenix架包集成進(jìn)去,,saiKU分上卷和下卷,,業(yè)務(wù)人員依據(jù)自己的需求去拿行和列數(shù)據(jù),saiKU通過(guò)Phoenix組裝SQL語(yǔ)句查詢結(jié)果數(shù)據(jù),。也用到zeppelin,,這是Spark交互式開發(fā)必須用到的。 接下來(lái)講一下數(shù)據(jù)倉(cāng)庫(kù),,首先是模型建設(shè),,第一層是基礎(chǔ)表,在Phoenix中建立與MySQL一樣的表,。在基礎(chǔ)表的基礎(chǔ)上構(gòu)建事實(shí)表(訂單實(shí)時(shí)發(fā)生的表)和維度表(如中國(guó)有多少省多少市等更新不是很大的表),,依據(jù)事實(shí)表和維度表進(jìn)行代碼開發(fā),構(gòu)建領(lǐng)域表,,就是依據(jù)業(yè)務(wù)需求得出的結(jié)果存到領(lǐng)域表,。數(shù)據(jù)校驗(yàn)是通過(guò)數(shù)據(jù)量比對(duì),起先是在重庫(kù)時(shí)做觸發(fā)器,,但是MySQL重庫(kù)觸發(fā)器支持不友好,。通過(guò)改造Phoenix代碼將數(shù)據(jù)寫入Redis,增加加一刪除減一,,MySQL數(shù)據(jù)和HBase數(shù)據(jù)是一天一查一對(duì)比,,當(dāng)不相等直接調(diào)用shell腳本進(jìn)行全表掃描。當(dāng)前只采用OMS,、WMS的庫(kù),,QPS處于2000,,1條數(shù)據(jù): 平均60列 495b。 業(yè)務(wù)場(chǎng)景開始是業(yè)務(wù)報(bào)表開發(fā),,有客訴妥投,、ABC訂單、商業(yè)季度等,。也提供一個(gè)BI自助分析,,第三個(gè)就是雙十一大屏和龍虎榜,同時(shí)使用了BMS系統(tǒng),,是一個(gè)商業(yè)結(jié)算系統(tǒng),。第五個(gè)是今年做的領(lǐng)導(dǎo)層和客戶層的慧策,商業(yè)決策分析,。 業(yè)務(wù)開發(fā)套路就是依據(jù)業(yè)務(wù)需求將數(shù)據(jù)存在那些表里面,,需要將構(gòu)建表的語(yǔ)句提取出來(lái)構(gòu)建Phoenix Table,然后Kafka+Spark Streaming+Phoenix進(jìn)行數(shù)據(jù)的插入,。接著就是Spark開發(fā)讀和寫,我們還利用了DBeaver,。我們建表使用了聯(lián)合組件,,由于公司集群規(guī)模不是很高,regionServer是38臺(tái),,COMPRESSION 是使用SNAPPY,,這是依據(jù)壓縮比、解壓性能,。 接下來(lái)是一個(gè)經(jīng)典開發(fā)案例Kafka+Spark Streaming+Phoenix,,Phoenix可以理解為MySQL架包的JDBC。我們并沒(méi)有使用Phoenix的Pool池,,官方也推薦使用正常JDBC文件,,因?yàn)?/span>JDBC已經(jīng)支持長(zhǎng)連接,foreachPartition拿到Phoenix的JDBC,,中間進(jìn)行常見(jiàn)數(shù)據(jù)處理,,Kafka接收過(guò)來(lái)數(shù)據(jù)是Json格式,如何將其轉(zhuǎn)化為Phoenix的upset語(yǔ)法和delete語(yǔ)法,,完成后就將連接關(guān)閉,。 數(shù)據(jù)流入Phoenix大數(shù)據(jù)平臺(tái)是通過(guò)bootstream的全表掃描,其增量數(shù)據(jù)也是實(shí)時(shí)進(jìn)入,。業(yè)務(wù)代碼開發(fā)首先將架包導(dǎo)入pom文件,,如何找維度是將Phoenix的Apache下載到IDEA,在測(cè)試類里面查找,。Phoenix+Spark讀取有好幾種,,選擇以上寫法原因有:首先其支持列裁剪,,第二支持where條件,configuration指的是Spark的HDFS的conf,。 業(yè)務(wù)開發(fā)是多張表,,Spark表是df,接下來(lái)就和Phoenix和HBase無(wú)關(guān),。接下來(lái)就是對(duì)接Spark業(yè)務(wù)開發(fā)邏輯處理,,最后結(jié)果集會(huì)回寫到HBase中。還是通過(guò)Phoenix寫入,,有追加,、overwrite。HBase沒(méi)有很好地可視化工具,,利用DBeaver,,支持MYSQL、Oracle等所有數(shù)據(jù)庫(kù)類型,,也支持二次開發(fā)借助于接口實(shí)現(xiàn),。 接下來(lái)介紹下集群調(diào)優(yōu)參數(shù),分為六個(gè)方面:(1)Linux parameters,、(2)HDFS parameters,、(3)HBase parameters、(4)GC parameters,、(5)Monitor,、(6)Bug。句柄數(shù),、文件數(shù),、線程數(shù)這些都是要調(diào),因?yàn)閞egionserver在操作時(shí)需要open file,,處理時(shí)需要用到一些線程,,一些系統(tǒng)都是架設(shè)在Linux上,因此集群調(diào)優(yōu)都需要調(diào)它,。需要注意的是改完后需要檢查是否生效,,立即生效是sysctt-p。Spark開發(fā)需要將數(shù)據(jù)頻繁的寫入HBase中,,HBase底層是HDFS,,在寫入時(shí)就會(huì)出現(xiàn)問(wèn)題,最后發(fā)現(xiàn)Linux系統(tǒng)參數(shù)沒(méi)有調(diào),。 在正常的HBase節(jié)點(diǎn)機(jī)器上,,swap是設(shè)置為0,這并不是禁用swap而是其惰性是最大的,。由于我們公司由于業(yè)務(wù)系統(tǒng)較多,,吃的內(nèi)存比較緊,,因此設(shè)為10,這樣可以使job慢一點(diǎn)但是不能掛,,但是如果做實(shí)時(shí)就需要設(shè)置為0,。這個(gè)最終設(shè)置取決于你們自身業(yè)務(wù)環(huán)境,選擇自己需要的就好,。如果做CBH的平臺(tái)部署必須要關(guān)閉大頁(yè)面,。 接下來(lái)分享一個(gè)有意思的參數(shù)HDFS Parameters,正常調(diào)優(yōu)是CBH界面打開,、HBase的xml文件打開,。主要調(diào)優(yōu)是timeout和handler參數(shù),將其幾倍放大,,socket.timeout在HBase的xml文件一定要部署,,否則無(wú)法支持高并發(fā)操作。 當(dāng)一個(gè)本機(jī)線程無(wú)法創(chuàng)建一個(gè)本機(jī)線程,,這段代碼打在HDFS的dataload,,當(dāng)時(shí)dataload的內(nèi)存配置是8G,實(shí)際只使用1G,,這個(gè)時(shí)候就休要加上echo "kernel.threads-max=196605"->/etc/sysctl.conf,,echo"kernel.pid_max=196605"->/etc/sysctl.conf,echo "vm.max_map_count=393210"-> /etc/sysctl.conf三個(gè)參數(shù),,這其實(shí)是底層Linux拋出的錯(cuò)誤。提醒一點(diǎn)socket.timeout參數(shù)不僅在HDFS中需要配置,,在HBase中也需要配置,。 GC是regionserver配置,但是配置是CDH配置,,GC默認(rèn)垃圾選擇器是CMS,,需要將其改為GE,如果需要配置可以去嘗試下,,小米以前分享過(guò),。可以對(duì)參數(shù)進(jìn)行調(diào)試進(jìn)行壓錯(cuò)調(diào)優(yōu),,尤其大數(shù)據(jù)平臺(tái)開發(fā)尤其如此,。 項(xiàng)目上線需要做監(jiān)控,第一個(gè)就是HBase的讀和寫,,綠色是寫,,但是讀存在兩個(gè)波峰,因?yàn)槲覀兊恼{(diào)度平臺(tái)以一個(gè)小時(shí)將所有job調(diào)度完,。圖中Y軸是每秒的請(qǐng)求量,,如果寫的量上來(lái)了或者讀的波峰沒(méi)有規(guī)律,,就有可能是集群宕了。 第二個(gè)監(jiān)控的指標(biāo)是FDS,,就是Regionserver的文件句柄數(shù),,如果請(qǐng)求很多,句柄數(shù)會(huì)很高,,因?yàn)槠涞讓右蕾囉贚inux,,如果超過(guò)Linux設(shè)置值機(jī)器容易夯住下線,導(dǎo)致CPU不正常,,這時(shí)需要后臺(tái)強(qiáng)制機(jī)器下線,。然后需要監(jiān)控Zookeeper,監(jiān)控的是Zookeeper Open Connections,,因?yàn)?/span>HBase進(jìn)行操作需要打開的連接,,當(dāng)業(yè)務(wù)場(chǎng)景為長(zhǎng)服務(wù),如Spark streaming一直運(yùn)行,,先前嘗試用SparkSQL+Phoenix做一個(gè)長(zhǎng)服務(wù),,因?yàn)檎{(diào)度都是通過(guò)shell腳本調(diào)度,在資源緊張時(shí)需要搶資源,,在submit時(shí)需要申請(qǐng)資源(大約30S),,線上是不允許的。最后采用Spark streaming+Spark SQL+Phoenix JDBC,,Spark streaming是實(shí)時(shí)的每隔一小時(shí)判斷進(jìn)行數(shù)據(jù)處理,,這個(gè)時(shí)候Zookeeper Open Connections就隨著遞增趨勢(shì)上漲,當(dāng)?shù)?/span>Connection數(shù)(默認(rèn)500)CDH會(huì)殺掉,。后來(lái)改為水平,,利用PHOENIX-4319:Zookeeper connection should be closed immediately解決問(wèn)題。 接下來(lái)講一下Kafka如何做監(jiān)控,,其實(shí)只需要上面一幅圖,,上圖綠色指標(biāo)讀,Received是藍(lán)色線,,相當(dāng)于生產(chǎn)者寫到Kafka里面,,綠色是Spark streaming進(jìn)行消費(fèi),相當(dāng)于Fetched,。這幅圖相當(dāng)于實(shí)時(shí)同步架構(gòu),,消息沒(méi)有做積壓。但是為什么波峰會(huì)比它高,,原因是數(shù)據(jù)通過(guò)Maxwell發(fā)送到Kafka時(shí)是一個(gè)Json數(shù)據(jù),,但是Kafka消費(fèi)時(shí)需要額外加一些東西(來(lái)自哪個(gè)topic、offset是什么等),,如果兩條線沒(méi)問(wèn)題就是沒(méi)出問(wèn)題,。 Bug方面,,PHOENIX-4056:java.lang.IllegalArgumentException: Can not create a Path from an empty string,先前有問(wèn)題采用降版本,,目前已經(jīng)解決,,方案在社區(qū)里有。SPARK-22968:java.lang.IllegalStateException: No current assignment for partition kssh-2,,這個(gè)是Sparkstreaming讀Kafka時(shí)拋出的錯(cuò)誤,,這個(gè)在Spark2.4.0有新的補(bǔ)丁。 接下來(lái)分享兩個(gè)案例,,分為兩種,,一種是3次RIT,園區(qū)斷電機(jī)器掛掉出現(xiàn)RIT,。HBase有個(gè)WAL,,數(shù)據(jù)基本不會(huì)丟,只需要將機(jī)器重啟,。重啟過(guò)程會(huì)有一些RIT操作,,如果regionserver掛了申請(qǐng)維護(hù)時(shí)間,嘗試重啟regionserver節(jié)點(diǎn),,如果不行重啟HBase集群,,這個(gè)時(shí)候需要看HBase的master的active的log日志。還有一次是高并發(fā)內(nèi)存不夠用,,regionserver掛掉,,重啟后在CDH的HBase運(yùn)行正常,但是在監(jiān)控頁(yè)面HBase還是異常,,這時(shí)候只需要將CMS的serviceMonitor重啟就OK,。第三次RIT事故regionserver掛掉,嘗試使用HBCK命令修復(fù)問(wèn)題還是很多,。最后通過(guò)日志分析發(fā)現(xiàn)Hlog有問(wèn)題,通過(guò)HDFS命令將文件移到某個(gè)地方,,重啟就OK了,。丟失的數(shù)據(jù)通過(guò)Maxwell恢復(fù),預(yù)估事故發(fā)生點(diǎn)通過(guò)全表掃描進(jìn)行恢復(fù),。 接下來(lái)分享一個(gè)三支煙的故事,,數(shù)據(jù)來(lái)源于阿里云,自建機(jī)房需要通過(guò)***將數(shù)據(jù)拉倒本地機(jī)房,。雙十一所有倉(cāng)庫(kù)都在運(yùn)作,,MySQL機(jī)器扛不住導(dǎo)致延遲比較大,延遲約半個(gè)小時(shí),。需要在T2將數(shù)據(jù)完全恢復(fù),,解決方案直接將Maxwell架設(shè)到阿里云進(jìn)行實(shí)時(shí)同步,,數(shù)據(jù)進(jìn)行全表掃描,只需要掃描大屏顯示需要的數(shù)據(jù),,將T1到T2的數(shù)據(jù)進(jìn)行SparkSQL,,將計(jì)算結(jié)果寫到redis里面,Sparkstreaming進(jìn)行現(xiàn)場(chǎng)改,,只判斷T2流進(jìn)的數(shù)據(jù)才會(huì)將T2的基礎(chǔ)值進(jìn)行累積計(jì)算,,實(shí)時(shí)Job跑了15分鐘數(shù)據(jù)就實(shí)時(shí)過(guò)來(lái)了。 作者介紹: 武基鵬,,上海久耶供應(yīng)鏈管理有限公司大數(shù)據(jù)研發(fā)工程師,。主要從事大數(shù)據(jù)平臺(tái)產(chǎn)品的技術(shù)工作;負(fù)責(zé)設(shè)計(jì),、構(gòu)建和優(yōu)化基于HDFS/HBase的存儲(chǔ)平臺(tái)架構(gòu),;負(fù)責(zé)提升Hadoop/HBase等集群的高可用性、高性能,、高擴(kuò)展特性,;負(fù)責(zé)基于Spark開發(fā)及性能調(diào)優(yōu)。 |
|
來(lái)自: 白楊4546 > 《大數(shù)據(jù)》