基于大數(shù)據(jù)平臺的
億級別非結構化數(shù)據(jù)的存儲實現(xiàn)
神州信息
趙軍
1.
項目背景
本次建設基于某政府單位的電子檔案系統(tǒng),整體數(shù)據(jù)存儲量為240TB左右,使用Oracle存儲,并且按每年30%比例持續(xù)增長,隨業(yè)務發(fā)展,預計未來5年內將達到1PB左右的數(shù)據(jù)量。當存儲的數(shù)據(jù)量過大時,Oracle數(shù)據(jù)庫將面臨需要更大的存儲空間,大數(shù)據(jù)量的導入導出將導致數(shù)據(jù)庫無法高效、穩(wěn)定的運行;同時所需要的全備份周期會逐漸延長,會影響到工作時間內業(yè)務運行;存儲資源需求過大,整個災備系統(tǒng)的存儲資源也會投入過大。
目前電子檔案數(shù)據(jù)庫數(shù)據(jù)
表1電子檔案主要表情況(截止到2021年底)
存儲空間嚴重不足
電子檔案數(shù)據(jù)庫總存儲量為240TB左右,按照現(xiàn)在的增長速度呈指數(shù)級上升,5年內將達到1PB左右的數(shù)據(jù)量,Oracle數(shù)據(jù)庫將需要更大的存儲空間。從資金層面考慮數(shù)據(jù)庫 SAN 上的磁盤存儲通常比 Web 服務器場中使用的磁盤上的存儲更為昂貴。
數(shù)據(jù)存取方式落伍
原架構對于電子檔案數(shù)據(jù)采用直接通過服務器端程序將需要存儲的文件轉為二進制文件流直接存在數(shù)據(jù)庫表的BLOB字段中,當需要查詢時同樣也是服務器端將文件以流的方式查詢出來,經過處理后以二進制流的方式發(fā)送給客戶端顯示出來。
此種方法從項目的角度上來說,文件存儲和數(shù)據(jù)庫存儲最好是要分離的,二進制的存儲方式特別是針對存儲文件大而多的情況,因為性能較差,且大量占用數(shù)據(jù)庫內存,已經逐步淘汰。
計算壓力不堪重負
原電子檔案數(shù)據(jù)存儲在Oracle數(shù)據(jù)庫中,查詢條件單一,已不能滿足電子檔案業(yè)務的管理需求。隨著數(shù)據(jù)量的上漲,服務器計算壓力也逐漸不堪重負。對電子檔案庫的查詢操作在原系統(tǒng)中發(fā)生非常頻繁,在工作日繁忙階段可產生高并發(fā)的情況,按目前通過文件二進制流的查詢方式,查詢效率已經不甚樂觀,隨著數(shù)據(jù)量的不斷加大,如果繼續(xù)按目前的查詢方式來看查詢效率會不斷的下降,直接影響到日常業(yè)務,降低工作效率。
安全運行無法保障
大數(shù)據(jù)量的導入導出將導致數(shù)據(jù)庫無法高效、穩(wěn)定的運行。加之數(shù)據(jù)庫單點故障、磁盤損壞等情況更會加劇數(shù)據(jù)庫走向奔潰。
全量備份周期延長
隨著數(shù)據(jù)量的增長,所需要的全備份周期會逐漸延長,會影響到工作時間內業(yè)務運行;存儲資源需求過大,整個災備系統(tǒng)的存儲資源也會投入過大。
2.
想法與設計
2.1 方案選擇
為解決電子檔案系統(tǒng)存儲空間不足、運行狀態(tài)不穩(wěn)定、計算負荷過重、備份效率低下的問題,我們迫切需要改變現(xiàn)有的電子檔案集中式存儲架構。集中式存儲服務器使用本地磁盤存放所有數(shù)據(jù),增加磁盤是解決存儲空間唯一的辦法,計算能力無法提升,系統(tǒng)安全性和可靠性也無法得到保證,不能滿足大規(guī)模存儲應用的需求。而當前的電子檔案系統(tǒng)就是采用了這種架構模式。
表2 集中式存儲架構和分布式存儲架構特性比較
圖1 集中式存儲架構和分布式存儲架構比較
因此我們將采用分布式存儲架構替換原有的集中式存儲系統(tǒng),分布式存儲系統(tǒng)采用可擴展的系統(tǒng)結構,利用多臺存儲服務器分擔存儲負荷,利用位置服務器定位存儲信息,它提高了系統(tǒng)的可靠性、可用性和存取效率,還易于擴展。分布式存儲架構的種種特性,都能夠完美的解決我們當下所面臨的問題。
2.2 問題解決
存儲空間嚴重不足
分布式存儲不再需要昂貴的磁盤陣列來解決存儲問題,廉價的商用機器都能擴展器存儲能力。
分布式存儲系統(tǒng)通過對集群服務器規(guī)模進行進行擴展,從而使系統(tǒng)存儲容量、計算和性能得到提高。隨著業(yè)務量的增大,對底層分布式存儲系統(tǒng)的性能要求也隨之增高。衡量可擴展性的要求集群具有線性的可擴展性,系統(tǒng)整體性能和服務數(shù)量是線性關系。分布式存儲有著合理的分布式架構,能夠預估并且彈性擴展計算、存儲容量和性能。
計算壓力不堪重負
分布式存儲的去中心化思想,讓各個節(jié)點都能分擔計算壓力,計算能力隨著節(jié)點的擴展而提升。
系統(tǒng)的吞吐量和系統(tǒng)的響應延遲這兩項指標,經常被用來衡量分布式存儲系統(tǒng)的性能。通常高性能的分布式存儲,能夠高效的管理讀緩存和寫緩存,并且能夠自動分級存儲。分布式存儲是通過把熱點區(qū)域內數(shù)據(jù)映射到高速緩存中,以此來提高系統(tǒng)響應的速度;如果這些區(qū)域不再是熱點,那么存儲系統(tǒng)就會將它們從高速緩存中剔除。而寫緩存技術則是配合高速存儲,來使得整體存儲的性能有顯著提高,按一定的策略,先將數(shù)據(jù)寫入高速存儲,再在適當?shù)臅r間進行同步落盤。
安全運行無法保障
不用再擔心單點故障的問題,數(shù)據(jù)多副本分散存儲,即使多個節(jié)點宕機,系統(tǒng)依然能對外提供服務。
使用網絡進行松耦合連接,分布式存儲能夠允許高速存儲和低速存儲分開部署,或者以任意比例混布,在業(yè)務環(huán)境不可預測,或者用于敏捷的情況下,將分層存儲的技術優(yōu)勢發(fā)揮到最佳。而且分布式存儲系統(tǒng)不受惡意訪問和攻擊,能夠保護存儲數(shù)據(jù)不被竊取。
全量備份周期延長
系統(tǒng)默認的多副本、多節(jié)點放置策略,無需再考慮數(shù)據(jù)備份的問題,從而節(jié)省昂貴的異地容災備份。
分布式系統(tǒng)數(shù)據(jù)安全方面的容災與備份,數(shù)據(jù)可靠不丟失。在分布式存儲的容災中,一個重要的手段就是多時間點快照技術,這樣用戶生產系統(tǒng)可以實現(xiàn)在一定時間間隔內對各版本數(shù)據(jù)的保存。而且,多時間點快照技術,能夠支持同時提取多個時間點的樣本,并且同時進行恢復。這一功能對于故障重現(xiàn)也很有幫助,可幫助進行分析和研究,避免類似災難的再次發(fā)生。多時間點快照,周期增量復制等技術為分布式存儲的高可靠性提供了保障。
2.3 產品選型
考慮到實際場景的需要,我們的目標是要建立一套全新的分布式存儲系統(tǒng),既能滿足數(shù)據(jù)存儲的需要,也能提供快速高效的數(shù)據(jù)請求服務,并盡可能的避免對現(xiàn)有的業(yè)務審查系統(tǒng)造成影響。在我們產品選型方案中,F(xiàn)astDFS、MinIO、HDFS、HBase是我們根據(jù)場景需要進行篩選比對之后,選擇最佳的一種。
FastDFS
圖2 FastDFS架構圖
雖說能能解決海量非結構化數(shù)據(jù)(PDF)的存儲問題,但是需要額外的關系型數(shù)據(jù)來存放PDF的關鍵信息(文件名稱、大小、在FastDFS中的位置等),也不能很好的使用內存提高讀寫效率。
MinIO
圖3 MinIO架構圖
MinIO對象存儲系統(tǒng)是為海量數(shù)據(jù)存儲、人工智能、大數(shù)據(jù)分析而設計,適合存儲海量圖片、視頻、日志文件、備份數(shù)據(jù)等,同樣的,關鍵信息也需要額外的關系型數(shù)據(jù)庫控制。
HDFS
圖4 HDFS架構圖
HDFS是指被設計成適合運行在通用硬件上的分布式文件系統(tǒng),但其關鍵信息也需要額外的關系型數(shù)據(jù)庫控制,再者它不適合低延遲的數(shù)據(jù)訪問,不支持并發(fā)寫入和文件隨機修改,這不是我們想要的。
HBase
圖5 HBase架構圖
HBase特別適合于非結構化數(shù)據(jù)的存儲,關鍵信息與PDF一并存儲,不需額外的關系型數(shù)據(jù)庫。充分使用內存資源,從而能夠對外提供低延時、高并發(fā)的讀寫請求服務,這最適合我們的業(yè)務需求。
按照HBase設計特性,有如下優(yōu)勢是我們業(yè)務場景迫切需要的:
1) 容量巨大
HBase的單表可以有百億行、百萬列,可以在橫向和縱向兩個維度插入數(shù)據(jù),具有很大的彈性。
當關系型數(shù)據(jù)庫的單表記錄在億級別時,查詢和寫入的性能都會呈現(xiàn)指數(shù)級下降,這種龐大的數(shù)量對傳統(tǒng)數(shù)據(jù)庫來說是一種災難,而HBase在限定某個列的情況下對于單表存儲百億甚至更多的數(shù)據(jù)都沒有性能問題。
HBase采用LSM樹作為內部數(shù)據(jù)存儲結構,這種結構會周期性的將小文件合并為大文件,以減少對磁盤的尋址時間。
2) 列存儲
與很多面向行存儲的關系型數(shù)據(jù)不同,HBase是面向列的存儲和權限控制的,它里面的每個列式單獨存儲額的,且支持基于列的獨立檢索。通過下圖的列子來看行存儲和列存儲的區(qū)別:
圖6 行存儲和列存儲區(qū)別
從上圖可以看到,行存儲里的一張表的數(shù)據(jù)都放在一起,但在列存儲里是按照列分開保存的。在這種情況下,進行數(shù)據(jù)的插入和更新,行存儲會相對容易。而進行行存儲時,查詢操作需要讀取所有的數(shù)據(jù),列存儲則只需要讀取相關列,可以大幅度降低系統(tǒng)的I/O吞吐量。
3) 稀疏性
通常在傳統(tǒng)的關系型數(shù)據(jù)庫中,每一列的數(shù)據(jù)類型是事先定義好的,會占用固定的內存空間,在此情況下,屬性值為空(NULL)的列也需要占用存儲空間。
而在HBase中的數(shù)據(jù)都是以字符串形式存儲的,為空的列并不占用存儲空間,因此HBase的列存儲解決了數(shù)據(jù)稀疏的問題,在很大程度上節(jié)省了存儲開銷。所以HBase通常可以設計成稀疏矩陣,同時這種方式比較接近實際的應用場景。
4) 擴展性強
HBase工作在HDFS之上,理所當然也支持分布式表,也繼承了HDFS的可擴展性。HBase是橫向擴展的,橫向擴展是指在擴展時不需要提升服務器本身的性能,只需要添加服務器到現(xiàn)有的集群即可。
HBase表根據(jù)Region的大小進行分區(qū),分別存儲在集群中不同的節(jié)點上,當添加新的節(jié)點時,集群就重新調整,在新的節(jié)點啟動HBase服務器,動態(tài)實現(xiàn)擴展。這里需要指出的是,HBase的擴展是熱擴展,即在不停止現(xiàn)有的服務器的前提下,可以隨時添加或減少節(jié)點。
5) 高可靠性
HBase運行在HDFS之上,HDFS的多副本存儲可以讓它在出現(xiàn)故障時自動恢復,同時HBase內部也提供了WAL(預寫日志文件)和Replication機制。
WAL(Write-Ahead-Log)預寫日志是在HBase服務器處理數(shù)據(jù)插入和刪除的過程中用來記錄操作內容的日志的,保證了數(shù)據(jù)寫入時不會因集群異常而導致寫入數(shù)據(jù)的丟失;而Replicaiton機制是基于日志操作來做數(shù)據(jù)同步的。
當集群中的單個節(jié)點出現(xiàn)故障時,協(xié)調服務器組件ZooKeeper通知集群的主節(jié)點,將故障節(jié)點的HLog中的日志信息分發(fā)到各從節(jié)點進行數(shù)據(jù)恢復。
2.4 設計目標
集群管理
集群管理方面:提供可視化的UI界面,實現(xiàn)集群自動化安裝、中心化管理、集群監(jiān)控、報警功能為一體的控制平臺。
平臺運行
平臺運行方面:保證低故障率、出現(xiàn)問題快速修復;可提供全天候24小時不間斷服務。
讀寫請求
讀寫請求方面:即使在數(shù)據(jù)量急速上漲的情況下依然能夠提供低延遲、高并發(fā)的讀寫請求。
數(shù)據(jù)遷移
數(shù)據(jù)遷移方面:保證由Oracle到HBase之間的數(shù)據(jù)遷移不影響當前業(yè)務系統(tǒng)使用,數(shù)據(jù)遷移準確無遺。
3.
實踐與落地
3.1 集群管理
根據(jù)我們的業(yè)務場景需求,我們希望能夠避免使用原生的Apache Hadoop來部署HBase,而是使用企業(yè)版大數(shù)據(jù)平臺來實現(xiàn),即CDH(Cloudera Distributed Hadoop)。因為原生的Apache Hadoop和HBase都有很多未修復的Bug存在,而且實際過程中往往需要頻繁的操作命令行,不是一兩個人所能完成;而CDH解決了原生Hadoop的很多未修復問題,升級和各個生態(tài)圈技術的兼容性,也提供了可視化UI界面來供運維人員部署其余組件,大大減少了集群的部署時間。總的來說,CDH提供開箱即用的企業(yè)使用所需的一切,換位滿足企業(yè)需求而構建,CDH將Hadoop與十幾個其他關鍵的開源項目集成。
使用CM(Cloudera Manager),我們可將集群自動化安裝、中心化管理、集群監(jiān)控、報警處理等功能融為一體。集群的安裝可以從幾天的時間縮短為幾個小時,運維人員也會從數(shù)十人降低到幾個人,這更適合我們的工作所需,將繁重的運維管理工作剝離出來,將工作重心集中的業(yè)務開發(fā)中。
圖7 CM管理控制臺
CM集群管理的四大核心功能:
管理:對集群進行管理,如添加、刪除節(jié)點等操作。
1) 批量自動化部署節(jié)點:CM為我們提供了強大的集群管理能力,能夠批量自動化部署節(jié)點。安裝一個Hadoop集群只需要添加安裝的節(jié)點,安裝需要的組件和角色這三大步,大大縮短了Hadoop的安裝時間,也簡化了Hadoop的安裝過程。
2) 可視化的參數(shù)配置功能:Hadoop包含許多組件,不同組件都包含各種各樣的XML配置文件,使用CM,我們就可以在GUI界面可視化配置參數(shù)。
3) 智能參數(shù)驗證及優(yōu)化:當我們的配置部分參數(shù)值有問題時,CM會給出智能提示信息,幫助我們更合理的修改配置參數(shù)。
4) 高可用配置:使用CM,我們可以對關鍵組件進行HA部署,如CM的Web管理控制臺可以對HDFS NameNode啟用HA功能。
5) 權限管理:根據(jù)CM的權限控制級別,我們可以配置不同的用戶,如有的用戶只有訪問CM的權限,但無對服務啟停操作的權限。
監(jiān)控:監(jiān)控集群的健康情況,對設置的各種指標和系統(tǒng)運行情況進行全面監(jiān)控。
1) 服務監(jiān)控:查看服務和實例級別健康檢查的結果,對設置的各種指標和系統(tǒng)運行情況進行全面監(jiān)控。如果任何運行情況測試是不良(Bad),則服務或者角色的狀態(tài)就是不良(Bad)。如果運行狀態(tài)存在隱患(Concering,沒有任意一項目是不良),則服務或角色的狀況就是隱患(Concerning)。而且系統(tǒng)會對管理員應該采取的行動提出建議。
2) 主機監(jiān)控:監(jiān)控集群內所有主機的有關信息,包括主機目前消耗到內存,主機上運行的角色分配等,不但顯示所有集群主機的匯總視圖,而且能夠進一步顯示單個主機關鍵指標詳細視圖。
3) 行為監(jiān)控:根據(jù)CM提供的列表或圖表來看查看集群上進行的活動,不僅顯示當前正在執(zhí)行的任務行為,還可以通過儀表盤查看歷史活動。
4) 事件活動:根據(jù)CM監(jiān)控界面,我們可以查看事件,可以通過時間范圍、服務、主機、關鍵字等信息過濾事件。
5) 報警:通過配置CM可以對指定的時間產生警報,并通過電子郵件或者SNMP的事件得到制定的警報通知。
6) 日志和報告:輕松點擊一個鏈接查看相關的特定服務的日志條目,并且CM為我們生成了收集的歷史日志監(jiān)控數(shù)據(jù)統(tǒng)計報表。
診斷:對集群出現(xiàn)的問題進行診斷,對出現(xiàn)的問題給出建議方案。
1) 周期性服務診斷:CM會對集群中運行的所有服務進行周期性的運行狀況測試,以檢測這些服務的狀態(tài)知否正常。如果有異常,就會進行告警,有利于更早的讓我們感知集群服務存在的問題。
2) 日志采集及檢索:對于一個大規(guī)模的集群,CM為我們提供了日志收集功能,能夠通過統(tǒng)一的界面查看集群中每臺及其各項服務的日志,并且能夠根據(jù)日志級別等不同的條件進行檢索。
3) 系統(tǒng)性能使用報告:根據(jù)CM,我們能夠查看系統(tǒng)性能使用報告,包括集群的CPU使用率,單節(jié)點的CPU使用率,單個進程的CPU使用率等各項性能,這對于我們調試Hadoop集群的性能是很重要的。
集成:對Hadoop的多組件進行整合。
1) 生態(tài)圈各組件集成:企業(yè)級大數(shù)據(jù)平臺就是有這樣的好處,其集成了整個Hadoop生態(tài)圈的各項組件。根據(jù)CM控制臺,我們可以輕松的部署各項服務,各項服務都默認了最優(yōu)的配置,我們只需根據(jù)情況適當調整即可。包括ZooKeeper、HDFS、YARN、SQOOP、Flume、Kafka、Hive、HBase、Impla、Oozie、Hue、Spark等都可以實現(xiàn)可視化安裝,無需配置。
2) 安全配置:為了方便Hadoop大數(shù)據(jù)平臺與原有的身份認證系統(tǒng)如AD、LDAP等的集成,CM只需在界面上配置即可。
3) Cloudera Manager API:通過Cloudera Manager API,能夠方便的將CM集成到企業(yè)原有管理系統(tǒng)中。
3.2 平臺運行
存儲擴展
對于傳統(tǒng)的關系型數(shù)據(jù)庫來說,當存儲空間不足時,最好的辦法就是增加磁盤,隨著數(shù)據(jù)量不斷增長,不可避免的會遇到性能瓶頸,因為龐大的數(shù)據(jù)量導致每次查詢尋址時間過長,造成業(yè)務系統(tǒng)請求阻塞,嚴重制約了關系型數(shù)據(jù)庫的使用范圍。這種只增加存儲不增加計算能力的辦法只可解決當下的問題,卻無法面對長遠的隱患問題。
對于CDH來說,存儲擴展將變得非常容易。當存儲不夠或者計算壓力過重時,我們可以適當?shù)脑黾訖C器來提升系統(tǒng)性能,只要配置正確,新節(jié)點能非常兼容的加入集群中。這種即增加存儲也提升計算能力的辦法無論面對多大的數(shù)據(jù)量都不會是問題。
圖8 CDH集群擴容
CDH的集群擴容非常簡單,在CDH中,我們只在待添加的節(jié)點中做好基礎配置(網絡、域名、Selinux、文件打開的最大數(shù)量、數(shù)據(jù)盤掛載)即可,添加節(jié)點的操作均在CM控制臺操作。添加節(jié)點時,輸入IP或者域名搜索,然后選定在新添加的節(jié)點中要配置的服務和角色即可,其余的均有CM自動執(zhí)行。
添加服務
CM是控制臺,其集成的各項服務才是CDH的核心。在原生的Hadoop中,添加服務是一件非常繁瑣的事情。首先在管理節(jié)點中將要添加的服務配置好(XML);然后分發(fā)到所有的節(jié)點中;最后在各個節(jié)點中分別啟動;以上所有的服務均是在命令行操作。而在CDH中,CM的Web頁面提供了一鍵添加服務甚至批量添加服務功能,所有的服務均由CM做了默認的配置(XML),只需根據(jù)自身情況做調整即可。
圖9 CDH添加服務
高可用性
為保證系統(tǒng)24小時不間斷提供服務,我們需要針對關鍵角色做故障自動轉移配置,即HA配置。比如HDFS NameNode、YARN ResourceManager、HBase Master等關鍵的性的角色為了避免點單故障,需要對這些角色額外單獨(不同節(jié)點上)配置一個同樣的服務(備用),當發(fā)生故障時,備用服務自動啟動,做到無縫切換。
圖10 HDFS NameNode高可用配置
在原生的Hadoop中,如果要做HA配置,我們要做大量的手動操作:選擇節(jié)點、同步配置文件、啟用HA、同步元數(shù)據(jù)、共享元數(shù)據(jù)、全部重啟服務等。而在CDH中,我們只需在控制臺中點擊“啟用High Availability”,選中HA節(jié)點,剩余的都交由CM去執(zhí)行。
負荷分擔
面對過于沉重的荷載,對于Oracle來說,我們慣用的方法是分庫分表分區(qū)等;對于Hive表來說,也存在著分區(qū)分桶等方法來避免全表掃描。對于HBase來說,為了更好的提升性能,用拆分Region的方式來提升查詢速度。
圖11 HBase的拆分Region
HBase拆分Region有別于其他數(shù)據(jù)庫,HBase表的所有數(shù)據(jù)都按照RowKey排序,并且按照RowKey拆分Region,每個Region中包含一定范圍的數(shù)據(jù)(Start Key – End Key),每個Region中的數(shù)據(jù)又按照RowKey排序。
高可靠性
為保證系統(tǒng)的可靠性,我們配置冗余的數(shù)據(jù)備份,不同備份將不同磁盤、不同節(jié)點、不同機架分別存放。這樣部分節(jié)點宕機,或者某個磁盤損壞,甚至某臺節(jié)點宕機導致部分備份丟失,我們都不必當心數(shù)據(jù)安全問題。此外,按照HDFS的Heart Beat機制,系統(tǒng)還會監(jiān)控數(shù)據(jù)備份,一旦有備份丟失,系統(tǒng)將會自動復制新的一份到其余節(jié)點中。
圖12 HDFS的數(shù)據(jù)備份策略
在CDH中,數(shù)據(jù)備份策略在CM控制臺中即可配置,無需在命令行去操作。
低故障率
對于Hadoop來說,硬件故障是常態(tài),為了避免硬件故障導致系統(tǒng)出現(xiàn)奔潰的情況,我們需要在內存、磁盤等方面做一些調整:
內存:在Hadoop中有些角色是需要內存資源用來存儲關鍵信息的,如HDFS NameNode元數(shù)據(jù)、HBase BlockCache等;因此給這些角色適當增加內存是有助于提升系統(tǒng)性能的。
磁盤:系統(tǒng)盤和數(shù)據(jù)盤獨立創(chuàng)建,系統(tǒng)盤做冗余磁盤陣列RAID1。
3.3 讀寫請求
根據(jù)業(yè)務場景,我們所有的業(yè)務數(shù)據(jù)(結構化和非結構化)都存儲在HBase中,因此對CDH的讀寫請求更主要針對HBase的讀寫請求。提升HBase的讀寫請求效率是電子檔案系統(tǒng)最核心的需求,因此HBase的優(yōu)化工作是我們工作的重中之重。適當調高HBase內存、調整垃圾回收策略、更改默認的Region大小、選擇合適的小文件合并時機和拆分Region時機、啟用Snappy壓縮、預創(chuàng)建Region、避免Region熱點等等都可以提高HBase的存取速度。
調整HBase內存
這里首先涉及HBase服務的堆內存設置。一般剛部署的HBase集群,默認配置只給Master和RegionServer分配了1G的內存,RegionServer中MemStore默認占40%即400M左右的空間,而一個MemStore刷寫閾值默認為128M,所以一個RegionServer也就能正常管理3個Region,多了就可能產生小文件了,另外也容易發(fā)生Full GC。因此建議合理調整Master和RegionServer的內存,比如:
其次要考慮開啟BlockCache,首先,BlockCache是RegionServer級別的,一個RegionServer只有一個BlockCache。BlockCache的工作原理是讀請求會首先檢查Block是否存在于BlockCache,存在就直接返回,如果不存在再去HFile和MemStore中獲取,返回數(shù)據(jù)時把Block緩存到BlockCache中,后續(xù)同一請求或臨近查詢可以直接從BlockCache中讀取,避免過多昂貴的IO操作。
調整垃圾回收策略
1) G1收集器VS CMS收集器
CMS收集器在物理上區(qū)分年輕代和年老代空間。G1收集器會將heap分成很多region,然后在邏輯區(qū)分年輕代和年老代空間。G1收集器主要用于控制垃圾回收的時間。對于HBase使用場景,大部分年老代的對象是memsotre或者blockcache。對比測試發(fā)現(xiàn),CMS收集器有更好的表現(xiàn)。
2) CMS配置調優(yōu)
設置較大的heap size。使用CMSInitiatingOccupancyFraction=70,值為70為JVM的使用百分比,當達到這個閾值后將啟動回收任務,這個值比較適合的值是要略大約memstore 40%+blockcache 20%。如果CMSInitiatingOccupancyFraction這個值小于60會導致GC報警。
3) 新生代收集器UseParNewGC
使用UseParNewGC收集器,并加大新生代空間大小占heap size 25%,因為memstore(40%)+blockcache(20%)占總heap(60%),這兩部分空間會被存放在年老年空間。所以新生代空間不應該大小1-60%,讓更多的GC發(fā)生在新生代,UseParNewGC可以并行收集,收集成本低。
4) TargetSurvivorRatio設置
TargetSurvivorRatio=90設置Survivor區(qū)的可使用率。這里設置為90%,則允許90%的Survivor空間被使用。默認值為50%,故該值設置提高了Survivor區(qū)的使用率。但存放的對象超過這個百分比,則對象會向年老代壓縮。因此,這個選項更有助于將對象留在年老代。
選擇合適的Region數(shù)量
通常較少的region數(shù)量可使群集運行的更加平穩(wěn),官方指出每個RegionServer大約100個regions的時候效果最好,理由如下:
1) HBase的一個特性MSLAB,它有助于防止堆內存的碎片化,減輕垃圾回收Full GC的問題,默認是開啟的。但是每個MemStore需要2MB(一個列簇對應一個寫緩存memstore)。所以如果每個region有2個family列簇,總有1000個region,就算不存儲數(shù)據(jù)也要3.95G內存空間。
2) 如果很多region,它們中Memstore也過多,內存大小觸發(fā)Region Server級別限制導致flush,就會對用戶請求產生較大的影響,可能阻塞該Region Server上的更新操作。
3) HMaster要花大量的時間來分配和移動Region,且過多Region會增加ZooKeeper的負擔。
4) 從HBase讀入數(shù)據(jù)進行處理的mapreduce程序,過多Region會產生太多Map任務數(shù)量,默認情況下由涉及的region數(shù)量決定。
所以,如果一個HRegion中Memstore過多,而且大部分都頻繁寫入數(shù)據(jù),每次flush的開銷必然會很大,因此我們也建議在進行表設計的時候盡量減少ColumnFamily的個數(shù)。每個region都有自己的MemStore,當大小達到了上限(hbase.hregion.memstore.flush.size,默認128MB),會觸發(fā)Memstore刷新。
計算集群region數(shù)量的公式:((RS Xmx) * hbase.regionserver.global.memstore.size) / (hbase.hregion.memstore.flush.size * (# column families))
假設一個RS有16GB內存,那么16384*0.4/128m 等于51個活躍的region。
如果寫很重的場景下,可以適當調高hbase.regionserver.global.memstore.size,這樣可以容納更多的region數(shù)量。
建議分配合理的region數(shù)量,根據(jù)寫請求量的情況,一般20-200個之間,可以提高集群穩(wěn)定性,排除很多不確定的因素,提升讀寫性能。監(jiān)控Region Server中所有Memstore的大小總和是否達到了上限(hbase.regionserver.global.memstore.upperLimit * hbase_heapsize,默認 40%的JVM內存使用量),超過可能會導致不良后果,如服務器反應遲鈍或compact風暴。
更改默認的Region大小
HBase中數(shù)據(jù)一開始會寫入memstore,滿128MB(看配置)以后,會flush到disk上而成為storefile。當storefile數(shù)量超過觸發(fā)因子時(可配置),會啟動compaction過程將它們合并為一個storefile。對集群的性能有一定影響。而當合并后的storefile大于max.filesize,會觸發(fā)分割動作,將它切分成兩個region。
1) 當hbase.hregion.max.filesize比較小時,觸發(fā)split的機率更大,系統(tǒng)的整體訪問服務會出現(xiàn)不穩(wěn)定現(xiàn)象。
2) 當hbase.hregion.max.filesize比較大時,由于長期得不到split,因此同一個region內發(fā)生多次compaction的機會增加了。這樣會降低系統(tǒng)的性能、穩(wěn)定性,因此平均吞吐量會受到一些影響而下降。
3) hbase.hregion.max.filesize不宜過大或過小,經過實戰(zhàn),生產高并發(fā)運行下,最佳大小5-10GB!關閉某些重要場景的HBase表的major_compact!在非高峰期的時候再去調用major_compact,這樣可以減少split的同時,顯著提供集群的性能,吞吐量、非常有用。
HFile文件是否太多
文件越多,檢索所需的IO次數(shù)必然越多,讀取延遲也就越高。文件數(shù)量通常取決于Compaction的執(zhí)行策略,一般和兩個參數(shù)有關:
hbase.hstore.compactionThreshold和hbase.hstore.compaction.max.size,前者表示一個store中的文件數(shù)超過多少個就應該合并,后者表示參數(shù)合并的文件大小最大是多少,超過此大小的文件不能參與合并。
hbase.hstore.compactionThreshold設置不能太大,默認是3個;設置需要根據(jù)Region的大小,通常可以認為是
hbase.hstore.compaction.max.size=RegionSize/hbase.hstore.compactionThreshold。
選擇合適的小文件合并策略
Compaction是將小文件合并為大文件,提高后續(xù)業(yè)務隨機讀性能,但是也會帶來IO放大以及帶寬消耗問題,問題主要產生于配置不合理導致Minor Compaction太過頻繁,或者Region設置太大情況下發(fā)生Major Compaction。
觀察系統(tǒng)IO資源以及帶寬資源使用情況,再觀察Compaction隊列長度,確認是否由于Compaction導致系統(tǒng)資源消耗過多。
Minor Compaction設置:hbase.hstore.compactionThreshold設置不能太大,也不能太小,因此建議設置為5~6;
hbase.hstore.compaction.max.size=RegionSzie/hbase.hstore.compactionThreshold。
Major Compaction設置:大Region讀延遲敏感業(yè)務(100G以上)通常不建議開啟自動Major Compaction,手動低峰觸發(fā)。小Region或延遲不敏感業(yè)務也可以開啟自動Major Compaction,但建議限制流量。
Region拆分策略
Region為什么要拆分?隨著數(shù)據(jù)的增加,一個Region管理的數(shù)據(jù)條數(shù)越來越多,出現(xiàn)傳統(tǒng)SQL數(shù)據(jù)庫的單節(jié)點并發(fā)問題,將Region拆分,將Region移動均衡到其他節(jié)點。
Region拆分有三種方式:預拆分、自動拆分、手動強制拆分
1) 預拆分:指定每個預拆分的Region的RowKey的開始值
create 'test_table', 'table_spilt_test1', SPLITS=> ['1001', '2001', '3001']
2) 自動拆分
Region的默認大小問10G,超過10G就自動拆分,Region大小通過下面這個參數(shù)控制,生產環(huán)境如果預分區(qū)后,每個Region數(shù)據(jù)都比較大可改成20G 30G:
hbase.hregion.max.filesize
3) 強制拆分
可在HBase shell根據(jù)提示,對某個Region進行強制拆分:
也可以調用HBase JAVA API來操作。
啟用Snappy壓縮
啟用壓縮可以大大提高集群的可用性,scan性能顯著提升。目前HBase默認支持的壓縮包括GZ、LZO以及Snappy,測試對比之后選擇Snappy壓縮算法。
表3 不同壓縮算法測試性能比較
create ‘test’,{NAME => ‘info’,VERSIONS => 1,COMPRESSION => ‘snappy’}
預創(chuàng)建Region
HBase中的預分區(qū)就是在創(chuàng)建表之前,指定好RowKey在哪個范圍的數(shù)據(jù)會落到哪個分區(qū)中,因為HBase會按照字典順序把RowKey進行排序。預分區(qū)的好處是一方面可以提高讀寫效率,二是防止數(shù)據(jù)傾斜,起到負載均衡的作用。
創(chuàng)建表格時指定分區(qū)邊界:
create ‘staff’,’info’,’partition’,SPLITS = > [‘1000’,’2000’,’3000’,’4000’]
使用16進制算法生成預分區(qū)
ceate ‘staff’,’info’,’partiton’,{COLUMNS = > 15,SPLITALGO => ‘’HexStringSplit’}
避免Region熱點
檢索HBase的記錄首先要通過RowKey來定位數(shù)據(jù),當大量的Client方位HBase集群的一個或者幾個Region,會造成少數(shù)RegionServer的讀寫請求過多、負載過大,而其他RegionServer負載卻很小,就造成了“熱點”現(xiàn)象。
常見的避免熱點的方法:
1) 加鹽:這里的加鹽不是密碼學中的加鹽,而是在RowKey的前面增加隨機數(shù),具體就是給RowKey分配一個隨機前綴使得它和之前的RowKey的開頭不同。給多少個前綴,這個數(shù)量應該和我們要分散數(shù)據(jù)到不同的Region數(shù)量一致。
2) 哈希:哈希會使同一行永遠用一個前綴加鹽。哈希也可以使負載分散到整個集群,但是讀卻是可以預測的。使用確定的哈希可以讓客戶端重構完整的RowKey,可以使用get操作準確獲取某一個行數(shù)據(jù)。
3) 反轉:反轉固定長度或者數(shù)字格式的RowKey。這樣可以使得RowKey中經常改變的部分(最沒有意義的部分)放在
前面。這樣可以有效的隨機RowKey,但是犧牲了RowKey的有序性。
4) RowKey唯一原則:必須在設計上保證其唯一性,RowKey是按照二進制字節(jié)數(shù)據(jù)排序存儲的,因此設計RowKey的時候,要充分利用這個排序的特點,經常讀的數(shù)據(jù)存儲的一起,將最近可能會被訪問的數(shù)據(jù)放到一塊。
5) RowKey長度原則:RowKey是一個二進制碼流,可以是任意字符串,最大長度64kb,實際應用中一般為10-100byte,以byte[]形式保存,一般設計成定長度,建議越短越好,不要超過16個字節(jié)(因為RowKey是要加載到內存中的)。
6) RowKey散列原則:如果RowKey按照時間戳的方式遞增,不要將時間放到二進制碼的前面,建議將RowKey高位作為三列字段,由程序隨機生成,低位放時間字段,這樣將提高數(shù)據(jù)均衡分布在每個Region上,以實現(xiàn)負載均衡的幾率。
Swap的設置
推薦設置為0,這樣只有在物理內存不夠的情況下才會使用交換分區(qū)。這個參數(shù)由于JVM虛擬機如果使用了Swap在GC回收時會花費更多到時間。
3.4 數(shù)據(jù)遷移
SQOOP數(shù)據(jù)導入
使用SQOOP執(zhí)行數(shù)據(jù)遷移的目的是需要將Oracle中的結構化數(shù)據(jù)(ID)遷移到Hive中,然后在Hive中計算要預分Region的RowKey值:
預分Region的RowKey(start key和end key)計算
##創(chuàng)建臨時表并分區(qū)分桶,目的是為了更快的計算
MR接口編程
Oracle到HBase表之間的數(shù)據(jù)轉移以MapReduce分布式計算框架執(zhí)行:
1) Mapper:
2) Reduce:
3) 主程序入口:
4.
質變與總結
在數(shù)據(jù)存儲方面:電子檔案系統(tǒng)不用再承受Oracle頻繁增加磁盤和數(shù)據(jù)量猛增的情況下帶來的痛苦,即使再大的數(shù)據(jù)量,對于分布式集群來說,都是添加節(jié)點的事情。即使在廉價的商用機器上,大數(shù)據(jù)平臺都能得到很好的部署,讓數(shù)據(jù)存儲不再是個問題。
在讀寫速度方面:因為HBase的特性,返回同樣的數(shù)據(jù)HBase比Oracle有著更低的延遲、更高的效率。
在運行狀態(tài)方面:因為分布式集群不存在單點故障問題,系統(tǒng)穩(wěn)定方面有了很大的保證,可確保24小時不間斷提供服務。
在用戶體驗方面:隨著請求速度的提升,用戶不用再長時間的等待數(shù)據(jù)庫請求結果,極大的提高了用戶工作效率。