Microsoft Orleans 中的节流谷物

Throttling grains in Microsoft Orleans

我正在尝试确定 Microsoft Orleans 的正确体系结构。我需要从大约 1000 个系统中检索 100 万到 300 万个文件,并将它们存储在几个中央服务器上。系统还将检索和存储每个文件的一些元数据,并将它们存储在数据库中。

我目前正在考虑为每个文件使用一个 grain,这样我可能会有数百万个 grain,但我想知道在这种情况下将每个 grain 同时保存到数据库中是否会使数据库过载。

我想知道是否应该考虑以下情况之一来尽量减少数据库的并发负载:

  1. 将 grains return 的结果传递给另一个 grain,它将管理数据库交互并分批存储元数据。
  2. 以这样的方式编写客户端代码以限制 grains 的创建...也许 create/activate grains 以 1000 个为一批,并且仅在先前创建或激活的 grains 已被创建或激活时才创建或激活更多由运行时停用和卸载。

我是否需要为这些烦恼,或者我是否可以简单地依靠 Orleans 运行时(可能通过设置)不要一次激活太多会尝试同时将数据保存到数据库的谷物?

我会放弃第二个建议,因为由于难以写出结果,您会限制整个系统的吞吐量。这是 Orleans 最大的优势之一,它几乎可以无限扩展以响应需求。

您可以尝试修改第一个解决方案。我不会 return 结果到另一个 grain,而是让每个 grain 使用其文件读取的结果调用无状态服务,然后将持久性委托给该服务。这可能是你的想法,但无状态服务不同于谷物,所以我想说清楚。

如果系统出现故障而此服务有一个正在尝试写入的行列表,这将打开丢失数据的大门。如果这是一个问题,我会让 grains 写入一个服务,该服务立即写入一个持久消息队列(即 RabbitMQ),然后另一个服务从该队列读取并写入数据库。我不会让 grains 直接写入消息队列,因为集中队列写入可以让您向该服务添加重试逻辑、断路器等。尝试为 1MM 颗粒添加共享断路器将是一场噩梦。

虽然你没有问,但我要提出另一个想法。我不禁质疑将所有这些数据放入数据库的决定。数据库非常擅长跟踪数据的变化,但我怀疑您正在收集的元数据将在以后进行分析,但不会被修改。这使得它成为事件流(例如 Azure 事件网格)的理想候选者。事件流针对写入进行了优化,可以轻松处理您正在谈论的浪涌类型。