目錄 php
大數據掃盲 1 html
0.2. 大數據處理技術架構 2 chrome
1. 數據分區與路由 2 數據庫
1.1. 二級映射機制 3 json
1.1.2. 虛擬桶(virtual bucket) 3 緩存
1.1.3. 一致性哈希(consistent hashing) 4 安全
1.2. 一致性 4 服務器
大數據能夠用4V來描述。
數據源,包括結構化數據、半結構化數據、非結構化數據。數據類型多樣化。
結構化數據指的是數據描述和數據自己是分離的,存放在關係數據庫中。
半結構化數據指的是數據的描述和數據自己摻雜在一塊兒,好比郵件、xml文件、json格式、HTML頁面。通常使用樹、圖結構存儲。
非結構化數據指的是沒有描述信息,好比音視頻文件、圖像等。沒有固定的存儲模型。
數據抽取與集成,指的是從原始的數據源中把數據提取出來,存放到必定的存儲模型中,如HDFS、HBase、Redis等。
數據分析,指的是進行數據挖掘、機器學習、統計分析等,能夠獲取更加深層次的信息。
數據展現,指的是數據的顯示,包括數據可視化、人機交互等。
傳統的數據庫中,數據量大了、運行速度慢了之後,能夠經過提升單機的硬件水平來提升存儲量或者查詢速度,這叫作縱向擴展。缺點是成本高,收效愈來愈弱。
在大數據領域,通常是經過增長服務器來進行橫向擴展。數據被分散存儲在不少臺服務器上,數據的查詢經過對分散在不少臺機器上面的數據查詢進行彙總獲得。
海量的數據按照什麼規則分配到這麼多服務器上?如何快速的查詢位於某臺服務器上的數據?當添加服務器或者下架服務器的時候,怎麼辦?
數據分配到服務器的方式稱做數據分區。
快速查詢位於服務器集羣上的某條數據,稱做數據路由。
當數據經過分區存儲到集羣后,會怎加數據訪問失敗的機率,這稱做數據的可靠性。最簡單的方式是使用副本機制。工業標準是副本數量爲3。
副本機制,能夠提升數據的安全性,能夠經過併發讀提升併發讀取效率,能夠經過查詢最近位置提升單次讀取效率。
副本機制,帶來一個問題,就是寫操做時,如何保持副本數據的一致性。
實現數據的分區與路由的方式,通常是二級映射機制。
其中,key是劃分到哪些分區上的?有兩種算法,一是哈希分區算法,一是範圍分區算法。
哈希分區是把某個key根據哈希算法計算的結果,放到指定的分區中,適合"鍵查詢"。
範圍分區是把一段聯繫的key放到指定的分區中,適合"範圍查詢"。
假設有k機器,把全部的機器從0到k-1編號,使用哈希函數hash(key) mod K 就能夠把全部數據存放到K臺機器中。取得時候,也按照哈希函數取值便可。
優勢是實現簡單。缺點是缺少靈活性,好比增長或者減小機器時。
在key和機器之間,引入中間層,稱做"虛擬桶",實現二級映射,就能夠完美解決機器擴展性的問題。如數據庫CouchBase。
哈希算法的致命缺陷是沒有實現二級映射。
在分佈式存儲中,哈希算法在增刪機器的場景下效率很是低,有解決方案嗎?這就是一致性哈希算法。
Consistency強一致性、availability可用性、partition tolerance分區容錯性,在一個大規模的分佈式服務系統中不可能同時存在。
C指的是更新操做成功並返回客戶端完成後,分佈式的全部節點在同一時間的數據徹底一致
A指的是讀和寫操做都能成功
P指的是節點宕機不影響服務的運行。
1. 假設DB的更新操做是同時寫北京和廣州的DB都成功才返回成功
在沒有出現網絡故障的時候,知足CA原則,C 即個人任何一個寫入,更新操做成功並返回客戶端完成後,分佈式的全部節點在同一時間的數據徹底一致, A 即個人讀寫操做都可以成功,可是當出現網絡故障時,我不能同時保證CA,即P條件沒法知足
2. 假設DB的更新操做是隻寫本地機房成功就返回,經過binlog/oplog回放方式同步至側邊機房
這種操做保證了在出現網絡故障時,雙邊機房都是能夠提供服務的,且讀寫操做都能成功,意味着他知足了AP ,可是它不知足C,由於更新操做返回成功後,雙邊機房的DB看到的數據會存在短暫不一致,且在網絡故障時,不一致的時間差會很大(僅能保證最終一致性)
3. 假設DB的更新操做是同時寫北京和廣州的DB都成功才返回成功且網絡故障時提供降級服務
降級服務,如中止寫入,只提供讀取功能,這樣能保證數據是一致的,且網絡故障時能提供服務,知足CP原則,可是他沒法知足A可用性原則
選擇權衡
經過上面的例子,咱們得知,咱們永遠沒法同時獲得CAP這3個特性,那麼咱們怎麼來權衡選擇呢?
選擇的關鍵點取決於業務場景
對於大多數互聯網應用來講(如網易門戶),由於機器數量龐大,部署節點分散,網絡故障是常態,可用性是必須須要保證的,因此只有設置一致性來保證服務的AP,一般常見的高可用服務吹噓5個9 6個9服務SLA穩定性就本都是放棄C選擇AP
對於須要確保強一致性的場景,如銀行,一般會權衡CA和CP模型,CA模型網絡故障時徹底不可用,CP模型具有部分可用性,實際的選擇須要經過業務場景來權衡(並非全部狀況CP都好於CA,只能查看信息不能更新信息有時候從產品層面還不如直接拒絕服務)
Atomicity原子性、consistency一致性、isolation獨立性、durability持久性
關係數據庫採用這套模型,保證高可靠和強一致性。
Basically availible基本可用、soft state軟狀態、eventual consistency最終一致性
Base是經過犧牲一致性來得到高可用。目前的大部分NoSQL數據庫都是base理論。
數學中的冪等指的是如max(x,y)=x、and操做等等。
分佈式系統中的冪等性指的是不管多少次調用,結果都是相同的。
由於在分佈式系統中,有可能網絡中斷,形成通信失敗,冪等性很是重要。Zookeeper就是冪等性系統。
略
假設服務器A是一個反垃圾郵件服務器,A維護了一個可疑IP列表,列表中包含了大量的可疑的 IP地址。服務器B是另外一個反垃圾郵件服務器,B也維護了一個可疑IP列表,列表中包含了大量的可疑的IP地址。兩臺服務器只能經過互聯網通訊。有一天, 服務器A須要確認本身的列表和服務器B的列表的類似度(即二者包含的相同的IP地址佔全部IP地址的比例)。
首先,讓咱們來看看什麼是Bloom Filter吧。初始狀態時,Bloom Filter是一個包含m位的位數組,每一位都置爲0。
爲了表達S={x1, x2,…,xn}這樣一個n個元素的集合,Bloom Filter使用k個相互獨立的哈希函數(Hash Function),它們分別將集合中的每一個元素映射到{1,…,m}的範圍中。對任意一個元素x,第i個哈希函數映射的位置hi(x)就會被置爲 1(1≤i≤k)。注意,若是一個位置屢次被置爲1,那麼只有第一次會起做用,後面幾回將沒有任何效果。以下圖所示,咱們能夠全部的元素xk映射到位數組 中。而m位的位數組就能夠做爲描述全部元素的簡化版。
在判斷y是否屬於這個集合時,咱們對y應用k次哈希函數,若是全部hi(y)的位置都是1(1≤i≤k),那麼咱們就認爲y是集合中的元素,不然就認爲y不是集合中的元素。下圖中y1就不是集合中的元素。y2或者屬於這個集合,或者恰好是一個false positive。
m的單位是bit,而n則是以元素個數爲單位(準確的說是不一樣元素的個數,能夠是字符串或者複製對象)。因此使用bloom filter內存上一般都是節省的。
具備良好的時間和空間效率,尤爲是空間效率極高。對於判斷元素是否屬於集合很是高效。好比google chrome使用它進行惡意url判斷,網絡爬蟲使用它檢查是否爬過特定的url,緩存數據等。如cassandra、hbase都採用了。
對一棵查找樹(search tree)進行查詢/新增/刪除 等動做, 所花的時間與樹的高度h 成比例, 並不與樹的容量 n 成比例。若是可讓樹維持矮矮胖胖的好身材, 也就是讓h維持在O(lg n)左右, 完成上述工做就很省時間。可以一直維持好身材, 不因新增刪除而長歪的搜尋樹, 叫作balanced search tree(平衡樹)。
構造平衡樹,很是複雜。可是構造跳錶很是簡單,並且功能相同、效率相近。
跳錶是一種隨機化的數據結構,目前開源軟件 Redis 和 LevelDB 都有用到它,
它的效率和紅黑樹以及 AVL 樹不相上下,但跳錶的原理至關簡單,只要你能熟練操做鏈表,
就能輕鬆實現一個 SkipList。
有序表的搜索
考慮一個有序表:
從該有序表中搜索元素 < 23, 43, 59 > ,須要比較的次數分別爲 < 2, 4, 6 >,總共比較的次數
爲 2 + 4 + 6 = 12 次。有沒有優化的算法嗎? 鏈表是有序的,但不能使用二分查找。相似二叉
搜索樹,咱們把一些節點提取出來,做爲索引。獲得以下結構:
這裏咱們把 < 14, 34, 50, 72 > 提取出來做爲一級索引,這樣搜索的時候就能夠減小比較次數了。
咱們還能夠再從一級索引提取一些元素出來,做爲二級索引,變成以下結構:
這裏元素很少,體現不出優點,若是元素足夠多,這種索引結構就能體現出優點來了。
這基本上就是跳錶的核心思想,其實也是一種經過"空間來換取時間"的一個算法,經過在每一個節點中增長了向前的指針,從而提高查找的效率。
跳錶
下面的結構是就是跳錶:
其中 -1 表示 INT_MIN, 鏈表的最小值,1 表示 INT_MAX,鏈表的最大值。
跳錶具備以下性質:
(1) 由不少層結構組成
(2) 每一層都是一個有序的鏈表
(3) 最底層(Level 1)的鏈表包含全部元素
(4) 若是一個元素出如今 Level i 的鏈表中,則它在 Level i 之下的鏈表也都會出現。
(5) 每一個節點包含兩個指針,一個指向同一鏈表中的下一個元素,一個指向下面一層的元素。
跳錶的搜索
LSM樹的本質是將大量的隨機寫操做轉換成批量的序列寫,這樣能夠極大的提高磁盤數據寫入速度,因此LSM樹很是適合對寫操做效率有高要求的應用場景。可是讀效率有些低,能夠經過bloom filter或者緩存優化讀性能。
LSM(Log Structured Merge Trees)數據組織方式被應用於多種數據庫,如LevelDB、HBase、Cassandra等,下面咱們從爲何使用LSM、LSM的實現思路兩方面介紹這種存儲組織結構,完成對LSM的初步瞭解。
存儲背景回顧
LSM相較B+樹或其餘索引存儲實現方式,提供了更好的寫性能。究其緣由,咱們先回顧磁盤相關的一點背景知識。
順序操做磁盤的性能,較隨機讀寫磁盤的性能高不少,咱們實現數據庫時,也是圍繞磁盤的這點特性進行設計與優化。若是讓寫性能最優,最佳的實現方式就是日誌型(Log/Journal)數據庫,其以追加(Append)的方式寫磁盤文件。
有得即有舍,萬事萬物存在權衡,帶來最優寫性能的同時,單純的日誌數據庫讀性能不好,爲找到一條數據,不得不遍歷數據記錄,要實現範圍查詢(range)幾乎不可能。爲優化日誌型數據庫的讀性能,實際應用中一般結合如下幾種優化措施:
二分查找(Binary Search): 在一個數據文件中使用二分查找加速數據查找
哈希(Hash): 寫入時經過哈希函數將數據放入不一樣的桶中,讀取時經過哈希索引直接讀取
B+樹: 使用B+樹做爲數據組織存儲形式,保持數據穩定有序
外部索引文件: 除數據自己按日誌形式存儲外,另對其單獨創建索引加速讀取,如以前介紹的《一種Bitcask存儲模型的實現》
以上措施都很大程度提高了讀性能(如二分查找將時間複雜度提高至O(log(N))),但相應寫性能也有折損,第一寫數據時須要維護索引,這視索引 的實現方式,最差狀況下可能涉及隨機的IO操做;第二若是用B+樹等結構組織數據,寫入涉及兩次IO操做,先要將數據讀出來再寫入。
LSM存儲結構
LSM存儲實現思路與以上四種措施不太相同,其將隨機寫轉化爲順序寫,儘可能保持日誌型數據庫的寫性能優點,並提供相對較好的讀性能。具體實現方式以下:
1. 當有寫操做(或update操做)時,寫入位於內存的buffer,內存中經過某種數據結構(如skiplist)保持key有序
2. 通常的實現也會將數據追加寫到磁盤Log文件,以備必要時恢復
3. 內存中的數據定時或按固定大小地刷到磁盤,更新操做只不斷地寫到內存,並不更新磁盤上已有文件
4. 隨着愈來愈多寫操做,磁盤上積累的文件也愈來愈多,這些文件不可寫且有序
5. 定時對文件進行合併操做(compaction),消除冗餘數據,減小文件數量
以上過程用圖表示以下:
LSM存儲結構的寫操做,只需更新內存,內存中的數據以塊數據形式刷到磁盤,是順序的IO操做,另外磁盤文件按期的合併操做,也將帶來磁盤IO操做。
LSM存儲結構的讀操做,先從內存數據開始訪問,若是在內存中訪問不到,再順序從一個個磁盤文件中查找,因爲文件自己有序,而且按期的合併減小了磁盤文件個數,於是查找過程相對較快速。
合併操做是LSM實現中重要的一環,LevelDB、Cassandra中,使用基於層級的合併方式(Levelled compaction),生成第N層的時候,對N-1層的數據進行排序,使得每層內的數據文件之間都是有序的,但最高層除外,由於該層不斷有數據文件產 生,於是只是數據文件內部按key有序。
除最高層外,其餘層文件間數據有序,這也加速了讀過程,由於一個key對應的value只存在一個文件中。假設總共有N層,每層最多K個數據文件,最差的狀況下,讀操做先遍歷K個文件,再遍歷每層,共須要K+(N-1)次讀盤操做。
總結
LSM存儲框架實現的思路較簡單,其先在內存中保存數據,再定時刷到磁盤,實現順序IO操做,經過按期合併文件減小數據冗餘;文件有序,保證讀取操做相對快速。
咱們須要結合實際的業務場景選擇合適的存儲實現,不存在萬金油式的通用存儲框架。LSM適用於寫多、讀相對少(或較多讀取最新寫入的數據,該部分數據存在內存中,不須要磁盤IO操做)的業務場景。
Merkle哈希樹校驗方式爲咱們提供了一個很好的思路,它試圖從校驗信息獲取及實際校驗過程兩個方面來改善上述問題。先說說什麼是哈希樹,以最簡 單的二叉方式爲例,以下圖所示,設某文件共13個數據塊,咱們能夠將其padding到16(2的整數次方)個塊(注意,padding的空白塊僅用於輔 助校驗,而無需看成數據進行實際傳輸),每一個塊均對應一個SHA1校驗值,而後再對它們進行反覆的兩兩哈希,直到得出一個惟一的根哈希值爲止(root hash, H0),這一計算過程便構成了一棵二元的Merkle哈希樹,樹中最底層的葉子節點(H15~H30)對應着數據塊的實際哈希值,而那些內部節點 (H1~H14)咱們則能夠將其稱爲"路徑哈希值",它們構成了實際塊哈希值與根哈希值H0之間的"校驗路徑",好比,數據塊8所對應的實際哈希值爲 H23,則有:SHA1(((SHA1(SHA1(H23,H24),H12),H6),H1)應該等於H0。固然,咱們也能夠進一步採用n元哈希樹來進 行上述校驗過程,其過程是相似的。
採用Merkle哈希樹校驗方式可以極大地減少.torrent文件的尺寸,這是由於,一旦採用這種方式來校驗數據塊,那麼便沒有必要 在.torrent文件中保存全部數據塊的校驗值了,其中僅需保存一個20字節的SHA1哈希值便可,即整個下載文件的根哈希值H0。想象一下一個3、 4GB的文件,其對應.torrent文件卻只有100-200字節的樣子?
一般設計是在各個日誌服務器安裝代理,經過代理收集數據。
數據總線的做用是可以造成數據變化通知通道,當集中存儲的數據源中的數據發生變化時,能儘快通知對數據變化敏感的相關應用或者系統構建,使得他們能儘快捕獲這種數據變化。
近乎實時的數據擴散,如linkedIn的databus。
sqoop
在集羣硬件上抽象出一個功能獨立的集羣資源管理系統。把全部資源當成一個總體,並對其餘全部計算任務提供統一的資源管理與調度框架和接口。計算任務按需申請資源、釋放資源。
好處:
集羣總體資源利用率高;
可增長數據共享能力;
支持多類型計算框架和多版本計算模型。
核心包含三部分:資源組織模型、調度策略、任務組織模型。
設計中,一般有節點管理器,負責收集本節點的資源使用狀況,彙報給資源收集器。並對分配給本節點的任務放入容器中執行。通用調度器包括資源收集器、資源池、任務池、調度策略。資源收集器負責接收各個節點管理器提交的各節點使用狀況,並更新到資源池中。資源池維護者本集羣最新的可用資源。任務池存放着待執行的各類任務。調度策略負責把任務取出分配可用的資源去執行任務。調度策略一般有FIFO、公平調度、能力調度等。
數據局部性,包括節點局部性優先、機架局部性優先、全局局部性優先。
搶佔式調度、非搶佔式調度,前者用於優先級調度,後者用於公平調度。
資源分配粒度,包括全分或不分式、增量知足式、資源儲備式。資源分配可能出現任務餓死、死鎖問題。
資源隔離方面一般採用容器技術,LXC是一種輕量級的內核虛擬化技術,LXC依賴於Linux內核的cgroups子系統。
典型的案例包括Mesos和Yarn。
序列化與RPC主要用於網絡中不一樣節點的進程直接的交互。
許多分佈式系統都會在進程間進行信息交換。RPC就是這種技術。當A調用B進程時,A進程掛起,把參數傳給B進程,B進程執行後把結果傳給A進程。B進程結束,A進程繼續執行。
數據序列化是爲了保證高效的數據傳輸的,通常採用json或者xml格式,也有采用專門協議的。
常見的框架包括protocol buffer、thrift、avro。
消息隊列主要用於大規模分佈式系統中,用於解除相互之間的功能耦合,這樣能夠減輕各個子系統之間的依賴,使得各個子系統能夠獨立演進、維護或者重用。這裏的消息指的是數據傳輸的基本單位,能夠是簡單的字符串,也能夠是複雜的對象。
常見的框架有ActiveMQ、ZeroMQ、RabiitMQ、Kafka等。
Gossip協議。應用於cassandra、bittorrent、s3等。還能夠用於維護貯備數據的最終一致性以及負載均衡等領域。