分布式后台任务负载均衡方式

2021-08-14 18:04:16 浏览数 (1)

一.引言

系统服务按运行模式可以简单划分为接口服务(外界使用tcp/http等方式触发服务)和后台任务(后台一次性/周期性触发任务)。对于接口服务,在分布式场景下使用负载均衡(DNS/NAT/ARP等方式都是可选的软件负载均衡方式)是常见的提高系统可用性和扩展性的方式。

接口场景下的负载均衡接口场景下的负载均衡

对于后台任务,在分布式场景下是否有相应的负载均衡方式,可以提高系统的可用性和扩展性呢?

任务场景下的负载均衡如何实现任务场景下的负载均衡如何实现

二.后台任务负载均衡方式

后台任务的典型应用场景是生产者-消费者模型,假设task以关系型数据库的方式发布。

抢占式

抢占式即各个consumer获取到任务即锁住,确保该任务不会被其他consumer重复消费。

对于使用关系型数据库进行任务发布的场景,可以在任务中引入状态位避免任务被重复消费。以下是一个比较通用的任务状态扭转示例。任务发布时,会经历CREATED, DELETED, READY三个状态,任务消费时,会经历RUNNING, SUCCESS, FAIL三个状态。其中READY状态属于可抢占状态,consumer获取后立即设置为RUNNING,并根据运行结果设置SUCCESS或者FAIL。

协商式

抢占式需要对任务进行改造,引入状态位。协商式则不需要改造任务,而是通过引入注册中心的方式,进行一致性哈希分发任务到各个consumer。

以下是使用关系型数据库作为注册中心的示例。service_name标识消费者类型,instance_name使用{host_ip}:{process_id}标识每一个消费者任务进程,expired_time_stamp标识该消费者任务进程有效截止时间,created_time_stamp标识该消费者任务进程注册时间。

每个消费者都能获取到该全局注册视图,并使用一致性哈希方式来获取到相应的任务。

instance_name

expired_time_stamp

created_time_stamp

10.104.63.157/1082

2021-08-09 01:22:39

2021-08-08 13:22:39

10.104.63.157/1083

2021-08-09 01:22:38

2021-08-08 13:22:38

10.104.63.157/1085

2021-08-09 01:22:38

2021-08-08 13:22:38

10.104.63.157/1087

2021-08-09 01:22:38

2021-08-08 13:22:38

一致性哈希,是指对消费者和待处理任务都进行哈希映射,待处理任务归属于顺时针最近的消费者。相比于普通哈希,一致性哈希拥有良好的单调性,即新增消费者时,待处理数据会被映射到新增消费者或者原有消费者。

下图给出了消费者新增和消费者失效场景的数据映射关系,可见一致性哈希极大减少了扩缩容场景下的数据迁移。

三. 扩展与总结

在分布式任务系统中,采用上述方式进行负载均衡,还有以下两个问题需要考虑

Exactly Once问题

无论是抢占式还是协商式任务分发,提供的是at least once的服务。大部分场景都可以做到exactly once,但是极端场景下还是会有任务被重复消费的可能。一方面可以引入task lock机制来确保exactly once,一方面也可以由业务侧来消除任务被重复消费的影响。

多队列问题

多队列是指任务区分类型,每个任务即一个任务队列。对于抢占式可以通过在任务中引入task_type来实现;对于协商式可以通过在注册表中引入task_name来实现,每一类task_type即形成一个哈希分发环。

task_type

instance_name

expired_time_stamp

created_time_stamp

task_a

10.104.63.157/1082

2021-08-09 01:22:39

2021-08-08 13:22:39

task_a

10.104.63.157/1083

2021-08-09 01:22:38

2021-08-08 13:22:38

task_b

10.104.63.157/1085

2021-08-09 01:22:38

2021-08-08 13:22:38

task_b

10.104.63.157/1087

2021-08-09 01:22:38

2021-08-08 13:22:38

总结下,抢占式和协调式在实际应用中,都能提供高可用且易于水平扩展,且不需要任务之间相互通信感知,易于实现。

实现特征

实现机制

是否支持多机多进程

是否支持exactly once

是否支持多对列

抢占式

状态机

支持

at least once

任务可引入task_type支持

协调式

服务注册 一致性哈希

支持

at least once

注册表可引入task_type

0 人点赞