Dapr - actors之构建块(3)

举报
小云悠悠zZ 发表于 2023/01/30 16:31:31 2023/01/30
【摘要】 假设方法返回的当前值 GetValue 为 1 。 当两个线程同时调用方法时,它们会在调用方法 Increment GetValue 之前调用方法 SaveValue 。 这会导致两个线程以相同初始值开始 (1) 。 然后,线程递增值并将 2 其返回给调用方。 现在,两次调用后的结果值是, 2 而不是它的值 3 这是一个简单的示例,说明了在使用多个线程时可能会滑入代码的问题种类,并且很容易解决。

Important

Because actors are randomly distributed across service instances, it should be expected that an actor operation always requires a call to a different node in the network.

由于actor是在各服务实例间随机分发的,因此Actor 始终需要调用网络中的其他节点。

The next figure shows an ordering service instance running in Pod 1 call the method of an instance with ID . Because the actor with ID is placed in a different instance, this results in a call to a different node in the cluster:shipOrderActor33

下图显示了在 Pod 1 中运行的ordering 服务实例调用 ship OrderActor ID 为的实例的方法 3 。 由于 ID 的actor 3 放在不同的实例中,因此将导致调用群集中的不同节点:

调用执行组件方法的关系图。

Figure 11-3. Calling an actor method.

图 11-3。 调用执Actor方法。

  1. The service calls the actor API on the sidecar. The JSON payload in the request body contains the data to send to the actor.
  2. The sidecar uses the locally cached partitioning information from the placement service to determine which actor service instance (partition) is responsible for hosting the actor with ID . In this example, it's the service instance in pod 2. The call is forwarded to the appropriate sidecar.3
  3. The sidecar instance in pod 2 calls the service instance to invoke the actor. The service instance activates the actor (if it hasn't already) and executes the actor method.
  1. 服务在挎斗上调用Actor API。 请求正文中的 JSON 有效负载包含要发送到Actor 的数据。
  2. 挎斗使用placement 服务中的本地缓存的分区信息来确定哪个执行组件服务实例 (分区) 负责托管 ID 为的Actor 。 在此示例中,它是 pod 2 中的服务实例。 调用将转发到相应的挎斗 3。
  3. Pod 2 中的挎斗实例调用服务实例以调用Actor。 如果Actor尚未 并执行Actor方法,则该服务实例将激活该执行组件。
Turn-based access model

Turn-based 的访问模型

The turn-based access model ensures that at any time there's at most one thread active inside an actor instance. To understand why this is useful, consider the following example of a method that increments a counter value:

turn-based 的访问模型可确保在一个Actor实例内最多只有一个线程处于活动状态。 若要了解此操作的原因,请考虑以下用于递增计数器值的方法示例:

public int Increment()
{
     var currentValue = GetValue();
     var newValue = currentValue + 1;

    SaveValue(newValue);

    return newValue;
}

Let's assume that the current value returned by the method is . When two threads call the method at the same time, there's a risk of both of them calling the method before one of them calls . This results in both threads starting with the same initial value (). The threads then increment the value to and return it to the caller. The resulting value after the two calls is now instead of which it should be. This is a simple example to illustrate the kind of issues that can slip into your code when working with multiple threads, and is easy to solve. In real world applications however, concurrent and parallel scenarios can become very complex.GetValue1IncrementGetValueSaveValue1223

假设方法返回的当前值 GetValue  1 。 当两个线程同时调用方法时,它们会在调用方法 Increment GetValue 之前调用方法 SaveValue 。 这会导致两个线程以相同初始值开始 (1) 。 然后,线程递增值并将 2 其返回给调用方。 现在,两次调用后的结果值是, 2 而不是它的值 3 。 这是一个简单的示例,说明了在使用多个线程时可能会滑入代码的问题种类,并且很容易解决。 但在实际应用程序中,并发和并行方案可能会变得非常复杂。

In traditional programming models, you can solve this problem by introducing locking mechanisms. For example:

在传统编程模型中,可以通过引入锁定机制来解决此问题。 例如:

public int Increment()
{
     int newValue;

    lock (_lockObject)
     {
         var currentValue = GetValue();
         newValue = currentValue + 1;

        SaveValue(newValue);
     }

    return newValue;
}

Unfortunately, using explicit locking mechanisms is error-prone. They can easily lead to deadlocks and can have serious impact on performance.

遗憾的是,使用显式锁定机制容易出错。 它们很容易导致死锁,并可能对性能产生严重影响。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。