大數據存儲技術方案介紹
來自: http://my.oschina.net/lwhmdj0823/blog/617726
大數據存儲方案
Cap思想
分布式領域CAP理論,
Consistency(一致性), 數據一致更新,所有數據變動都是同步的
Availability(可用性), 好的響應性能
Partition tolerance(分區容錯性) 可靠性
定理:任何分布式系統只可同時滿足二點,沒法三者兼顧。
忠告:架構師不要將精力浪費在如何設計能滿足三者的完美分布式系統,而是應該進行取舍。
關系數據庫的ACID模型擁有 高一致性 + 可用性 很難進行分區:
Atomicity原子性:一個事務中所有操作都必須全部完成,要么全部不完成。
Consistency一致性. 在事務開始或結束時,數據庫應該在一致狀態。
Isolation隔離層. 事務將假定只有它自己在操作數據庫,彼此不知曉。
Durability. 一旦事務完成,就不能返回。
跨 數據庫事務:2PC (two-phase commit), 2PC is the anti-scalability pattern (Pat Helland) 是反可伸縮模式的,JavaEE中的JTA事務可以支持2PC。因為2PC是反模式,盡量不要使用2PC,使用BASE來回避。
BASE思想
BASE模型反ACID模型,完全不同ACID模型,犧牲高一致性,獲得可用性或可靠性:
Basically Available基本可用。支持分區失敗(e.g. sharding碎片劃分數據庫)
Soft state軟狀態 狀態可以有一段時間不同步,異步。
Eventually consistent最終一致,最終數據是一致的就可以了,而不是時時高一致。
BASE思想的主要實現有
1.按功能劃分數據庫
2.sharding碎片
BASE思想主要強調基本的可用性,如果你需要High 可用性,也就是純粹的高性能,那么就要以一致性或容錯性為犧牲,BASE思想的方案在性能上還是有潛力可挖的。
現在NoSQL運動豐富了拓展了BASE思想,可按照具體情況定制特別方案,比如忽視一致性,獲得高可用性等等,NOSQL應該有下面兩個流派:
1. Key-Value存儲,如Amaze Dynamo等,可根據CAP三原則靈活選擇不同傾向的數據庫產品。
2. 領域模型 + 分布式緩存 + 存儲 (Qi4j和NoSQL運動),可根據CAP三原則結合自己項目定制靈活的分布式方案,難度高。
這兩者共同點:都是關系數據庫SQL以外的可選方案,邏輯隨著數據分布,任何模型都可以自己持久化,將數據處理和數據存儲分離,將讀和寫分離,存儲可以是異步或同步,取決于對一致性的要求程度。
不同點:NOSQL之類的Key-Value存儲產品是和關系數據庫頭碰頭的產品BOX,可以適合非Java如PHP RUBY等領域,是一種可以拿來就用的產品,而領域模型 + 分布式緩存 + 存儲是一種復雜的架構解決方案,不是產品,但這種方式更靈活,更應該是架構師必須掌握的。_x000B_
由于業務數據量的爆炸式增長從而導致了存儲成本的不斷上漲,同時加大了存儲管理的難度,目前我們公司大數據架構采用結構化、非結構化數據庫、(Nosql),HDFS分布式文件系統相結合的存儲結構模式進行數據的存儲工作,且存儲結構均采用集群化的方式進行存儲從而保證數據的安全、穩定性、易于擴展、大數據量高性能、靈活的數據模型。
1.系統大致存儲圖為:
2.大數據存儲特點:
2.1易擴展性:NoSQL
數據庫種類繁多,但是一個共同的特點都是去掉關系數據庫的關系型特性。數據之間無關系,這樣就非常容易擴展。也無形之間,在架構的層面上帶來了可擴展的能力。
2.2大數據量,高性能:NoSQL
數據庫都具有非常高的讀寫性能,尤其在大數據量下,同樣表現優秀。這得益于它的無關系性,數據庫的結構簡單。一般MySQL使用 Query Cache,每次表的更新Cache
就失效,是一種大粒度的Cache,在針對web2.0的交互頻繁的應用,Cache性能不高。而NoSQL的 Cache
是記錄級的,是一種細粒度的Cache,所以NoSQL在這個層面上來說就要性能高很多了。
2.3靈活的數據模型:NoSQL
無需事先為要存儲的數據建立字段,隨時可以存儲自定義的數據格式。而
在關系數據庫里,增刪字段是一件非常麻煩的事情。如果是非常大數據量的表,增加字段簡直就是一個噩夢。這點在大數據量的web2.0時代
非結構數據庫的備份:
3.HBase介紹
3.1 HBase架構介紹
3.1.1 Hbase基本組件說明:
3.1.1.1 Client
ü包含訪問HBase的接口,并維護cache來加快對HBase的訪問,比如region的位置信息
3.1.1.2 Master
ü為Region server分配region
ü負責Region server的負載均衡
ü發現失效的Region server并重新分配其上的region
ü管理用戶對table的增刪改查操作
3.1.1.3 Region Server
üRegionserver維護region,處理對這些region的IO請求
üRegionserver負責切分在運行過程中變得過大的region
3.1.1.4 Zookeeper作用
ü通過選舉,保證任何時候,集群中只有一個master,Master與RegionServers 啟動時會向ZooKeeper注冊
ü存貯所有Region的尋址入口
ü實時監控Region server的上線和下線信息。并實時通知給Master
ü存儲HBase的schema和table元數據
ü默認情況下,HBase 管理ZooKeeper 實例,比如, 啟動或者停止ZooKeeper
üZookeeper的引入使得Master不再是單點故障
3.1.1.5 Write-Ahead-Log(WAL)
該機制用于數據的容錯和恢復:
每 個HRegionServer中都有一個HLog對象,HLog是一個實現Write Ahead Log的類,在每次用戶操作寫入MemStore的同時,也會寫一份數據到HLog文件中(HLog文件格式見后續),HLog文件定期會滾動出新的,并 刪除舊的文件(已持久化到StoreFile中的數據)。當HRegionServer意外終止后,HMaster會通過Zookeeper感知 到,HMaster首先會處理遺留的 HLog文件,將其中不同Region的Log數據進行拆分,分別放到相應region的目錄下,然后再將失效的region重新分配,領取 到這些region的HRegionServer在Load Region的過程中,會發現有歷史HLog需要處理,因此會Replay HLog中的數據到MemStore中,然后flush到StoreFiles,完成數據恢復。
3.1.1.6 HBase容錯性
Master容錯:Zookeeper重新選擇一個新的Master
ü無Master過程中,數據讀取仍照常進行;
ü無master過程中,region切分、負載均衡等無法進行;
RegionServer容錯:定時向Zookeeper匯報心跳,如果一旦時間內未出現心跳,Master將該RegionServer上的Region重新分配到其他RegionServer上,失效服務器上“預寫”日志由主服務器進行分割并派送給新的RegionServer
Zookeeper容錯:Zookeeper是一個可靠地服務,一般配置3或5個Zookeeper實例
Region定位流程:
尋找RegionServer
ZooKeeper--> -ROOT-(單Region)--> .META.--> 用戶表
-ROOT-
ü表包含.META.表所在的region列表,該表只會有一個Region;
üZookeeper中記錄了-ROOT-表的location。
.META.
ü表包含所有的用戶空間region列表,以及RegionServer的服務器地址。
3.1.1.7 Hbase使用場景
storing large amounts of data(100s of TBs)
need high write throughput
need efficient random access(key lookups) within large data sets
need to scale gracefully with data
for structured and semi-structured data
don't need fullRDMS capabilities(cross row/cross table transaction, joins,etc.)
大數據量存儲,大數據量高并發操作
需要對數據隨機讀寫操作
讀寫訪問均是非常簡單的操作
3.1.2 Hbase介紹
3.1.2.1 HBase基本概念
RowKey:
是Byte array,是表中每條記錄的“主鍵”,方便快速查找,Rowkey的設計非常重要。
Column Family:
列族,擁有一個名稱(string),包含一個或者多個相關列
Column:
屬于某一個columnfamily,familyName:columnName,每條記錄可動態添加
Version Number:
類型為Long,默認值是系統時間戳,可由用戶自定義
Value(Cell):
Byte array
3.1.2.2 HBase介紹
HBase是一個構建在HDFS上的分布式列存儲系統;
HBase是基于Google BigTable模型開發的,典型的key/value系統;
HBase是Apache Hadoop生態系統中的重要一員,主要用于海量結構化數據存儲;
從邏輯上講,HBase將數據按照表、行和列進行存儲。
與hadoop一樣,Hbase目標主要依靠橫向擴展,通過不斷增加廉價的商用服務器,來增加計算和存儲能力
3.1.3 HBase特點
? 大:一個表可以有數十億行,上百萬列;
? 無模式:每行都有一個可排序的主鍵和任意多的列,列可以根據需要動態的增加,同一張表中不同的行可以有截然不同的列;
? 面向列:面向列(族)的存儲和權限控制,列(族)獨立檢索;
? 稀疏:空(null)列并不占用存儲空間,表可以設計的非常稀疏;
? 數據多版本:每個單元中的數據可以有多個版本,默認情況下版本號自動分配,是單元格插入時的時間戳;
數據類型單一:Hbase中的數據都是字符串,沒有類型。
3.1.5 HBase數據類型
3.1.4 HBase物理模型
每個column family存儲在HDFS上的一個單獨文件中,空值不會被保存。
Key 和 Version number在每個 column family中均有一份;
HBase 為每個值維護了多級索引,即:<key, column family, column name, timestamp>
物理存儲:
1、Table中所有行都按照row key的字典序排列;
2、Table在行的方向上分割為多個Region;
3、Region按大小分割的,每個表開始只有一個region,隨著數據增多,region不斷增大,當增大到一個閥值的時候,region就會等分會兩個新的region,之后會有越來越多的region;
4、Region是Hbase中分布式存儲和負載均衡的最小單元,不同Region分布到不同RegionServer上。
5、Region雖然是分布式存儲的最小單元,但并不是存儲的最小單元。Region由一個或者多個Store組成,每個store保存一個columns family;每個Strore又由一個memStore和0至多個StoreFile組成,StoreFile包含HFile;memStore存儲在 內存中,StoreFile存儲在HDFS上。
3.2 HBase原理
3.3 HBase復制(HBase Relication)
HBase復制是另外一個負載較輕的備份工具。文章《HBase復制概述》有對它的詳細描述。總的來說,賦值被定義為列簇級別,可以工作在后臺并且保證所有的編輯操作在集群復制鏈之間的同步。
復制有三種模式:主->從(master->slave),主<->主(master<->master)和循環(cyclic)。這種方法給你靈活的從任意數據中心獲取數據并且確保它能獲得在其他數據中心的所有副本。在一個數據中心發生災難性故障的情況下,客戶端應用程序可以利用DNS工具,重定向到另外一個備用位置。
復制是一個強大的,容錯的過程。它提供了“最終一致性”,意味著在任何時刻,最近對一個表的編輯可能無法應用到該表的所有副本,但是最終能夠確保一致。
注:對于一個存在的表,你需要通過本文描述的其他方法,手工的拷貝源表到目的表。復制僅僅在你啟動它之后才對新的寫/編輯操作有效。
表2 集群復制架構圖
3.4導出(Export)
HBase的導出工具是一個內置的實用功能,它使數據很容易從hbase表導入HDFS目錄下的SequenceFiles文件。它創造了一個 map reduce任務,通過一系列HBase API來調用集群,獲取指定表格的每一行數據,并且將數據寫入指定的HDFS目錄中。這個工具對集群來講是性能密集的,因為它使用了mapreduce和 HBase 客戶端API。但是它的功能豐富,支持制定版本或日期范圍,支持數據的篩選,從而使增量備份可用。
下面是一個導出命令的簡單例子:
1. hbase org.apache.hadoop.hbase.mapreduce.Export <tablename> <outputdir>
一旦你的表導出了,你就可以復制生成的數據文件到你想存儲的任何地方(比如異地/離線集群存儲)。你可以執行一個遠程的HDFS集群/目錄作為命令的輸出目錄參數,這樣數據將會直接被導出到遠程集群。使用這個方法需要網絡,所以你應該確保到遠程集群的網絡連接是否可靠以及快速。
3.5拷貝表(CopyTable)
拷貝表功能在文章《使用CopyTable在線備份HBase》中有詳細描述,但是這里做了基本的總結。和導出功能類似,拷貝表也使用HBase API創建了一個mapreduce任務,以便從源表讀取數據。不同的地方是拷貝表的輸出是hbase中的另一個表,這個表可以在本地集群,也可以在遠程集群。
一個簡單的例子如下:
1. hbase org.apache.hadoop.hbase.mapreduce.CopyTable --new.name=testCopy test
這個命令將會拷貝名為test的表到集群中的另外一個表testCopy。
請注意,這里有一個明顯的性能開銷,它使用獨立的“puts”操作來逐行的寫入數據到目的表。如果你的表非常大,拷貝表將會導致目標region server上的memstore被填滿,會引起flush操作并最終導致合并操作的產生,會有垃圾收集操作等等。
此外,你必須考慮到在HBase上運行mapreduce任務所帶來的性能影響。對于大型的數據集,這種方法的效果可能不太理想。
3.6 HBase API(比如作為一個java應用)
由于總是這樣使用hadoop,你可以使用公用的api寫自己定制的客戶端應用程序來直接查詢表格。你也可以通過mapreduce任務的批量處理優勢,或者自己設計的其他手段。然而,這個方法需要對hadoop開發以及因此對生產集群帶來的影響有深入的理解。
離線備份原生的HDFS數據(Offline Backup of Raw HDFS Data)
最強力的備份機制,也是破壞性最大的一個。涉及到最大的數據占用空間。你可以干凈的關閉你的HBase集群并且手工的在HDFS上拷貝數據。因為 HBase已經關閉,所以能確保所有的數據已經被持久化到HDFS上的HFile文件中,你也將能獲得一個最準確的數據副本。但是,增量的數據幾乎不能再獲得,你將無法確定哪些數據發生了變化。
同時也需要注意,恢復你的數據將需要一個離線的元數據因為.META.表將包含在修復時可能無效的信息。這種方法需要一個快速的,可信賴的網絡來傳輸異地的數據,如果需要在稍后恢復它的話。
由于這些原因,Cloudera非常不鼓勵在HBase中這種備份方法。
3.7 故障恢復(Disaster Recory)
HBase被設計為一個非常能容忍錯誤的分布式系統,假設硬件失敗很頻繁。在HBase中的故障恢復通常有以下幾種形式:
· 在數據中心級別的災難性故障,需要切換到備份位置;
· 需要恢復由于用戶錯誤或者意外刪除的數據的之前一個拷貝;
· 出于審計目的,恢復實時點數據拷貝的能力
正如其他的故障恢復計劃,業務需要驅動這你如何架構并且投入多少金錢。一旦你確定了你將要選擇的備份方案,恢復將有以下幾種類型:
· 故障轉移到備份集群
· 導入表/恢復快照
· 指向HBase在備份位置的根目錄
如果你的備份策略是這樣的,你復制你的HBase數據在不同數據中心的備份集群,故障轉移將變得簡單,僅需要使用DNS技術,轉移你的應用程序。
請記住,如果你打算允許數據在停運時寫入你的備份集群,那你需要確保在停運結束后,數據可以回到主機群。主<->主或循環的復制架構能自動處理這個過程,但對于一個主從結構來講,你就需要手動進行干預了。
你也可以在故障時通過簡單的修改hbase-site.xml的 hbase.root.dir屬性來更改hbase根目錄,但是這是最不理想的還原選項,因為你復制完數據返回生產集群時,正如之前提到的,可能會發現.META是不同步的。
4. HDFS介紹
4.1 HDFS架構介紹
如上圖所示,HDFS也是按照Master和Slave的結構。分NameNode、SecondaryNameNode、DataNode這幾個角色。
NameNode:是Master節點,是大領導。管理數據塊映射;處理客戶端的讀寫請求;配置副本策略;管理HDFS的名稱空間;
SecondaryNameNode:是一個小弟,分擔大哥namenode的工作量;是NameNode的冷備份;合并fsimage和fsedits然后再發給namenode。
DataNode:Slave節點,奴隸,干活的。負責存儲client發來的數據塊block;執行數據塊的讀寫操作。
熱備份:b是a的熱備份,如果a壞掉。那么b馬上運行代替a的工作。
冷備份:b是a的冷備份,如果a壞掉。那么b不能馬上代替a工作。但是b上存儲a的一些信息,減少a壞掉之后的損失。
fsimage:元數據鏡像文件(文件系統的目錄樹。)
edits:元數據的操作日志(針對文件系統做的修改操作記錄)
namenode內存中存儲的是=fsimage+edits。
SecondaryNameNode負責定時默認1小時,從namenode上,獲取fsimage和edits來進行合并,然后再發送給namenode。減少namenode的工作量。
4.1.1 HDFS介紹
HDFS(Hadoop Distributed File System )Hadoop分布式文件系統。是根據google發表的論文翻版的。論文為GFS(Google File System)Google 文件系統。
4.1.2 HDFS特點
① 保存多個副本,且提供容錯機制,副本丟失或宕機自動恢復。默認存3份。
② 運行在廉價的機器上。
③ 適合大數據的處理。多大?多小?HDFS默認會將文件分割成block,64M為1個block。然后將block按鍵值對存儲在HDFS上,并將鍵值對的映射存到內存中。如果小文件太多,那內存的負擔會很重。
4.2 HDFS原理
4.2.1 寫操作
有一個文件FileA,100M大小。Client將FileA寫入到HDFS上。
HDFS按默認配置。
HDFS分布在三個機架上Rack1,Rack2,Rack3。
a. Client將FileA按64M分塊。分成兩塊,block1和Block2;
b. Client向nameNode發送寫數據請求,如圖藍色虛線①------>。
c. NameNode節點,記錄block信息。并返回可用的DataNode,如粉色虛線②--------->。
Block1: host2,host1,host3
Block2: host7,host8,host4
原理:
NameNode具有RackAware機架感知功能,這個可以配置。
若client為DataNode節點,那存儲block時,規則為:副本1,同client的節點上;副本2,不同機架節點上;副本3,同第二個副本機架的另一個節點上;其他副本隨機挑選。
若client不為DataNode節點,那存儲block時,規則為:副本1,隨機選擇一個節點上;副本2,不同副本1,機架上;副本3,同副本2相同的另一個節點上;其他副本隨機挑選。
d. client向DataNode發送block1;發送過程是以流式寫入。
流式寫入過程,
1>將64M的block1按64k的package劃分;
2>然后將第一個package發送給host2;
3>host2接收完后,將第一個package發送給host1,同時client想host2發送第二個package;
4>host1接收完第一個package后,發送給host3,同時接收host2發來的第二個package。
5>以此類推,如圖紅線實線所示,直到將block1發送完畢。
6>host2,host1,host3向NameNode,host2向Client發送通知,說“消息發送完了”。如圖粉紅顏色實線所示。
7>client收到host2發來的消息后,向namenode發送消息,說我寫完了。這樣就真完成了。如圖黃色粗實線
8>發送完block1后,再向host7,host8,host4發送block2,如圖藍色實線所示。
9>發送完block2后,host7,host8,host4向NameNode,host7向Client發送通知,如圖淺綠色實線所示。
10>client向NameNode發送消息,說我寫完了,如圖黃色粗實線。。。這樣就完畢了。
分析,通過寫過程,我們可以了解到:
①寫1T文件,我們需要3T的存儲,3T的網絡流量貸款。
②在執行讀或寫的過程中,NameNode和DataNode通過HeartBeat進行保存通信,確定DataNode活著。如果發現DataNode死掉了,就將死掉的DataNode上的數據,放到其他節點去。讀取時,要讀其他節點去。
③掛掉一個節點,沒關系,還有其他節點可以備份;甚至,掛掉某一個機架,也沒關系;其他機架上,也有備份。
4.2.2讀操作
讀操作就簡單一些了,如圖所示,client要從datanode上,讀取FileA。而FileA由block1和block2組成。
那么,讀操作流程為:
a. client向namenode發送讀請求。
b. namenode查看Metadata信息,返回fileA的block的位置。
block1:host2,host1,host3
block2:host7,host8,host4
c. block的位置是有先后順序的,先讀block1,再讀block2。而且block1去host2上讀取;然后block2,去host7上讀取;
上面例子中,client位于機架外,那么如果client位于機架內某個DataNode上,例如,client是host6。那么讀取的時候,遵循的規律是:
優選讀取本機架上的數據。
4.2.3 HDFS常用命令
hadoop fs -ls /
hadoop fs -lsr
hadoop fs -mkdir /user/hadoop
hadoop fs -put a.txt /user/hadoop/
hadoop fs -get /user/hadoop/a.txt /
hadoop fs -cp src dst
hadoop fs -mv src dst
hadoop fs -cat /user/hadoop/a.txt
hadoop fs -rm /user/hadoop/a.txt
hadoop fs -rmr /user/hadoop/a.txt
hadoop fs -text /user/hadoop/a.txt
hadoop fs -copyFromLocal localsrc dst 與hadoop fs -put功能類似。
hadoop fs -moveFromLocal localsrc dst 將本地文件上傳到hdfs,同時刪除本地文件。
hadoop dfsadmin -report
hadoop dfsadmin -safemode enter | leave | get | wait
hadoop dfsadmin -setBalancerBandwidth 1000
hadoop fsck
start-balancer.sh
5 HDFS與HBase進行比較
? 兩者都具有良好的容錯性和擴展性,都可以擴展到成百上千個節點;
? HDFS適合批處理場景
? 不支持數據隨機查找
? 不適合增量數據處理
? 不支持數據更新