奥尔良工作分配
Work distribution in Orleans
在 Microsoft Orleans 中,我尝试使用以下代码实现类似可用工作列表的功能:
public Task<WorkResponse> PerformWork(WorkRequest request)
{
Console.WriteLine("Performing work for id: {0}", request.Param1);
Thread.Sleep(TimeSpan.FromSeconds(10));
var result = Task.FromResult(new WorkResponse(request.Param1, request.Param2, request.Param3));
Console.WriteLine("Completed work for id: {0}", request.Param1);
return result;
}
但是如果我使用像这样的代码开始一些任务,事情就不会正常运行。
_work
.ToList()
.AsParallel()
.ForAll(x =>
{
Console.WriteLine("Requesting work for id: {0}", x.Key);
var worker = GrainFactory.GetGrain<IWork>(x.Key);
var response = worker.PerformWork(x.Value);
Console.WriteLine("Response for work id: {0}", x.Key);
});
然而,如果另一个节点加入集群,那么这个工作似乎永远不会移动到新节点。该新节点上只会处理新安排的工作。
似乎如果在 Orleans 队列中有一堆额外的工作,那么新节点就会卡在加入集群中。
Orleans 使用固定数量的工作线程来最小化上下文切换和线程的开销。调用 Thread.Sleep()
会引起麻烦,因为工作人员将忙于睡觉而无法从队列中提取新工作。
当您避免使用 Thread.Sleep(...)
并使用 await Task.Delay(...)
时会发生什么。
Orleans 使用的成员资格算法要求筒仓具有响应能力:慢筒仓与死筒仓无法区分。
在 Microsoft Orleans 中,我尝试使用以下代码实现类似可用工作列表的功能:
public Task<WorkResponse> PerformWork(WorkRequest request)
{
Console.WriteLine("Performing work for id: {0}", request.Param1);
Thread.Sleep(TimeSpan.FromSeconds(10));
var result = Task.FromResult(new WorkResponse(request.Param1, request.Param2, request.Param3));
Console.WriteLine("Completed work for id: {0}", request.Param1);
return result;
}
但是如果我使用像这样的代码开始一些任务,事情就不会正常运行。
_work
.ToList()
.AsParallel()
.ForAll(x =>
{
Console.WriteLine("Requesting work for id: {0}", x.Key);
var worker = GrainFactory.GetGrain<IWork>(x.Key);
var response = worker.PerformWork(x.Value);
Console.WriteLine("Response for work id: {0}", x.Key);
});
然而,如果另一个节点加入集群,那么这个工作似乎永远不会移动到新节点。该新节点上只会处理新安排的工作。
似乎如果在 Orleans 队列中有一堆额外的工作,那么新节点就会卡在加入集群中。
Orleans 使用固定数量的工作线程来最小化上下文切换和线程的开销。调用 Thread.Sleep()
会引起麻烦,因为工作人员将忙于睡觉而无法从队列中提取新工作。
当您避免使用 Thread.Sleep(...)
并使用 await Task.Delay(...)
时会发生什么。
Orleans 使用的成员资格算法要求筒仓具有响应能力:慢筒仓与死筒仓无法区分。