淺談區域性 (locality)
在設計不同的網路服務系統時,為了能夠有擴展性,通常都會設計成分散式的架構,然而除了架構上的設計,如何部署也是很重要的事,其中有個很重要的議題叫做區域性,因為沒有統一或明確的翻譯慣例,所以以英文來說明較為精確,在這裡指的區域性英文為locality,對於這個議題最近有一點心得
所以,回到主題,到底什麼是區域性? 簡單的來說,就是存取資料或資源時,很常存取或是相關的資料放在一起、或很近的地方的特性,舉個實例,例如假設我們有關於某個使用者的資料,但是使用者相關的資料分散在全球不同的資料庫裡,這時我們就會說,這資料庫的區域性不好,以圖來表示,我們假設使用者的資料分散在美西的DB1、美中的DB2和美東的DB3,而使用者在西雅圖要存取這些資料,就得走很遠的距離到三個很遠的地點存取資料
反言之,如果關於這使用者的資料,都存在離使用者很近的點,而且也都在同樣或是很接近的資料庫裡,那麼存取起來就會較快,這樣一來我們就可以說這樣的資料儲存方式它的區域性比較好,我們假設把同一使用者相關的資料都放在相近的地方,以圖為例,都放在加洲,這樣一來同樣是存取使用者的資料,其中所花的傳輸距離成本就遠比上一個例子來得少,反應速度也會因此較快
一般而言,區域性是越強越好,但是也有例外,那就是當考慮到可得性(availability)的時候,這樣的特性是指資料或資源隨時都可取得的機率高低,如果當我們把雞蛋放在同一個籃子裡,也就是資料都放在同樣的Datacenter裡,一但這個Datacenter對外的網路中斷,或是甚至遇到不可預料的災難時,那麼那些資料都會因此而無法取得,所以除了考慮到存取時的區域性,當資料有一定重要程度時,可得性也是很重要的考量,所以某些情況下,資料分散也是必要的
然而,區域性就表面看來,似乎只要將常用的、相關的資料都放在一起好像就能達成,然而經過仔細思考會發現其實並不是只有這樣,還有需要考慮到存取資料的距離,還有存取要求本身的高低階,在這篇文章我想分享的就是主要在於思考關於區域性設計上的一些理論的心得
請求的相依性與粒度
我發現並不是所有的情況下不佳的地區性都一定會嚴重影響到存取的效能,像是請求的相依性其實對於延遲的影響就非常大,如果說所有的情求都不能同時處理,一定得要上一個完成才能完成下一個的話,這樣一來就會造成每個request的請求都要額外花費一次連線的延遲成本,可以參考下圖
很明顯的,左邊的情況,傳輸距離所造成的影響,會是
請求數量 * (運算成本 + 延遲成本)
右邊的情況是
(請求數量 * 運算成本) + 延遲成本
因此光是請求是否能同步處理,並且是否有前後相依,就會造成相當大的差別,如果請求的數量越多,這樣的成本差距就越大,左邊的例子我們以NoSQL或是 SQL的請求為例子,通常下一道請求都是基於上一道請求的資料而決定的,如果說任務被拆散成很零碎的多道請求,像是有些key-value based的NoSQL資料庫,因為沒有高階的查詢指令,必然會有大量的請求,如此一來如果NoSQL資料庫放在很遠的地方,就會造成光是這之間的傳輸成本就會高得嚇人,而以SQL來看,因為可以盡可能地將多道SQL濃縮為少數幾道查詢,因此同樣的傳輸成本對於SQL資料庫來說,傳輸的成本造成的影響會小一點
而右邊的情況,通常是大量的資料傳輸,例如影音串流,因為上一筆資料無關下一筆資料,以這種情況來看,傳輸的距離不會是太大的問題,只有一開始會有的傳輸延遲
心得
一些簡單的心得就是,當請求是相依的,如果數量不大,那麼其實傳輸的延遲是可以被忽視的,又或著是大量連續的資料傳輸,距離的影響是較小的,如果不考慮連線的品質問題的話,但是如果是有相依特性的請求,數量又大的話,最好資料庫的部署要越接近越好,否則光是連線的延遲成本就相當驚人,就算你的NoSQL資料庫再怎麼快,也沒有任何幫助,甚至會比SQL資料庫還要慢