云计算设计模式(十三)——领导人选举模式

云计算设计模式(十三)——领导人选举模式

通过协调合作,在分布式应用程序的任务实例集合执行的操作,选举一个实例作为承担管理的其他实例责任的领导者。这个模式可以有助于确保任务实例不互相冲突,导致争用共享资源,或与其他的任务实例正在执行的工作无意中干扰。

背景和问题

一个典型的云应用包括行动协调的方式很多任务。这些任务都可以是实例运行相同的代码和需要访问相同的资源,或者它们可能是可并行工作,以执行复杂计算的各个部分。

任务实例可能为多的时间自主运行,但它也可能是必要的,以协调各实例的操作,以确保它们不发生冲突,导致争用共享资源,或无意中妨碍工作,其他的任务实例正在执行。例如:
•在基于云的系统,该系统实现了横向扩展,同一个任务的多个实例可以与每个实例服务于不同的用户同时运行。如果这些实例写入到共享资源,也可能是必要的,以协调它们的操作,以防止每个实例从盲目地覆盖由他人进行的更改。
•如果任务正在执行复杂的计算以并行的单个元素,其结果将需要被聚合时,他们都完成了。

由于任务实例都是同行,没有天生的领导者,能够充当协调员或聚合器。

解决方案

单个任务实例应选充当领导者,这种情况下应协调其他从属任务实例的操作。如果所有的任务实例都运行相同的代码,他们可能都能够充当领导者。因此,选举过程必须谨慎管理,以防止两个或多个实例接管领导者的角色在同一时间。

该系统必须选择的领导者提供了一个坚固的机构。这种机制必须能够应付诸如网络中断或进程故障事件。在许多解决方案中,下属的工作情况监控的领导者,通过某种类型的心跳机制,或通过轮询。如果指定的领导者意外终止或网络故障使得领导者不通下属的工作情况,有必要为他们选出了新的领导人。

有可用于选举的领导者之间的一组任务在分布式环境中,包括几个策略:
•与排名最低的实例或进程ID选择任务实例。
•竞速获得一个共享的分布式互斥。第一个任务实例获取该互斥锁处于领先地位。然而,系统必须保证,如果领导者终止或变得与系统的其余部分断开,该互斥被释放,以允许另一个任务实例成为领导者。
•实施的共同领导人选举算法,如恶霸算法或环算法之一。这些算法是相对简单的,但也有一些更复杂的技术提供。这些算法假定每个候选参选具有唯一的ID,并且,它们可以用可靠的方式在其他候选人进行通信。

问题和注意事项

在决定如何实现这个模式时,请考虑以下几点:
•选出一个领导者的过程应该是弹性的瞬时和永久失效。
•必须能够检测到当领导失败,或变成不可用(可能是由于通讯故障)。在这是需要这种检测的速度将取决于系统。有些系统可能能够发挥作用了一会儿没有一个领导者,在此期间造成的领导人变得不可用瞬时故障可能已被排除。在其他情况下,可能有必要立即检测领袖失败并引发新的选举。
•在实现自动缩放水平的系统中,如果系统鳞背面和关闭一些计算资源的领导者可能被终止。
•使用一个共享的分布式互斥引入外部服务,提供了互斥锁的可用性依赖。该服务可以构成一个单点故障。如果此服务应该以任何理由变得不可用时,系统将无法选出一个领导者。
•使用一个专用进程的领导者是一个比较简单的方法。然而,如果该过程失败,可能有显著延迟而被重新启动,并且将得到的延迟可能影响其他进程的性能和响应时间,如果他们正在等待领导人来协调的动作。
•实施的领导人选举算法之一手动为调整和优化代码的最大灵活性。

何时使用这个模式

使用此模式时,在分布式应用程序的任务,比如云托管解决方案,需要认真协调,也没有天生的领导者。

注意:

避免使领导者在系统中的瓶颈。领导者的目的是协调的附属任务完成的工作,它不一定有机会参加这项工作本身,尽管它应该是有能力这样做,如果任务没有当选领导人。

这种模式可能不适合:
•如果有一个天生的领导者或专用的过程,可以随时充当领导者。例如,有可能实现一个单进程,其协调该任务的实例。如果这个过程失败或变得不健康,系统可以将其关闭并重新启动它。
•如果任务之间的协调,可以很容易地通过使用更轻便的机构来实现的。例如,如果几个任务实例仅仅需要对共享资源的访问协调,一个最好的解决办法可能是使用乐观或悲观锁来控制访问该资源。
•如果一个第三方的解决方案是比较合适的。例如,微软的Azure HDInsight服务(基于Apache Hadoop的)使用所提供的ApacheZookeeper协调的map / reduce的汇总任务和汇总数据的服务。它也可以安装并在Azure的虚拟机配置动物园管理员,并将其集成到自己的解决方案,或使用可从微软开放技术的动物园管理员预置的虚拟机映像。欲了解更多信息,请参阅Apache的动物园管理员在微软的Azure在微软开放技术的网站。

例子

在列入可用于本指南中的示例代码中LeaderElection解决方案DistributedMutex项目展示了如何使用租赁在Azure存储BLOB提供了一种机制,实现共享的分布式互斥。此互斥锁可以用来选择在Azure云服务的领导者之间的一组角色的实例。第一个角色实例获得租约当选的领导人,并保持领先直至其租赁或直到它无法续租。其他角色实例可以继续监视在领导不再可用的情况下将BLOB租赁。

注意:

一个BLOB租赁是在一个blob的排他写锁。单个BLOB可以是一整租的在任何一个时间点的问题。角色实例可以请求租约在指定的斑点,而且将被授予租约,如果没有其他租赁在同一个斑点,是由这个或任何其他作用,比如举行,否则将抛出一个异常。
为了减少一个故障角色实例保留无限期租用的可能性,指定了一辈子的租约。当此期满后,租赁变为可用。然而,当一个角色实例持有的租赁也可以请求租约到期,并且将被授予租约的时间再延长。角色实例可以不断重复这一过程,如果它希望保留租约。
有关如何租用一个blob的详细信息,请参阅租赁斑点(REST API)在MSDN上。

在该实例中BlobDistributedMutex类包含RunTaskWhenMutexAquired方法,使一个角色实例试图获得租约在指定的斑点。团块(名称,容器和储存的帐户)的细节传递给构造在一个BlobSettings对象被创建的BlobDistributedMutex对象时(这个对象是包含在示例代码的简单结构)。构造函数也接受一个任务,它引用的角色实例应该运行,如果它成功收购租赁在BLOB和当选领导人的代码。需要注意的是处理获得租约的低层次细节中的代码名为BlobLeaseManager一个单独的辅助类实现。

[csharp] view plaincopy

  1. public class BlobDistributedMutex
  2. {
  3. ...
  4. private readonly BlobSettings blobSettings;
  5. private readonly Func<CancellationToken, Task> taskToRunWhenLeaseAcquired;
  6. ...
  7. public BlobDistributedMutex(BlobSettings blobSettings,
  8. Func<CancellationToken, Task> taskToRunWhenLeaseAquired)
  9. {
  10. this.blobSettings = blobSettings;
  11. this.taskToRunWhenLeaseAquired = taskToRunWhenLeaseAquired;
  12. }
  13. public async Task RunTaskWhenMutexAcquired(CancellationToken token)
  14. {
  15. var leaseManager = new BlobLeaseManager(blobSettings);
  16. await this.RunTaskWhenBlobLeaseAcquired(leaseManager, token);
  17. }
  18. ...

代码示例中的RunTaskWhenMutexAquired上述方法调用以下代码示例来实际获得的租赁所示的RunTaskWhenBlobLeaseAcquired方法。该RunTaskWhenBlobLeaseAcquired方法异步运行。如果租赁的成功获取,角色实例已经当选的领导者。该taskToRunWhenLeaseAcquired委托的目的是为了执行协调其它角色实例的工作。如果未取得租赁,另一个角色实例已当选为领导人和当前角色实例仍然是一个下属。注意,TryAcquireLeaseOrWait方法是使用BlobLeaseManager对象获取租赁一个辅助方法。

[csharp] view plaincopy

  1. ...
  2. private async Task RunTaskWhenBlobLeaseAcquired(
  3. BlobLeaseManager leaseManager, CancellationToken token)
  4. {
  5. while (!token.IsCancellationRequested)
  6. {
  7. // Try to acquire the blob lease.
  8. // Otherwise wait for a short time before trying again.
  9. string leaseId = await this.TryAquireLeaseOrWait(leaseManager, token);
  10. if (!string.IsNullOrEmpty(leaseId))
  11. {
  12. // Create a new linked cancellation token source so that if either the
  13. // original token is cancelled or the lease cannot be renewed, the
  14. // leader task can be cancelled.
  15. using (var leaseCts =
  16. CancellationTokenSource.CreateLinkedTokenSource(new[] { token }))
  17. {
  18. // Run the leader task.
  19. var leaderTask = this.taskToRunWhenLeaseAquired.Invoke(leaseCts.Token);
  20. ...
  21. }
  22. }
  23. }
  24. }
  25. ...

由领导开始的任务还异步执行。虽然这个任务正在运行,下面的代码示例所示的RunTaskWhenBlobLeaseAquired方法周期性地尝试续订租约。这个动作有助于确保该角色实例保持领先。在简单解决方案中,续订请求之间的延迟小于对租赁期限,以防止另一角色实例当选的领导人指定的时间。如果更新失败,以任何理由,任务被取消。如果租用未能被更新或任务被取消(可能为角色实例关停的结果),租赁被释放。在这一点上,这个或另一个角色实例可能被选为领导者。下面的代码提取物显示出此过程的一部分。

[csharp] view plaincopy

  1. ...
  2. private async Task RunTaskWhenBlobLeaseAcquired(
  3. BlobLeaseManager leaseManager, CancellationToken token)
  4. {
  5. while (...)
  6. {
  7. ...
  8. if (...)
  9. {
  10. ...
  11. using (var leaseCts = ...)
  12. {
  13. ...
  14. // Keep renewing the lease in regular intervals.
  15. // If the lease cannot be renewed, then the task completes.
  16. var renewLeaseTask =
  17. this.KeepRenewingLease(leaseManager, leaseId, leaseCts.Token);
  18. // When any task completes (either the leader task itself or when it could
  19. // not renew the lease) then cancel the other task.
  20. await CancelAllWhenAnyCompletes(leaderTask, renewLeaseTask, leaseCts);
  21. }
  22. }
  23. }
  24. }
  25. ...
  26. }

该KeepRenewingLease方法是使用BlobLeaseManager对象续租另一个helper方法。该CancelAllWhenAnyCompletes方法取消指定为前两个参数的任务。

图1示出了BlobDistributedMutex类的功能。

图1 - 使用BlobDistributedMutex类选出一个领导者和运行协调操作的任务

下面的代码示例显示了如何使用BlobDistributedMutex类的辅助角色。此代码获取租赁了一个名为MyLeaderCoordinatorTask在开发的仓储租赁容器中的blob,并指定在MyLeaderCoordinatorTask方法定义的代码应该运行,如果角色实例当选的领导人。

[csharp] view plaincopy

  1. var settings = new BlobSettings(CloudStorageAccount.DevelopmentStorageAccount,
  2. "leases", "MyLeaderCoordinatorTask");
  3. var cts = new CancellationTokenSource();
  4. var mutex = new BlobDistributedMutex(settings, MyLeaderCoordinatorTask);
  5. mutex.RunTaskWhenMutexAcquired(this.cts.Token);
  6. ...
  7. // Method that runs if the role instance is elected the leader
  8. private static async Task MyLeaderCoordinatorTask(CancellationToken token)
  9. {
  10. ...
  11. }

请注意有关样品溶液中的以下几点:
•BLOB是一个潜在的单点故障。如果Blob服务不可用,或的blob是人迹罕至,领导者将无法续租,并没有其他的作用,比如将能够获得租约。在这种情况下,没有作用,例如将能够充当领导者。然而,的blob服务被设计为弹性的,所述的blob的服务,以便彻底失败被认为是极不可能的。
•如果被领导者摊位正在执行的任务,领导者可能会继续续租,防止任何其他角色实例从获得租约,并接管了领导作用,以协调任务。在现实世界中,领导者的健康应该频繁地进行检查。
•在选举过程具有不确定性。你不能做任何假设哪个角色实例将得到的blob租约,成为领导者。
•不应使用任何其他目的用作的blob租赁的目标的的blob。如果一个角色实例尝试将数据存储在该的blob,该数据将不能被访问,除非该角色实例是领导者和持有的的blob租约。

本文翻译自MSDN:http://msdn.microsoft.com/en-us/library/dn568104.aspx

时间: 2024-10-19 06:13:37

云计算设计模式(十三)——领导人选举模式的相关文章

云计算设计模式(二十)——调度程序代理管理者模式

云计算设计模式(二十)——调度程序代理管理者模式 协调一系列在分布式服务集和其他远程资源的的行为,试图透明地处理故障,如果这些操作失败,或撤销,如果系统不能从故障中恢复执行工作的影响.这种模式可以分布式系统中增加弹性和灵活性,使之恢复和重试失败是由于短暂的异常,持久的故障和处理故障等操作. 背景和问题 应用程序执行其包括多个步骤,其中的一些可以调用远程服务或访问远程资源的任务.各个步骤可以是相互独立的,但它们是由实现该任务的应用程序逻辑编排. 只要有可能,应用程序应该确保任务运行完成和解决远程访

云计算设计模式系列文章

云计算设计模式(一)——缓存预留模式 云计算设计模式(二)——断路器模式 云计算设计模式(三)——补偿交易模式 云计算设计模式(四)——消费者的竞争模式 云计算设计模式(五)——计算资源整合模式 云计算设计模式(六)——命令和查询职责分离(CQRS)模式 云计算设计模式(七)——事件获取模式 云计算设计模式(八)——外部配置存储模式 云计算设计模式(九)——联合身份模式 云计算设计模式(十)——守门员模式 云计算设计模式(十一)——健康端点监控模式 云计算设计模式(十二)——索引表模式 云计算设

云计算设计模式(二十三)——Throttling节流模式

云计算设计模式(二十三)——Throttling节流模式 控制由应用程序使用,一个单独的租户或整个服务的一个实例的资源的消耗.这种模式可以允许系统继续运行并满足服务水平协议,即使当增加需求的资源放置一个极端载荷. 背景和问题 在云应用负载通常上变化的基础上的活动用户的数量或他们正在执行的活动类型的时间.例如,多个用户可能会在工作时间被激活,否则系统可能被要求在每月结束时执行计算昂贵的分析.也有可能是突然和意外的突发活动.如果系统的处理要求超过了可用的资源的能力,其将遭受性能不佳,甚至会失败.该系

云计算设计模式(二十四)——仆人键模式

云计算设计模式(二十四)——仆人键模式 使用一个令牌或密钥,向客户提供受限制的直接访问特定的资源或服务,以便由应用程序代码卸载数据传输操作.这个模式是在使用云托管的存储系统或队列的应用中特别有用,并且可以最大限度地降低成本,最大限度地提高可扩展性和性能. 背景和问题 客户端程序和网络浏览器经常需要读取和写入文件或数据流,并从一个应用程序的存储空间.通常,应用程序将处理的运动数据,或者通过从存储读取它,并将其传输到客户端,或通过从客户机读取该载流并将其存储在数据存储中.然而,这种方法吸收了宝贵的资

云计算设计模式(十九)——运行重构模式

云计算设计模式(十九)——运行重构模式 设计应用程序,使得它可以在不需要重新部署或者重新启动应用程序重新配置.这有助于保持可用性并减少停机时间. 背景和问题 一个主要目的为重要的应用,如商业和企业网站是尽量减少停机时间以及由此引发的中断给客户和用户.但是,有时有必要重新配置应用程序改变特定行为或设置,而在部署和使用.因此,它是用于该应用程序被设计成这样一种方式,以允许在运行时要应用这些配置的变化,并为应用程序,以检测所述变化并且尽快地应用它们的部件的优点. 该种要应用可能被调整记录,以协助与应用

云计算设计模式(十七)——基于队列的负载均衡模式

云计算设计模式(十七)——基于队列的负载均衡模式 使用队列,作为一项任务,它调用才能顺利间歇重物,可能会以其他方式导致失败的服务或任务超时服务之间的缓冲区.这个模式可以帮助最小化峰中的可用性和响应需求为任务和服务的影响. 背景和问题 许多解决方案在云中涉及运行调用服务的任务.在这种环境下,如果一个服务进行间歇重物,它可能会导致性能或可靠性问题 一个服务可以是一个组件,它是相同的溶液作为利用它的任务的一部分,或者它可以是第三方服务提供访问经常使用的资源,如高速缓存或存储服务.如果相同的服务是由多个

云计算设计模式(十五)——管道和过滤器模式

云计算设计模式(十五)——管道和过滤器模式 分解,执行复杂处理成一系列可重复使用分立元件的一个任务.这种模式可以允许执行的处理进行部署和独立缩放任务元素提高性能,可扩展性和可重用性. 背景和问题 一个应用程序可能需要执行各种关于它处理的信息不同复杂的任务.一个简单,但不灵活的方式来实施这个应用程序可以执行此处理为单一模块.然而,这种方法有可能减少用于重构代码,对其进行优化,或者重新使用它,如果是在应用程序中其他地方所需要的相同的处理的部件的机会. 图1通过使用单片式的方式示出了与处理数据的问题.

云计算设计模式(九)——联合身份模式

云计算设计模式(九)——联合身份模式 验证委托给外部身份提供者.这种模式可以简化开发,最大限度地减少对用户管理的要求,并提高了应用程序的用户体验. 背景和问题 用户通常需要使用由提供,并通过与它们有商业关系的不同组织主持的多个应用程序一起工作.但是,这些用户可能被迫使用特定的(和不同的)的凭证,每一个.这可以: •原因脱节的用户体验.用户经常忘记登录凭据时,他们有很多不同的的. •暴露安全漏洞.当用户离开公司的帐户,必须立即取消设置.这是很容易忽略这在大型组织中. •复杂的用户管理.管理员必须管

云计算设计模式(十)——守门员模式

云计算设计模式(十)——守门员模式 通过使用充当客户端和应用程序或服务之间的代理,验证和进行消毒的请求,并将它们之间的请求和数据的专用主机实例保护的应用程序和服务.这可以提供一个额外的安全层,并限制了系统的攻击面. 背景和问题 应用程序通过接受和处理请求揭露它们的功能提供给客户.在云托管方案,应用程序暴露终端客户机连接,一般包括代码来处理来自客户端的请求.此代码可以执行认证和验证,一些或所有请求的处理,并有可能访问存储等服务代表客户端的. 如果恶意用户能够危及系统和访问应用程序的托管环境,它使用