紋理排列
Orleans 可確保當發出粒紋呼叫時,叢集中某些伺服器上的記憶體中有該粒紋實例可用來處理要求。 如果叢集中目前沒有作用中的粒紋,Orleans 會挑選其中一部伺服器來啟動粒紋。 這稱為 顆粒擺放。 放置也是負載平衡的一種方式:均勻分配繁忙的任務有助於讓整個叢集的工作負載更加平均。
Orleans 中的放置程式是完全可設定的:開發人員可以從一組現成可用的放置原則中選擇,例如隨機、偏好本機和負載型,或可設定自定義邏輯。 這可讓您在決定建立粒紋的位置時具有完整的彈性。 例如,微粒可以放置在靠近其需要操作的資源的伺服器上,或放在與其互相溝通的其他微粒附近。 根據預設,Orleans 會挑選隨機相容的伺服器。
Orleans 使用的放置策略可以全域配置或根據每個粒度類別進行設置。
隨機放置
從叢集中的相容伺服器隨機選取伺服器。 這個放置策略是透過將 RandomPlacementAttribute 新增到粒度來設定。
本地放置
如果本地伺服器相容,請選取本地伺服器,否則請選取隨機伺服器。 這個放置策略是透過將 PreferLocalPlacementAttribute 應用到粒子來設定。
哈希式放置
將顆粒ID哈希為非負整數,並取模於相容的伺服器數目。 從依伺服器位址排序的相容伺服器清單中選取對應的伺服器。 請注意,這不保證會在叢集成員資格變更時保持穩定。 具體來說,新增、移除或重新啟動伺服器可以改變針對指定粒紋標識符選取的伺服器。由於使用此策略放置的粒紋會登錄在粒紋目錄中,因此隨著成員資格變更,放置決策的這項變更通常不會有明顯的效果。
這個放置策略是透過將 HashBasedPlacementAttribute 添加到穀粒中進行配置。
啟用計數型放置
此放置策略打算根據最近忙碌的粒紋數目,將新的粒紋啟動放在負載最輕的伺服器上。 它包含一種機制,其中所有伺服器會定期將其啟用計數發佈至所有其他伺服器。 然後,放置主管藉由檢查最近報告的啟用計數,並根據這些數據,預測目前伺服器上可能的啟用計數,選擇預期啟用次數最少的伺服器。 Director 會在進行此預測時隨機選取數部伺服器,以避免多個個別的伺服器多載相同的伺服器。 根據預設,會隨機選取兩部伺服器,但此值可透過 ActivationCountBasedPlacementOptions來設定。
此演算法基於 Michael David Mitzenmacher 的論文 「隨機化負載平衡中雙選擇的力量」,且同樣應用於 Nginx 進行分散式負載平衡,如 NGINX 文章 中所述的「雙選擇的力量」Load-Balancing算法。
這個放置策略是藉由將 ActivationCountBasedPlacementAttribute 新增至顆粒來設定。
無狀態工作者配置
無狀態工人配置是一種特別的配置策略,專用於 無狀態工人 微粒。 這個佈置操作幾乎與 PreferLocalPlacement 相同,不同之處在於每部伺服器可以激活多個相同的穀粒,且由於不需要,因此不必在穀粒目錄中註冊這些穀粒。
這個放置策略是透過將 StatelessWorkerAttribute 新增至粒子來配置的。
基於孤島角色的放置
具決定性放置策略,將穀粒放置在具有特定角色的筒倉中。 這個放置策略是藉由將 SiloRoleBasedPlacementAttribute 新增至粒紋來設定。
資源最佳化配置
資源優化的放置策略試圖根據可用的記憶體和CPU使用量,在筒倉之間平衡grain啟用,以優化叢集資源。 它將權重分配給運行時的統計數據,以便優先考量不同資源,並為每個孤立區域計算出標準化分數。 選擇最低分數的筒倉來放置即將進行的啟用。 正規化可確保每個屬性會按比例貢獻整體分數。 您可以根據不同資源的使用者特定需求和優先順序,透過 ResourceOptimizedPlacementOptions 調整權數。
此外,該放置策略提供一個選項來建立更強的 偏好 到本地倉儲(收到要求進行新放置的倉儲),以便被選擇作為啟用的目標。 這是透過屬於選項一部分的 LocalSiloPreferenceMargin
屬性來控制。
此外,在線,調適型 演算法提供平滑效果,藉由將它轉換成多項式衰變過程來避免快速信號下降。 對於 CPU 使用量而言,這尤其重要,並且整體上有助於避免倉儲設備上資源的飽和,特別是避免資源在剛加入的倉儲設備上過度使用。
此演算法是以:基於資源的配置與合作式雙模式卡爾曼濾波
這個放置策略是藉由將 ResourceOptimizedPlacementAttribute 新增至粒紋來設定。
選擇放置策略
要選擇適當的紋理配置策略,除了 Orleans 提供的預設值之外,需要進行監控及開發人員的評估。 放置策略的選擇應以應用程式的大小和複雜度、工作負載特性和部署環境為基礎。
隨機放置仰賴 大數法則,因此當大量穀物(10,000 個以上)有無法預測的負載分布時,通常是一個良好的預設值。
啟用計數型放置也包含隨機元素,依靠“兩次選擇原理”,這是一種常用於分布式負載平衡的演算法,並且在流行的負載平衡器中使用。 孤島經常將運行時間統計數據發送到叢集中的其他孤島,包括:
- 可用的記憶體、物理記憶體總計和記憶體使用量。
- CPU 使用量。
- 啟動總計次數和最近的活躍啟動次數。
- 在過去幾秒內活躍的激活區域滑動視窗,有時稱為激活工作集。
從這些統計數據中,目前僅使用啟用計數來判斷給定料倉上的負載。
最後,您應該試驗不同的策略並監視效能計量,以判斷最適合。 藉由選取正確的粒紋放置策略,您可以將 Orleans 應用程式的效能、延展性和成本效益優化。
設定預設放置策略
如果沒有覆寫預設值,Orleans 將會隨機放置。 在設定時註冊 PlacementStrategy 的實作,可以覆蓋預設的放置策略。
siloBuilder.ConfigureServices(services =>
services.AddSingleton<PlacementStrategy, MyPlacementStrategy>());
設定資料粒的配置策略
粒紋類型的放置策略是藉由在粒紋類別上新增適當的屬性來設定。 相關屬性會在 放置策略 區段中指定。
範例自定義放置策略
首先定義實作 IPlacementDirector 介面的類別,需要單一方法。 在此範例中,我們假設您有一個已定義的函式 GetSiloNumber
,該函式會根據即將創建的穀物的 Guid,返回筒倉編號。
public class SamplePlacementStrategyFixedSiloDirector : IPlacementDirector
{
public Task<SiloAddress> OnAddActivation(
PlacementStrategy strategy,
PlacementTarget target,
IPlacementContext context)
{
var silos = context.GetCompatibleSilos(target).OrderBy(s => s).ToArray();
int silo = GetSiloNumber(target.GrainIdentity.PrimaryKey, silos.Length);
return Task.FromResult(silos[silo]);
}
}
接著,您必須定義兩個類別,以便能將穀物類別指派給策略:
[Serializable]
public sealed class SamplePlacementStrategy : PlacementStrategy
{
}
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public sealed class SamplePlacementStrategyAttribute : PlacementAttribute
{
public SamplePlacementStrategyAttribute() :
base(new SamplePlacementStrategy())
{
}
}
接著,將此策略應用於您想使用的任一粒紋類別,並將其標記為屬性。
[SamplePlacementStrategy]
public class MyGrain : Grain, IMyGrain
{
// ...
}
最後,當您建置 SiloHost時,請註冊策略:
private static async Task<ISiloHost> StartSilo()
{
var builder = new HostBuilder(c =>
{
// normal configuration methods omitted for brevity
c.ConfigureServices(ConfigureServices);
});
var host = builder.Build();
await host.StartAsync();
return host;
}
private static void ConfigureServices(IServiceCollection services)
{
services.AddPlacementDirector<SamplePlacementStrategy, SamplePlacementStrategyFixedSiloDirector>();
}
如需查看進一步使用放置上下文的第二個簡單範例,請參閱 Orleans 源代碼庫中的 PreferLocalPlacementDirector
。