j2ee绿洲

找到属于自己的一片天空
数据加载中……
metamorphosis-7-集群与负载均衡

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

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

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

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

Broker集群配置

Broker集群配置非常容易,假设你已经按照如何开始服务器配置管理配置好并启用了你第一台broker,某一天你发现这个单台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上的一个分区来发送消息,默认的策略是一个轮询的路由规则,一张图来表示

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

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

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

消费者的负载均衡

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

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

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

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

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

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

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

posted on 2012-11-23 09:58 心情经纬 阅读(611) 评论(0)  编辑  收藏 所属分类: 消息队列专题


只有注册用户登录后才能发表评论。


网站导航: