'性能優化模式(5)——數據局部性模式'

"

原理和動機

數據局部性模式是多次請求槓桿反模式的針對性解決方案。在大數據和強調個性化服務的時代,一個服務消費幾十種不同類型數據的現象非常常見,同時每一種類型的數據服務都有可能需要一個大的集群(多臺機器)提供服務。這就意味著客戶端的一次請求有可能會導致服務端成千上萬次調用操作,很容易使系統進入多次請求槓桿反模式。在具體開發過程中,導致數據服務數量暴增的主要原因有兩個:1. 緩存濫用以及缺乏規劃,2. 數據量太大以至於無法在一臺機器上提供全量數據服務。數據局部性模的核心思想是合理組織數據服務,減少服務調用次數。具體而言,可以從服務端和客戶端兩個方面進行優化。

服務端優化方案的手段是對服務進行重新規劃。對於數據量太大以至於無法在一臺機器上存儲全量數據的場景,建議採用Bigtable或類似的解決方案提供數據服務。典型的Bigtable的實現包括Hbase、Google Cloud Bigtable等。實際上數據局部性是Bigtable的一個重要設計原則,其原理是通過Row key和Column key兩個主鍵來對數據進行索引,並確保同一個Row key索引的所有數據都在一臺服務器上面。通過這種數據組織方式,一次網絡請求可以獲取同一個Row key對應的多個Column key索引的數據。缺乏規劃也是造成服務數量劇增的一個重要原因。很多通過統計和挖掘出來的特徵數據往往是在漫長的時間裡由不同team獨立產生的。而對於每種類型數據,在其產生之初,由於不確定其實際效果以及生命週期,基於快速接入原則,服務提供者往往會用手頭最容易實施的方案,例如採用Redis Cache(不加選擇地使用緩存會導致緩存濫用)。數據服務之間缺乏聯動以及缺乏標準接入規劃流程就會導致數據服務數量膨脹。數據局部性原則對規劃的要求,具體而言是指:

  • 1. 數據由儘可能少的服務器來提供,
  • 2. 經常被一起使用的數據儘可能放在同一臺服務器上。

客戶端優化有如下幾個手段:

  1. 本地緩存,對於一致性要求不高且緩存命中率較高的數據服務,本地緩存可以減少服務端調用次數;
  2. 批處理,對於單機或者由等價的機器集群提供的數據服務,儘可能採用批處理方式,將多個請求合成在一個請求中;
  3. 客戶端Hash,對於需要通過Hash將請求分配到不同數據服務機器的服務,儘量在客戶端進行Hash,對於落入同一等價集群的請求採用批處理方式進行調用。

案例分析

我們的挑戰來自於美團的推薦、個性化列表和個性化搜索服務。這些個性化系統需要獲取各種用戶、商家和團購信息。信息類型包括基本屬性和統計屬性。最初,不同屬性數據由不同的服務提供,有些是RPC服務,有些是Redis服務,有些是HBase或者數據庫,參見下圖:

"

原理和動機

數據局部性模式是多次請求槓桿反模式的針對性解決方案。在大數據和強調個性化服務的時代,一個服務消費幾十種不同類型數據的現象非常常見,同時每一種類型的數據服務都有可能需要一個大的集群(多臺機器)提供服務。這就意味著客戶端的一次請求有可能會導致服務端成千上萬次調用操作,很容易使系統進入多次請求槓桿反模式。在具體開發過程中,導致數據服務數量暴增的主要原因有兩個:1. 緩存濫用以及缺乏規劃,2. 數據量太大以至於無法在一臺機器上提供全量數據服務。數據局部性模的核心思想是合理組織數據服務,減少服務調用次數。具體而言,可以從服務端和客戶端兩個方面進行優化。

服務端優化方案的手段是對服務進行重新規劃。對於數據量太大以至於無法在一臺機器上存儲全量數據的場景,建議採用Bigtable或類似的解決方案提供數據服務。典型的Bigtable的實現包括Hbase、Google Cloud Bigtable等。實際上數據局部性是Bigtable的一個重要設計原則,其原理是通過Row key和Column key兩個主鍵來對數據進行索引,並確保同一個Row key索引的所有數據都在一臺服務器上面。通過這種數據組織方式,一次網絡請求可以獲取同一個Row key對應的多個Column key索引的數據。缺乏規劃也是造成服務數量劇增的一個重要原因。很多通過統計和挖掘出來的特徵數據往往是在漫長的時間裡由不同team獨立產生的。而對於每種類型數據,在其產生之初,由於不確定其實際效果以及生命週期,基於快速接入原則,服務提供者往往會用手頭最容易實施的方案,例如採用Redis Cache(不加選擇地使用緩存會導致緩存濫用)。數據服務之間缺乏聯動以及缺乏標準接入規劃流程就會導致數據服務數量膨脹。數據局部性原則對規劃的要求,具體而言是指:

  • 1. 數據由儘可能少的服務器來提供,
  • 2. 經常被一起使用的數據儘可能放在同一臺服務器上。

客戶端優化有如下幾個手段:

  1. 本地緩存,對於一致性要求不高且緩存命中率較高的數據服務,本地緩存可以減少服務端調用次數;
  2. 批處理,對於單機或者由等價的機器集群提供的數據服務,儘可能採用批處理方式,將多個請求合成在一個請求中;
  3. 客戶端Hash,對於需要通過Hash將請求分配到不同數據服務機器的服務,儘量在客戶端進行Hash,對於落入同一等價集群的請求採用批處理方式進行調用。

案例分析

我們的挑戰來自於美團的推薦、個性化列表和個性化搜索服務。這些個性化系統需要獲取各種用戶、商家和團購信息。信息類型包括基本屬性和統計屬性。最初,不同屬性數據由不同的服務提供,有些是RPC服務,有些是Redis服務,有些是HBase或者數據庫,參見下圖:

性能優化模式(5)——數據局部性模式

通常而言,客戶端每個用戶請求都會觸發多個算法。一方面,每個算法都會召回幾十甚至幾百個團購或者商家ID,團購和商家基礎屬性被均勻地分配到幾十臺Redis裡面(如下圖),產生了大量的Redis請求,極端情況下,一次客戶端請求所觸發的團購基礎數據請求就超過了上千次;另一方面,用戶特徵屬性信息有十幾種,每種屬性也由單獨的服務提供,服務端網絡調用次數暴增。在一段時間裡,很多系統都進入了多次請求槓桿反模式,Redis服務器的網卡經常被打死,多次進行擴容,提高線程池線程數量,絲毫沒有改善。

"

原理和動機

數據局部性模式是多次請求槓桿反模式的針對性解決方案。在大數據和強調個性化服務的時代,一個服務消費幾十種不同類型數據的現象非常常見,同時每一種類型的數據服務都有可能需要一個大的集群(多臺機器)提供服務。這就意味著客戶端的一次請求有可能會導致服務端成千上萬次調用操作,很容易使系統進入多次請求槓桿反模式。在具體開發過程中,導致數據服務數量暴增的主要原因有兩個:1. 緩存濫用以及缺乏規劃,2. 數據量太大以至於無法在一臺機器上提供全量數據服務。數據局部性模的核心思想是合理組織數據服務,減少服務調用次數。具體而言,可以從服務端和客戶端兩個方面進行優化。

服務端優化方案的手段是對服務進行重新規劃。對於數據量太大以至於無法在一臺機器上存儲全量數據的場景,建議採用Bigtable或類似的解決方案提供數據服務。典型的Bigtable的實現包括Hbase、Google Cloud Bigtable等。實際上數據局部性是Bigtable的一個重要設計原則,其原理是通過Row key和Column key兩個主鍵來對數據進行索引,並確保同一個Row key索引的所有數據都在一臺服務器上面。通過這種數據組織方式,一次網絡請求可以獲取同一個Row key對應的多個Column key索引的數據。缺乏規劃也是造成服務數量劇增的一個重要原因。很多通過統計和挖掘出來的特徵數據往往是在漫長的時間裡由不同team獨立產生的。而對於每種類型數據,在其產生之初,由於不確定其實際效果以及生命週期,基於快速接入原則,服務提供者往往會用手頭最容易實施的方案,例如採用Redis Cache(不加選擇地使用緩存會導致緩存濫用)。數據服務之間缺乏聯動以及缺乏標準接入規劃流程就會導致數據服務數量膨脹。數據局部性原則對規劃的要求,具體而言是指:

  • 1. 數據由儘可能少的服務器來提供,
  • 2. 經常被一起使用的數據儘可能放在同一臺服務器上。

客戶端優化有如下幾個手段:

  1. 本地緩存,對於一致性要求不高且緩存命中率較高的數據服務,本地緩存可以減少服務端調用次數;
  2. 批處理,對於單機或者由等價的機器集群提供的數據服務,儘可能採用批處理方式,將多個請求合成在一個請求中;
  3. 客戶端Hash,對於需要通過Hash將請求分配到不同數據服務機器的服務,儘量在客戶端進行Hash,對於落入同一等價集群的請求採用批處理方式進行調用。

案例分析

我們的挑戰來自於美團的推薦、個性化列表和個性化搜索服務。這些個性化系統需要獲取各種用戶、商家和團購信息。信息類型包括基本屬性和統計屬性。最初,不同屬性數據由不同的服務提供,有些是RPC服務,有些是Redis服務,有些是HBase或者數據庫,參見下圖:

性能優化模式(5)——數據局部性模式

通常而言,客戶端每個用戶請求都會觸發多個算法。一方面,每個算法都會召回幾十甚至幾百個團購或者商家ID,團購和商家基礎屬性被均勻地分配到幾十臺Redis裡面(如下圖),產生了大量的Redis請求,極端情況下,一次客戶端請求所觸發的團購基礎數據請求就超過了上千次;另一方面,用戶特徵屬性信息有十幾種,每種屬性也由單獨的服務提供,服務端網絡調用次數暴增。在一段時間裡,很多系統都進入了多次請求槓桿反模式,Redis服務器的網卡經常被打死,多次進行擴容,提高線程池線程數量,絲毫沒有改善。

性能優化模式(5)——數據局部性模式

在對系統進行分析之後,按照數據局部性模式的原則,我們採用瞭如下手段,徹底解決了系統多次請求槓桿反模式的問題:

  1. 採用大內存服務器存儲所有的團購和商家基礎信息,每個算法只要一次網絡請求就可以獲取所有的信息;
  2. 服務端採用多線程方式提供服務,避免了Redis單一線程模式下單個請求慢所帶來的連鎖效應;
  3. 借鑑類似Bigtable的數據組織方式,將用戶的多種特徵採用兩個維度(用戶維度和特徵類型)進行索引,確保同一用戶的信息只存放在一臺機器上面,減少網絡調用數量。

缺點和優點

數據局部性模式並不適用於系統初級階段。在初級階段,最小可用原則往往是主要設計原則之一,出於兩方面的考慮:一方面,在初級階段,很難預測所要提供服務的數據是否有效而且能夠長期使用,以及未來的調用量;另一方面,在初級階段,工程師可能無法預測最終的調用模式,而不同的調用模式會導致數據局部性方案的設計不同。對於已經大量使用的數據服務,採用數據局部性模式進行重構必然要改變老的調用模式,這一方面會引入新的Bug,另一方面也意味著巨大的工作量。需要特別強調的是,數據處於系統的最底層,對於結構複雜而又重要的數據,重構所帶來可靠性、一致性和工作量都是需要權衡的因素。對於請求量比較小的數據服務,即使一次請求會觸發嚴重的請求槓桿效應,但是如果原始觸發請求數量在可預見的時間內沒有明顯變多的跡象,進行數據服務重構可能得不償失。

數據局部性模式能夠解決多次請求槓桿反模式所導致的問題,但它並非大數據的產物,CPU、編譯器的設計理念裡早就融入了該模式,所以很容易被工程師理解。雖然過度設計在系統初級階段是一個要儘量避免的事情,但是理解和掌握數據局部性模式對於設計出一個可擴展、可重用的系統有很大幫助。很多成熟的系統因為多次請求槓桿反模式而導致系統頻繁崩潰,理解數據局部性模式的原則有助於提高工程師分析解決問題的能力,而在確認了系統存在請求槓桿問題後,數據局部性原則是一件非常銳利的武器。

"

相關推薦

推薦中...