我正在测试Microsoft Orleans作为分布式计算框架的可行性。似乎它可以工作,但是我想知道如何设置给定筒仓中的最大活动颗粒数?
我的谷物不会纯粹受 CPU 限制,而是会执行一些 IO 和其他相关任务。我担心如果我让它疯狂运行,它会启动大量实例,这会使整个事情陷入困境。
像这样的筒仓配置可能吗?
举个简单的例子:我有一个拥有1,000,000个用户的服务,每个用户都有一些个人资料信息.我想使用actor管理此配置文件信息的CRUD操作.
在Project Orleans中,我的理解是每个用户只有一粒,所以1,000,000个虚拟粒子具有相同的actor类型(只有在使用时才会创建),每个粒子将管理存储在其中的单个用户的配置文件信息.州.随着用户的增长,谷物的数量也在增长.
在Service Fabric中,如果我正确地解释文档,它的工作方式会略有不同.我会有一个有状态的actor类型来管理所有用户的CRUD操作,为了可伸缩性,我会对actor进行分区,为每个分区负责一部分用户数据.鉴于分区选项,我看不到一种明显的方法来实现它与Project Orleans相同的细粒度方式.
我非常喜欢奥尔良项目的方法.演员只是处理单个用户的数据,可扩展性是显而易见的(更多的用户等于更多的谷物).记忆模型也很简单:一个演员按需少量状态就可以得到水分.
看起来Service Fabric的实现会稍微复杂一些.每个参与者都在处理一组用户,为了可伸缩性,我必须事先决定应该制作多少分区,因为以后无法修改.对于内存模型,每个参与者管理的数据量随着用户数量的增长而增长.
所以我的问题是:我的理解是否正确,Service Fabric中的演员比Project Orleans更粗糙?
更新
谢谢你的回答.在我的错误中,我认为一个分区包含一个actor实例,它将包含并管理分区中所有actor ID的状态.这是完全错误的.Michiel指出分区包含许多actor实例,每个actor ID一个.因此,演员可以像在奥尔良项目中那样实施.现在,这更有意义了,谢谢.
我试图弄清楚如果在同一个集群中托管2个不同的奥尔良谷物与在同一个虚拟网络中的不同集群中部署2个不同的谷物,将会有多大的性能.有人可以给出一些指导,以及在这种情况下2种谷物如何相互交流.
我试图了解谷物在奥尔良的工作方式。当我尝试使用外部 Grain 中的内部 Grain 的结果时,我的程序将停止。
内层颗粒是否会被外层颗粒的上下文阻塞,因此我永远无法从内层颗粒中获得结果?
public class OuterGrain : Grain, IOuterGrain
{
public Task<string> GetFormattedTime()
{
var innerGrain = GrainFactory.GetGrain<IInnerGrain>(1);
var innerGrainTask = innerGrain.GetCurrentTime();
return Task.FromResult(innerGrainTask.Result.ToString("yy-MM-dd"));
}
}
public class InnerGrain : Grain, IInnerGrain
{
public Task<DateTime> GetCurrentTime()
{
return Task.FromResult(DateTime.Now);
}
}
Run Code Online (Sandbox Code Playgroud) 如果我有一个谷物(或客户)要经常向另一个谷物发送消息(每分钟几次,持续数小时),那么访问该谷物的最佳实践是什么?我是否可以从工厂获得,使用并丢弃它-每次都获得新的谷物参考?还是在这种情况下,我应该“保留”对谷物的引用,只从工厂获得一次?
我目前正在为我们的组织了解 MS Orleans。我知道只要所有数据库更新都是通过谷粒来的,奥尔良谷粒将与数据库保持同步。
但是如果有一些批量处理过程(如处理数据文件)更新/插入/删除数据库中的记录会发生什么?
是否有一些流程或模式可以与奥尔良一起使用来满足这一点?还是我们需要通过 Grains 处理所有批量处理?如果我们通过谷粒处理批量操作 - 我们是通过更新每个谷粒(如果每个谷粒将自身更新到数据库中似乎非常昂贵)或者是否有一些批量模式用于强制所有受影响的谷粒“刷新”?
答案可能很明显。我在文档中没有找到关于这些场景的任何内容。
我们将使用 Orleans 作为带有 MS-SQL 服务器的本地安装。
编辑:
我指的是更新 N 粒数据的过程。对于 sql 来说,一次更新 1000 条记录的调用比更新一条记录的 1000 次调用要好得多。一个具体的例子是库存更新:每个产品库存都是一个谷物。每隔 15 分钟左右,第 3 方就会收到一份文件,通知在应用程序之外发生的库存数量变化。这应该在数据库中更新并反映在谷物中。文件可能有 10k 条记录...
Microsoft Orleans 框架提供了一种无需太多复杂性即可构建分布式、大规模系统的方法。
缩放对于奥尔良来说是很自然的;如果主机出现故障,则该主机上的活动谷物会在其他地方重新激活,因为它们的状态会保留在存储中。
考虑到这一点,Docker 等容器服务如何应用于生产中的 Orleans 应用程序?如果 Orleans 默认情况下已经可以扩展,为什么我们需要一个精心设计的容器服务来进行扩展?
可以说我有一个移动应用程序,我想从该应用程序连接到奥尔良服务器。
我应该直接连接到奥尔良还是使用某些前端服务器(为什么?)
如果直接使用,我应该使用奥尔良流或自定义套接字连接。如果我不能使用奥尔良客户端(和流),应该如何实现接受套接字连接的谷物。如果不使用谷物,甚至有可能将谷物从内存中逐出吗?
如果前端是前端,那么前端本身是否必须是谷物?
我有一个奥尔良应用程序,其结构如下:
public interface IGraintest : Orleans.IGrainWithGuidCompoundKey
{
Task Init();
}
public abstract class GraintestImpl<T> : Grain, IGraintest, Deserializer<T>
{
string streamName;
public Task Init()
{
return Task.CompletedTask;
}
public override async Task OnActivateAsync()
{
var primaryKey = this.GetPrimaryKey(out streamName);
var streamProvider = GetStreamProvider("SMSProvider");
var stream = streamProvider.GetStream<String>(primaryKey, streamName);
// To resume stream in case of stream deactivation
var subscriptionHandles = await stream.GetAllSubscriptionHandles();
if (subscriptionHandles.Count > 0)
{
foreach (var subscriptionHandle in subscriptionHandles)
{
await subscriptionHandle.ResumeAsync(OnNextMessage);
}
}
await stream.SubscribeAsync(OnNextMessage);
} …Run Code Online (Sandbox Code Playgroud) 我正在评估奥尔良的一个我们即将开始的新项目。
最终我们想要运行一群持久的演员,但我目前正在努力让奥尔良的内存版本的基线变得高性能。
给定以下颗粒
using Common.UserWallet;
using Common.UserWallet.Messages;
using Microsoft.Extensions.Logging;
namespace Grains;
public class UserWalletGrain : Orleans.Grain, IUserWalletGrain
{
private readonly ILogger _logger;
public UserWalletGrain(ILogger<UserWalletGrain> logger)
{
_logger = logger;
}
public async Task<CreateOrderResponse> CreateOrder(CreateOrderCommand command)
{
return new CreateOrderResponse(Guid.NewGuid());
}
public Task Ping()
{
return Task.CompletedTask;
}
}
Run Code Online (Sandbox Code Playgroud)
以下筒仓配置:
static async Task<IHost> StartSiloAsync()
{
ServicePointManager.UseNagleAlgorithm = false;
var builder = new HostBuilder()
.UseOrleans(c =>
{
c.UseLocalhostClustering()
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "dev";
options.ServiceId = "OrleansBasics";
})
.ConfigureApplicationParts(
parts => parts.AddApplicationPart(typeof(HelloGrain).Assembly).WithReferences()) …Run Code Online (Sandbox Code Playgroud)