以並行思維方式思考

banq發表於2016-12-06
許多軟體開發人員試圖建立可擴充套件系統時往往會遇到困難。也許這是因為,最簡單和最明顯的解決方案往往無法擴充套件; 這可能解釋了為什麼這些方案有時被稱為“幼稚”的解決方案。

一旦你瞭解並行一些基本概念和準則,在任何情況下,就會編寫可伸縮擴充套件的程式碼,最重要的是Amdahl定律,你不需要真正理解其背後的數學原理,但理解它的中心思想卻是至關重要的,“並行程式受到其組成的序列子部分的限制” - 為此,你必須理解“並行程式碼”和“序列碼'。

要理解並行程式碼,首先必須瞭解非並行(序列)程式碼是什麼。作為經驗法則,序列程式碼傾向於做出以下假設:
1.它需要訪問所有關於整個問題領域的資料,才能解決問題。
2.它需要在它完成執行的時候才會解決整個問題。

雖然一些問題本質上是序列的,但事實證明許多問題域可以並行化。問題域的解決方案,可以完全並行有時稱為“ 易並行 (Embarrassingly parallel)”。

易並行程式碼可以無限擴充套件; 序列程式碼則不能,最終需要重寫;因為這一點,有人會說,序列程式碼設計不良 - 這就是為什麼許多開發人員進入函數語言程式設計的原因;Haskell,Erlang和Scala等語言鼓勵您編寫並行程式碼(透過避免狀態改變和可變資料)。

不幸的是,選擇一種特定的程式語言並不夠; 編寫並行程式碼,你還需要改變一點你的思維。如果你回想起前面提到的關於序列程式碼的觀點,你可以推斷並行程式碼要求你做出以下假設:
1.它只需要處理它想要解決的整體問題的資料子集。
2.它只需要在它完成執行的時候解決整個問題的一個子集。

在客戶端 - 伺服器/網路環境中,通常的問題是我們希望處理來自(有時是大量)併發使用者的請求(通常是同時讀取和/或修改大量的系統資料)。這些型別的問題通常涉及許多不同的(非重疊的)資料集,因此它們可以容易地並行化。

由於hashing , indexing和sharding分片 (均存在資料庫和作為應用程式的核心邏輯的一部分); 每個請求的處理可以完全相互隔離 - 這是寫易並行程式碼的關鍵; 請確保您的程式碼在任何給定時間只處理整個資料的有限子集。

總結; 並行思考的關鍵是考慮你的資料是否可由能獨立處理的小型、固定大小的資料子集組成的。

為了給你一個實際示例,請考慮以下情況:

我們希望構建一個由兩個獨立過程組成的實時系統 - 讓我們稱之為ProcessA和ProcessB。 讓我們假設我們有兩個使用者(Alice和Bob)連線到我們的系統;Alice連線到ProcessA,Bob連線到ProcessB。 我們想要做的是允許Alice向Bob傳送訊息。 所以問題看起來像這樣:

這個問題的一個樸素,非並行(序列)解決方案將是:ProcessA簡單地詢問ProcessB是否連線到使用者'Bob',如果是,ProcessA可以傳遞訊息到ProcessB,然後它將傳送給Bob。

當我們的系統中只有兩個使用者和兩個程式時,這個“樸素”的序列解決方案實際上工作得很好,但是如果我們的整體問題看起來像這樣:有N多組使用者像 Alice和Bob這樣進行同時通訊。

在這種情況下你可以想象,processA每次訊息透過系統時與每個其他程式進行通訊/協調是不可行的; 這意味著我們所有的程式都會一次又一次地對相同的資料(在這種情況下;每條訊息)進行操作。

解決這個問題的一個簡單的並行演算法是pub / sub -有很多方法來實現它,但其背後的核心原則是在不同的通道上劃分訊息,並跟蹤每個通道的訂閱者。 pub /sub的典型實現是將涉及跨越多個程式分割通道(使得每個程式處理所有可能的通道名稱的子集)。 因此,要在兩個或多個使用者之間傳送訊息,您只需將訊息釋出到適當的頻道,即將訊息傳送到相應的程式(您可以對頻道名稱進行雜湊處理,以確定哪個程式負責該頻道),然後過程將該訊息轉發給相關訂戶。

使用pub / sub,您可以透過將使用者名稱稱(或id)合併到頻道名稱(例如“alice-channel”,“bob-channel”)中,然後僅允許使用者訂閱自己的頻道頻道。 pub / sub背後的“易並行”理念是每個程式只處理透過系統的所有通道和訊息的固定子集。您新增的程式越多,每個程式將需要處理的通道/訊息越少 - 系統可以處理多少個頻道;只要您可以繼續新增更多程式(以及執行這些程式的更多硬體)。

除了資源限制,這個pub / sub實現的唯一真正的限制是每個通道的訊息吞吐量;但這通常是可接受的限制。 由於訊息通常用於人類活動; 每個人每分鐘只能消耗這麼多的訊息 - 實際上,pub / sub的實際限制傾向於接近良好使用者體驗所需的自然限制 -也就是說,對於高吞吐量(後端/大資料)應用程式,您可以始終將pub / sub通道分成更小的子集,如'alice-channel-1','alice-channel-2',...,'alice-channel-n',而不必對pub /

當然,最終理解並行程式碼的最好方法是開始動手編寫它!希望這篇文章可以給你一個激勵,自己試試。

Thinking in Parallel

相關文章