簡體   English   中英

如何根據特定的資源路徑執行盡可能公平的負載均衡

[英]How to perform an as fair as possible load balancing based on specific resource paths

我有一個應用程序提供來自文件的工件(來自 PDF 文件的頁面作為圖像),原始 PDF 文件位於 S3 上,當客戶端點擊其中一個時,它們被下載到生成圖像的服務器。 這些機器有一個本地緩存機制,保證每個 PDF 文件只下載一次。

因此,當客戶帶來請求時,請給我第1頁,Z437175BA4191210EE004EE1D937494D09Z 123.Z437175BA4191210EE004E1D93749494D09Z此cache the the Z437175bA並將圖像發送回客戶端。

客戶端本身不知道它連接到一個特殊的服務器,看起來它只是訪問網站服務器,但是,為了性能,我想確保這個客戶端總是被定向到同一個文件服務器服務於它的第一個請求(並從 S3 下載了文件)。

我可以在客戶端上設置一個 cookie,讓他總是從那個特定的文件服務器下載,但是把它放在客戶端上會導致不公平的使用,因為有些用戶會打開很多文檔,而有些則不會,所以我想在資源級別執行此負載平衡(PDF 文檔)。

每個文檔都有一個唯一的標識(數據庫中的整數主鍵),我的第一個解決方案是使用 Redis 並將文檔 ID 作為鍵存儲,值是當前緩存此文檔的服務器計算機的主機,但我想刪除 Redis 或尋找一種更簡單的方法來實現這一點,而無需在其他地方尋找密鑰。

此外,如果定義的算法或想法允許動態添加更多文件服務器,那就太好了。

基於資源的親和性執行這種負載平衡的最佳方法是什么?

順便說一句,這個應用程序是 Ruby、java 和 Scala 的混合體。

我會在負載均衡器中使用以下方法:

  • 剝離請求的資源 URL 以刪除查詢和片段部分。
  • 將剝離的 URL 轉換為字符串並獲取其哈希碼。
  • 使用可用服務器列表中的后端服務器 select 的哈希碼; 例如

    String[] serverNames =... String serverName = serverNames[hash % serverNames.length];

這會將負載均勻地分布在所有服務器上,並始終將相同的請求發送到同一台服務器。 如果您添加更多服務器,它會自行調整......盡管在緩存再次預熱時您會受到性能影響。

我認為您不想以“公平”為目標; 即某種保證每個請求花費大致相同的時間。 為了實現公平,您需要主動監控每個后端的負載並根據負載進行調度。 這將(在某種程度上)否定緩存/親和性,並將消耗資源來進行測量和負載平衡決策。 一種愚蠢的負載分散方法(例如我的建議)應該為您的用例提供更好的整體吞吐量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM