日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

一文读懂NoSQL的模式 | 时光机

發布時間:2024/9/27 数据库 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一文读懂NoSQL的模式 | 时光机 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

戳藍字“CSDN云計算”關注我們哦!

時光機:搭載這部時光機,帶您回顧《程序員》大量優秀文章,重溫經典技術干貨,我們發現硬核技術永不過時,對于get要點、solve難題、提高自我,仍有非凡意義。

作者:Richy?Ho,一名軟件架構師,熱衷于分布式及并行計算、機器學習和數據挖掘、SaaS和云計算。先后在Cisco、eBay、Adobe等公司工作。博客為horicky.blogspot.com。

?


導讀

過去,一些用于存儲大規模數據的數據存儲機制逐漸成形,它們與RDBMS模型相去甚遠,被統稱為NoSQL。提煉出各種NoSQL方案背后共通的技術原理,有助于更深刻地理解它們對應用程序設計的內在影響。

過去,? 儲大規模數據的數據存儲機制逐漸成形。這些存儲方案與RDBMS模型相去甚遠,被統稱為NoSQL。其中引人注目的主要角色有:

●?Google BigTable, HBase, Hypertable

Amazon Dynamo, Voldemort, Cassendra, Riak

Redis

CouchDB, MongoDB

上面列舉的方案具有這樣一些共同的特點:

?鍵/值存儲;

?系統運行在數量巨大的普通機器上;

?數經過分區和復制,散布在大量的機器上;

放松了對數據一致性的約束。(因為CAP理論證明,一致性、可用性和分布不可能三者兼得。)本文意在提煉出以上方案背后共通的技術原理,以圖更深刻地理解它們對應用程序設計的內在影響。

?

API模型

?

底層的數據模型可以看作一個巨大的Hashtable(鍵/值存儲)。訪問Hashtable的API基本形式如下:get(key):給定一個鍵,取得對應的值。put(key,?value):新建一個鍵/值對,或者更新給定的鍵對應的值。delete(key):移除一個鍵及其對應的值。

?

通過更高級的API,還可以在服務器環境中執行用戶定義的函數。execute(key,?operation,?parameters):(通過給定的鍵)對特定的值調用某操作,該值可以具有特殊的數據結構(如List、Set、Map……)。mapreduce(keyList,?mapFunc,?reduceFunc):對給定范圍的鍵調用Map/Reduce函數。

?

機器布局

?

整套硬件設施由大量(數百臺、數千臺……)便宜的、普通的、不可靠的機器通過網絡連接而成。每臺機器稱為一個物理節點(PN)。每個PN上的軟件配置是相同的,但CPU數量、內存、磁盤等硬件能力可能不同。在每個PN上,依據其硬件能力,運行著數量不等的虛擬節點(VN)。

?

數據分區

?

(一致性散列)由于整個散列表分散在許多VN上,我們需要找一種方法將每個鍵映射到相應的VN。其中一種辦法是用以下式子確定分區位置:分區?=?鍵?mod總VN數量。這種方案的劣勢在于當VN數量變化的時候,現有鍵的所有權(即位于哪個VN上)會發生極大的變化,全部數據都要重新分配到所有VN。因此多數大規模的存儲都采用一種“一致性散列”的技巧去最小化所有權變更的數量。

?

在?一?致?性?散?列?方?案?中?,?鍵?空間是有限的,且落在一個圓周上。虛擬節點的ID也從同一個鍵空間中分配。對于任意鍵,如果從該鍵開始,沿著圓周順時針走,遇到的第一個虛擬節點就是它所屬的節點。


如果某個節點崩潰了,它所屬的所有鍵都被移交到順時針方向的相鄰節點。因此,鍵的重新分配只發生在崩潰節點的鄰居身上,其他節點仍然保留原有鍵不變。

?


數據復制

?

為了用單個來說并不可靠的資源提供更高的可靠性,我們需要復制數據分區。


復制(Replication)不僅提高了數據的整體可靠性,還由于將工作負載分散到多個副本(Replica)而對性能有所幫助。


只?讀?請?求?可?以?分?發?到?任?意?的副本,而更新請求的處理則較為困難,我們必須小心地協調各副本的更新。

?

成員變更

?

請注意虛擬節點可在任意時刻加入或離開網絡,而不影響這個環的運作。


當新節點加入到網絡


1.新加入的節點公告自身存在,將ID告知若干重要節點(或者簡單地廣播到所有節點)。

2.左右兩側的相鄰節點調整鍵的所有權以及副本成員信息。這步驟通常是同步完成的。

3.新加入的節點開始從它的相鄰節點并行、異步地批量復制數據。

4.副本成員的變更信息異步地傳播到其他節點。

注意其他節點可能尚未更新其副本成員信息,因而繼續向舊的節點轉發請求。而因為舊節點(即新加入節點的鄰居)已經掌握新節點的信息(第2步),它們會將請求轉發給新加節點。

?

另一方面,新加節點可能還處于下載數據的狀態,尚不能提供服務。我們用“矢量時鐘”(見后文)去確定新加節點是否已準備好處理請求,否則客戶可以聯系其他副本成員。

?

當現有節點離開網絡(比如當節點崩潰的時候)

?

1.崩潰的節點不再響應Gossip消息,因此它的鄰居發現這一情況。

2.鄰居更新成員信息,并異步地復制數據。

?


?節點崩潰


我們尚未提及虛擬節點如何映射到物理節點。實際的方案有很多,主要目標是不讓相同副本的各個虛擬節點落在同一個物理節點上。其中一種簡單的方案是隨機地將虛擬節點分配到物理節點,但增加一重檢查,保證物理節點上不存在擁有相同鍵范圍的副本。

?

請注意,由于機器崩潰發生在物理節點的層次,意味著上面運行的許多虛擬節點一同崩潰。當這種情況發生的時候,(多個虛擬節點的)負載由很多臺物理機器分擔。因此由于物理節點崩潰而增加的負載被均勻地均衡掉了。

?

客戶端的一致性

?

當我們擁有同一數據的多份副本,就有必要操心如何同步它們,才能使得在客戶端看來,數據是一致的。有很多種客戶端一致性模型:


1.嚴格一致性:語義上相當于只存在一份數據副本。任何更新看上去

都是即時發生的。

2.“讀己之所寫”一致性:客戶端可立即看到自己所作的更新(且客戶端可在不同請求之間切換服務器),但不能立即看到其他客戶端所作的更新。

3.會話(Session)一致性:對于客戶端在同一會話作用域中發起的請求(通常綁定到同一臺服務器),提供“讀己之所寫”一致性。

4.單調讀一致性:保證時間上的單調性,保證客戶端在未來的請求中,只會讀到比當前更為新的數據。

5.最終一致性:這是最弱的一種保證。在更新的過程中,客戶端將看到一幅不一致的視圖。當并發訪問同一數據幾率非常小的時候,此模型效果良好。

?

客戶端需要等待一段時間才能看到自己先前所作的更新。取決于采用何種一致性模型,需要安排兩種機制:客戶端請求如何分發到副本。副本如何傳播及執行更新。圍繞著如何實現這兩方面,出現了許多模型,各有不同的權衡取舍。

?

主從(或單主)模型

?

在此模型下,每個數據分區都有一個主節點和多個從節點。所有更新請求都必須發給主節點,主節點執行更新后再異步地傳播給從節點。如果主節點在將更新傳播給任何從節點之前發生崩潰,就會出現一個丟失數據的時間窗口。因此有的系統會選擇同步等待,到更新傳播到至少一個從節點為止。

?

如果客戶端能容忍某種程度的舊數據,讀請求可以分發到任何副本。負載因此可以分散到多個副本上。如果對于某些數據,客戶端不能容忍取得非最新的數據,那就必須向主節點請求。


請注意此模型并不意味著某個物理節點扮演主節點的角色。主從關系發生在虛擬節點的層次。每個物理節點上,既有充當某分區主節點的虛擬節點,也有扮演其他分區從節點的虛擬節點。因此,寫負載也被分散到不同的物理節點上,只不過這是由于分區的結果而非復制的結果。當一個物理節點崩潰時,將會失去特定分區的主節點。此時一般將更新最及時的從節點選為新的主節點。當應用的讀/寫比很高的時候,主從模型效果顯著;當更新涉及的鍵范圍分布均勻的時候,它的效果也很好。因為這些因素,大多數數據復制方案都選擇了主從模型。

?

更新由主節點傳播到從節點有兩種方式:傳狀態和傳操作。如果是傳狀態,主節點將它的最新狀態傳遞給從節點,然后從節點用得到的最新狀態替換掉自己的當前狀態。如果是傳操作,主節點傳遞一系列操作給從節點,然后從節點對自己的本地狀態執行操作。傳狀態模型更能抵御消息丟失的情況,因為只要后續的更新消息能正確抵達,副本仍然能成功更新到最新的狀態。

?

即使在傳狀態模型里,我們也不希望發送完整的對象給其他副本,因為通常修改的只是對象的一小部分。發送對象未變的部分等于浪費帶寬。我們需要一種機制去檢查并發送更新的部分。常見的做法是將對象打散成小塊,并且計算出對象中各小塊的一棵散列樹。于是副本通過比較各自的散列樹,就能知道對象中的哪些小塊改動過了,只發送改動過的小塊即可。

?

一般來說,傳操作模型需要通過網絡發送的數據量較少。然而傳操作模型需要一種可靠的消息機制去保證消息的傳遞順序。

?

多主(或無主)模型


如果某些鍵范圍存在熱點,寫請求比較密集,主從模型沒辦法很好地將負載均勻地分散掉。多主模型允許將更新請求發送給任何副本(可能稱之為無主模型更合適)。如果任意客戶端可向任意服務器發出任意請求,那么我們如何同步狀態,才能保持客戶端的一致性,同時使所有副本最終都能達到相同的狀態?下文將介紹幾種辦法。

?

基于多數決的兩段式提交

?

為了實現“嚴格一致性”,我們可以采用傳統的兩段式提交(2PC)協議。假設某數據有N個副本。當更新數據的時候,有一個“預備”階段,由協調者詢問所有副本,是否已準備好執行各個更新。然后每個副本將數據寫入日志文件,成功后通知協調者。收到所有副本的成功消息之后,協調者發起第二階段——“提交”階段,要求所有副本都完成提交,此時每個副本寫入另一條日志條目確認更新。請注意這里存在一些可伸縮性的問題,因為協調者需要“同步地”等待很多輪網絡消息來回,還要等待磁盤I/O完成。

?

另一方面,如果某個副本崩潰了,更新將會失敗。當副本的數量越多,其中之一發生問題的幾率也越大。因此,數據復制反而損害了系統的可用性。所以傳統的2PC在高吞吐量的事務系統中間并不流行。基?于?q?u?o?r?u?m?的?2?P?C?(?如PAXOS)效率更高一些。在此模型中,協調者只需要同步更新W個副本(而非全部N個副本)。

?

協調者仍舊寫入全部N個副本,但只等待其中任意W個副本確認寫入成功。站在概率的角度看,這種做法具有更高的效率。然而,由于并非全部副本都完成了更新,我們在讀取數據的時候需要小心地保證讀到的節點中至少有一個是成功更新過的。

?

當讀取數據的時候,我們需要讀取R個副本,并返回其中時間戳最新的一個結果。為了保證“嚴格一致性”,只要保證讀的集合與寫的集合有重疊即可,也就是W?+?R?>?N。你可能也想到了,基于多數決的2PC可以看作是2PC協議的一般化推廣,傳統的2PC是當W?=?N和R?=?1時的特例。一般化之后的模型使我們可以根據讀寫負載的比率,權衡選擇不同的W和R。如果用戶不能承受選取足夠大的W和R,即當W?+?R?<=?N的時候,那么客戶端的一致性模型就要放寬到較弱的類型。

?

如果客戶端可以容忍較寬松的一致性模型,那么我們沒必要采用上述的2PC提交或者基于多數決的協議。后文將介紹一種傳言(Gossip)模型,通過異步的傳言消息交換傳播更新,使所有副本最終都達到最新的狀態。

?

矢量時鐘

?

矢量時鐘是一種時間戳機制,透過它我們可以推導更新之間的因果關系。首先,每個副本都持有矢量時鐘。假設副本i的時鐘是Vi。Vi[i]是副本根據特定規則更新其矢量時鐘之后的邏輯時鐘。


當副本i執行了一則內部操作,副本i的時鐘加一。當副本i向副本j發送一則消息,副本i首先把自己的時鐘Vi[i]加一,并將自己的矢量時鐘Vi附加到消息中發送出去。當副本j收到來自副本i的消息,它首先自增其時鐘Vj[j],然后合并其時鐘及消息所附的時鐘Vm。即Vj[k]?=?max(Vj[k],?Vm[k])。

?


于是可定義偏序關系,Vi?>?Vj,當且僅當對于所有的k,V?i?[?k?]?>?=?Vj[k]。根據這樣的偏序關系,我們就可以推導出更新之間的因果關系。背后的原理是這樣的:內部操作的效果可在同一節點上立即看到。

?

接收到消息之后,接收節點得知發送節點在消息發送之時的情況。情況不僅包括了發送節點上發生的事情,還包括了發送節點所知的所有其他節點上發生的事情。換言之,Vi[i]反映了節點i上發生最后一次內部操作的時間。Vi[k]?=?6意味著副本i已經知道副本k在它的邏輯時鐘6的時刻的情況。請注意這里是在一種抽象的意義上使用“情況(situation)”一詞。取決于消息中傳遞何種信息,“情況”有不同的具體含義。情況的具體含義會影響如何增加矢量時鐘。下文介紹的“傳狀態模型”和“傳操作模型”在消息中傳遞的信息不一樣,它們矢量時鐘如何增加,也因此不同。

?

由于狀態總是從副本流向客戶端,絕不會反過來,所以客戶端不占矢量時鐘的條目。矢量時鐘里每個副本占一條。不過,客戶端可以持有它最后聯系的副本的矢量時鐘,這對于實現我們先前討論的客戶端一致性甚為關鍵。例如,為了支持單調讀一致性,副本可以保證附在數據上的矢量時鐘大于客戶端在查詢時提交的矢量時鐘。

?

傳言(傳狀態模型)

?

在傳狀態模型里,每個副本都維護著一個矢量時鐘和一個狀態的版本樹,版本樹中的狀態無法(通過比較矢量時鐘)得出狀態之間的“大于”或“小于”關系。換言之,狀態版本樹包含了所有存在沖突的更新。


在查詢的時候,客戶端將它的矢量時鐘一并提交,副本將狀態樹中早于客戶端時鐘的子集發回給客戶端(這就實現了單調讀一致性)。然后客戶端通過合并所有的版本,增加其時鐘。這意味著客戶端要負責解決所有的版本沖突,因為當客戶端稍后發送更新的時候,它的矢量時鐘會早于所有的版本。

?


在更新的時候,客戶端發送它的矢量時鐘,副本檢查客戶端的狀態是否早于任意現有版本,如果是,副本將丟棄客戶端的更新。各個副本還可以在后臺互相傳言,嘗試將各自的版本樹合并起來。


?


在傳操作方式下,執行操作的次序非常重要,至少需要保證因果序(causal?order)。因為次序的關系,只要之前的操作還沒執行完,副本就不得不推遲任何新的操作。因此副本需要將操作請求保存到一個日志文件,并彼此交換日志,通過統一合并日志推導出正確的操作序列,才能相應地更新各自的本地存儲。

?

“ 因 果 序 ” 意 味 著 每 個 副 本要 先 完 成 對 “ 因 ” 的 修 改 才 能 執

行對“果”的修改。“全序(totalorder)”則要求每個副本都執行同一個序列中的操作。在此模型中,每個副本持有一個矢量時鐘列表。Vi為副本自身的矢量時鐘,Vj為副本i接收到副本j傳言消息時的矢量時鐘。V-state代表最后更新狀態的矢量時鐘。

?

當客戶端提交查詢的時候,它會一并發送客戶端的矢量時鐘,這個時鐘代表了客戶端的視圖。副本檢查自己所知的狀態是否遲于客戶端所知的狀態。

?

當收到更新操作,副本會將操作緩沖起來,直到可以將之應用到本地狀態。每個提交的操作都會帶上兩個時間戳,V-client標明客戶端在其發出更新請求時的視圖。V-@receive標明副本在收到請求時的視圖。

?


更新操作的請求會留在隊列里,直到副本收到該請求所依賴的所有其他請求。這個條件反映在矢量時鐘Vi上,即當Vi大于V-client時條件滿足。



更新(傳操作模型)

?

在后臺,各個副本交換它們記錄的更新隊列日志并更新彼此的矢量時鐘。在日志交換之后,副本檢查特定的操作是否可以執行(當所有依賴操作都已收到),然后完成操作。請注意在同一時刻,有可能存在多個操作準備好執行,此時副本將按照因果序(通過比較矢量時鐘)排列各操作,依次執行。還有可能發生不同副本上的并發更新問題。也就是說可能存在多個合法的操作序列,為了使不同副本以相同次序執行并發的更新,我們需要一種“全序”機制。

?


其中一種方法是設立一個單調增加的序列號,不管哪個更新先執行都好,序列號先到先得。另一方面,如果操作本身是可以互換的,那么操作的執行次序也就無關緊要了。執行更新之后,更新操作還不能立即從隊列中刪除,因為更新可能還沒有交換到到所有的副本。我們繼續檢查每次日志交換后每個副本的矢量時鐘,直到確認所有副本都已收到更新,才可以將它從隊列中刪除。

?

Map Reduce的執行過程

?

分布式的存儲架構也適合分布式的處理。例如對一個鍵列表執行Map/Reduce操作的情況。


系統將Map和Reduce函數推送給所有的節點(即將處理邏輯向數據靠攏)。Map函數分布到鍵所屬的各個副本上去處理,然后Map函數的輸出被轉交給Reduce函數去執行聚合操作。

?


對刪除的處理


在多主復制系統中,我們用矢量時鐘時間戳去判定因果序,我們需要非常小心地處理“刪除”的情況,以免丟失掉刪除對象關聯的時間戳信息,否則我們根本無法推導何時執行刪除。

?

因此,我們通常將刪除當作一種特殊的更新來處理,把對象標記為刪除,但仍然保留其元數據、時間戳信息。當經過足夠長的時間,我們確信所有節點都已經將該對象標記為刪除之后,我們才通過垃圾收集回收已刪除對象的空間。

?




福利

掃描添加小編微信,備注“姓名+公司職位”,加入【云計算學習交流群】,和志同道合的朋友們共同打卡學習!



推薦閱讀:

  • VMware竟然出了一款防火墻

  • 技術頭條

  • 你的 AI 老師已上崗

  • 要成為年薪百萬的技術大牛必經歷這5個階段, 收好這份超實用的技術進階指南 | 技術頭條

  • 助力?Android?抗衡?iOS,華為發布方舟編譯器!

  • 程序員的黑磚窯,東南亞博彩騙局詳解

  • 售價910元!周志華等人英文新書《演化學習》出爐!


真香,朕在看了! 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的一文读懂NoSQL的模式 | 时光机的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。