請求層級平行(request-level parallelism)
想像一間忙碌的咖啡店有十二位咖啡師。一百位客人走進來,每人想要自己的一杯飲料。客人之間不需要合作——Alice 的拿鐵和 Bob 的濃縮毫無關係——所以店家只要把每張單子交給任何一位有空的咖啡師,十幾杯飲料就同時做出來。加速幾乎是免費的,正是因為這些訂單彼此獨立。這就是請求層級平行(request-level parallelism)的樣貌:大量彼此分開、互不相干的工作,可以並排執行,純粹因為沒有任何一件在等另一件。
在倉儲規模電腦裡,「訂單」就是使用者請求:網路搜尋、頁面載入、照片上傳、API 呼叫。每秒湧入數百萬個,而關鍵在於每一個都和其他的獨立——你的搜尋和我的毫無關係。於是系統把它們攤到整支伺服器艦隊上,每台機器(或執行緒)處理一個不同的請求,總吞吐量幾乎線性擴展:兩倍的伺服器大致服務兩倍的請求。這是最容易利用的平行性,因為沒有共享的更新要協調,也沒有細粒度的通訊要同步——你只需要夠多的機器,以及把每個請求導向其中一台的方法。
拿它和計算機結構其他部分苦苦掙扎的較難平行性對比會有幫助。指令層級平行在單一指令流內重疊運算,受相依性所限;資料層級平行對許多資料元素做同一種運算;執行緒層級平行把一個程式分到多個核心,必須協調共享記憶體。請求層級平行幾乎避開了所有這些困難的協調,因為工作的單位是完整、獨立的請求。這種便宜又獨立、且供應充沛的平行性,正是 WSC 能用許多普通電腦而非一台英雄級機器來打造的最重要原因。
誠實的提醒:請求並非總是完美獨立。它們常常打到同一個共享資料庫、同一塊熱門資料、或同一把鎖,而那些共享狀態正是爭用、一致性問題與尾端延遲悄悄回來的地方。請求層級平行讓向外擴展變得容易,但底下的共享服務仍必須小心設計,否則那份獨立性只是個會在負載下崩潰的幻覺。
促銷日的線上商店每秒有 5 萬次頁面瀏覽,每次都是一個獨立請求。負載平衡器把它們噴灑到 2000 台網頁伺服器上,每台每秒約 25 個請求。再加 2000 台,你就能服務大約兩倍的流量——因為這些請求從不需要彼此交談。
獨立請求幾乎線性向外擴展:機器越多,吞吐量按比例越高。
請求層級平行只有在請求真正獨立時才是最容易利用的平行性。一旦它們全都猛敲同一個共享資料庫或鎖,爭用與尾端延遲就回來了。