[譯] 論數據流的擴展性

在分佈式系統中,數據流是一種簡單但功能強大的儲存和共享數據的機制。說數據流簡單的緣由之一是由於它們很容易擴展。不管是從縱向(增長計算機的容量)仍是從橫向(增長計算機的數量),數據流都能很好的擴展。本次數據流的擴展性的教程中,咱們將瞭解數據流縱向擴展性好的緣由,以及在橫向擴展性上的選擇。常見的問題是,當數據流在橫向擴展時,對數據流的處理也可能要進行橫向的擴展,這將會影響數據流處理管道的設計。html

縱向仍是橫向擴展

爲了不讀者感到困惑,我這裏先對於縱向和橫向進行定義。縱向擴展是指你使用更強大的計算機來運行數據流的存儲和處理程序。縱向擴展有時也稱爲向上擴展。你能夠提升的包括磁盤的大小和速度、內存、CPU 的速度以及 CPU 的核心數量和顯卡等設備。前端

Vertical scaling - AKA scaling up to a more powerful computer.

橫向擴展指的是將工做分配給多臺計算機。所以,數據流中的數據會在多臺計算機之間分配,處理數據流的程序也會被分配 (至少它們能夠被分配)橫向擴展有時也稱爲向外擴展。你能夠將一臺計算機的工做橫向擴展給多臺計算機android

有兩種狀況下可能須要橫向擴展:1、你得不到一個有更大內存和磁盤, 能夠存儲和處理你的全部數據的計算機。2、有這樣的計算機,可是太貴買不起。ios

Horizontal scaling - AKA scaling out to multiple computers.

縱向擴展

上面已經提到了,縱向擴展意味着從配置低的計算機擴展到配置高的計算機。下面是傳統計算機體系結構的各個層次:git

Computer architecture - vertical scaling.

數據離 CPU 越遠,CPU 訪問它的的速度就越慢。在上圖中,數據離最底層越近,CPU 訪問速度越慢。github

上述計算機體系結構的每一層都通過了優化,以便串行讀取數據。這意味着,順序讀取位於磁盤上,RAM 或 L三、L二、L1 高速緩存中的數據比讀取隨機分佈在磁盤、RAM 和高速緩存的數據要快。將數據順序寫入磁盤也要比隨機寫入磁盤各個部分要快得多。算法

數據流徹底是串行數據結構。它們連續地讀取,連續地寫入。這意味着,你能夠在單臺計算機上面輕鬆的向上擴展數據流。寫入流的數據能夠輕鬆的擴展到流文件中。向文件追加是寫入文件的最快方式,相比之下,回到文件開始的位置並重寫文件相對要慢。後端

從文件讀取時,一大塊數據被讀入到 RAM。RAM 中的數據會被存入緩存,一小部分數據被讀取並存入到 L3 緩存中,還有一小部分被讀取並存入到 L2 緩存中,還有更小的一部分被讀取並存入到 L1 緩存中,CPU 能夠直接訪問 L1 緩存並讀取這部分數據。由於你的數據分散在整個磁盤中,若是你須要將一小塊數據從磁盤讀取到 CPU 中,你須要先讀取一大塊數據到 RAM中,而後再進入 L三、L2和L1高速緩存,那麼在讀取所需數據以前,這將會產生更屢次數的數據讀取操做。當數據以串行方式位於一個大塊中時,磁盤、RAM、L三、L2 和 L1 高速緩存讀取數據的速度要比隨機讀取快得多。緣由很簡單,由於讀取次數少,每一次讀取的塊中都包含相關數據。緩存

由於數據流的讀寫很好地利用了現代計算機,當你擴展計算機運行數據流服務時,數據流服務的性能也會線性地增加。服務器

橫向擴展

以前也已經提到了,橫向擴展是將程序從一臺計算機擴展到多臺計算機。在數據流中,這意味着要將數據流中的消息分發到多臺計算機。下面的圖描述了將數據流的消息分發給多臺計算機的過程:

The messages of a data stream distributed onto multiple computers.

將數據流的消息分發給多臺計算機也稱爲對於數據流的分區

分區影響消息序列的順序的一致性

對於數據流的分區會影響消息序列的順序的一致性。在一臺計算機上,數據流的消息的讀取和寫入的順序能夠保證是相同的。一旦你對數據流進行了分區,咱們就不能保證這個順序了。具體的分區方法決定了會以何種方式影響消息序列的順序。

Round Robin 分區

Round Robin 分區是跨多臺計算機對數據流的消息進行分區的最簡單的方法。Round Robin 分區只是在計算機之間均勻和順序地分發消息。換句話說,1 號消息存儲在 1 號計算機上,2 號消息存儲在 2 號計算機上,以此類推。當全部的計算機都接收到消息後,Round Robin 分區的方法再從 1 號計算機開始。

若是隻有一個應用程序寫入數據流,使用 Round Robin 分區的方法是最簡單的。可是要是有多個程序同時運行就很差辦了。

當使用 Round Robin 分區機制時,對於流的讀取來講,按照流中劃分消息以前的順序從新組裝流中的消息是至關容易的。輸出流只需以輪詢調度方式從每個分區讀取一條消息。

基於字段值分區

基於字段值分區的原理是經過每一個消息的特定值將消息分發給不一樣的計算機。一般,識別ID(例如主鍵值)做爲分發消息的字段。計算每一個字段值的哈希值,而後利用這個哈希值將消息映射到集羣的一臺計算機中。

當使用字段值分區時,極可能會丟失整個消息序列的順序。寫入同一臺計算機(同一分區)的消息仍保持相互之間的順序,可是整個序列的順序可能會丟失,由於其餘的計算機(其餘分區)可能在它們以前被讀取。下圖就說明了這個問題:

Key based data stream partitioning may affect overall message sequence.

若是要得到數據流分區的所有好處,就不能控制流處理器從不一樣分區讀取數據的順序。若是你還想擴展流處理器,那更不切實際。下圖就說明這個問題:

Key based data stream partitioning with stream processor partitioning too, will most likely affect overall message sequence.

在不少狀況下,其實你並不須要完整的消息序列的順序。你須要的多是在數據流中相關消息的消息序列順序。例如,若是消息表示對於客戶端更新,那麼將對於同一客戶端的更新消息應該集中在集羣中的同一臺計算機(同一個分區)上。這樣,你就能夠保證對於每個客戶的更新順序,這對於你的程序來講已經足夠了。對於不一樣客戶端更新順序可能改變,可是對於同一邏輯實體(客戶端)的更新序列保持相同,對於不一樣邏輯實體的更新之間的序列的改變可能不必定是個問題。

對於消息進行分區以便最後全部的相關消息都會在同一臺服務器上,這一般是經過對消息主鍵上的數據進行分區完成的。這樣應該會保證同一邏輯實體(例如客戶端)的全部相關消息都會存儲在同一臺計算機上。

基於字段值的分區,消息的分佈可能會不均勻。它取決於字段的分佈以及將消息映射到羣集計算機的哈希函數。不合適的哈希算法可能會將更多消息映射到某些計算機上而不是其餘計算機。這樣不均勻的消息分發會致使集羣計算機之間負載分佈的不平均,這又會致使對於計算機資源的非最佳利用。

在某些狀況下,基於非標識字段值(例如外鍵或某些其餘字段值)對消息進行分區是有意義的。這顯然會致使消息離散分佈,甚至可能致使很是不均勻的分佈,例如使用一個比其餘值更廣泛的值做爲分區值。

下面是橫向擴展數據流的示意圖,其中集羣中的計算機的消息分佈不必定均勻:

Key based data stream partitioning may lead to uneven distribution of the messages in the stream across the computers in the cluster.

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索