集群-metaq

集群

Meta假定producer、broker和consumer都是分布式的集群系统。

Producer可以是一个集群,多台机器上的producer可以往同一个topic发送消息。

Meta的服务器broker一般也是一个集群,多台broker组成一个集群提供一些topic服务,生产者按照一定的路由规则往集群里某台broker发送消息,消费者按照一定的路由规则拉取某台broker上的消息。

Consumer也可以组织成一个集群来消费同一个topic,发往这个topic的消息按照一定的路由规则发送到consumer集群里的某一台机器。Consumer集群每个consumer必须拥有相同的分组名称。

Broker集群配置

Broker集群配置非常容易:

  • 拷贝broker1的配置文件conf/server.ini到新的broker,假设为broker2。
  • 修改broker2的server.ini,只要修改brokerId为另一个不同于broker1的值即可
  • 启动broker2,这样一来broker2将和broker1组成一个服务器集群
  • 在这个过程中你不需要重启任何现有的服务,包括生产者、消费者和broker1,他们都将自动感知到新的broker2

可见,配置一个集群唯一要做的就是使用同一份配置文件并定义不同的brokerId即可。

负载均衡

负载均衡和failover分不开,我们将分别讨论下生产者和消费者的负载均衡策略。我们先假定broker是一个集群,这样每个topic必定有多个分区。

生产者的负载均衡和failover

每个broker都可以配置一个topic可以有多少个分区,但是在生产者看来,一个topic在所有broker上的的所有分区组成一个分区列表来使用。

在创建producer的时候,客户端会从zookeeper上获取publish的topic对应的broker和分区列表,生产者在发送消息的时候必须选择一台broker上的一个分区来发送消息,默认的策略是一个轮询的路由规则,一张图来表示

producer-cluster

生产者在通过zk获取分区列表之后,会按照brokerId和partition的顺序排列组织成一个有序的分区列表,发送的时候按照从头到尾循环往复的方式选择一个分区来发送消息。考虑到我们的broker服务器软硬件配置基本一致,默认的轮询策略已然足够。

如果你想实现自己的负载均衡策略,可以实现上文提到过的PartitionSelector接口,并在创建producer的时候传入即可。

在broker因为重启或者故障等因素无法服务的时候,producer通过zookeeper会感知到这个变化,将失效的分区从列表中移除做到fail over。因为从故障到感知变化有一个延迟,可能在那一瞬间会有部分的消息发送失败。

消费者的负载均衡

消费者的负载均衡会相对复杂一些。我们这里讨论的是单个分组内的消费者集群的负载均衡,不同分组的负载均衡互不干扰,没有讨论的必要。 消费者的负载均衡跟topic的分区数目紧密相关,要考察几个场景。 首先是,单个分组内的消费者数目如果比总的分区数目多的话,则多出来的消费者不参与消费,如图

consumer-cluster1

其次,如果分组内的消费者数目比分区数目小,则有部分消费者要额外承担消息的消费任务,具体见示例图如下

image-cluster2

综上所述,单个分组内的消费者集群的负载均衡策略如下

  • 每个分区针对同一个group只挂载一个消费者
  • 如果同一个group的消费者数目大于分区数目,则多出来的消费者将不参与消费
  • 如果同一个group的消费者数目小于分区数目,则有部分消费者需要额外承担消费任务

Meta的客户端会自动帮处理消费者的负载均衡,它会将消费者列表和分区列表分别排序,然后按照上述规则做合理的挂载。

从上述内容来看,合理地设置分区数目至关重要。如果分区数目太小,则有部分消费者可能闲置,如果分区数目太大,则对服务器的性能有影响。

在某个消费者故障或者重启等情况下,其他消费者会感知到这一变化(通过 zookeeper watch消费者列表),然后重新进行负载均衡,保证所有的分区都有消费者进行消费。

来自淘宝

猜你喜欢

转载自soledede.iteye.com/blog/1953359