MetaQ的使用

MetaQ是什么

meatq是阿里团队的消息中间件。是支撑双11最为核心的系统之一。

MetaQ的使用目的

解耦收发双方,使得系统异步化,同时利用消息中间件堆积消息的功能,可以使得下游系统在可以慢慢消费消息,增强系统的缓冲能力,达到“削峰填谷”的目的
学习MetaQ思维导图

适合的应用

  • 日志传输,高吞吐量的日志传输本来就是kafka的强项
  • 消息广播功能,如广播缓存配置失效。
  • 数据的顺序同步功能,如mysql binlog复制
  • 分布式环境下(broker,producer,consumer都为集群)的消息路由,对顺序和* 可靠性有极高要求的场景。
  • 作为一般MQ来使用的其他功能

mete与Kafka的区别

Kafka是scala写的,传说kafka整个社区发展缓慢
有些功能kafka没有实现,但我却需要:事务、多种offset存储、高可用方案(HA)等
meta的对于kafka特有的区别:

  • 文本协议设计,非常透明,支持类似memcached stats的协议来监控broker
  • 纯Java实现,从通讯到存储,从client到server都是重新实现。
  • 提供事务支持,包括本地事务和XA分布式事务
  • 支持HA复制,包括异步复制和同步复制,保证消息的可靠性
  • 支持异步发送消息
  • 消费消息失败,支持本地恢复
  • 多种offset存储支持,数据库、磁盘、zookeeper,可自定义实现
  • 支持group commit,提升数据可靠性和吞吐量。
  • 支持消息广播模式
  • 一系列配套项目:python客户端、twitter storm的spout、tail4j等。

概念和术语

在学习metaQ是会涉及到一些术语,专业名词,什么的让我们先来了解这些名词,当我们在学习时遇到这些名词时让我们知道这个是干什么用的。

消息生产者

也称为Message Producer(/prə’djuːsə/制作人),一般简称为producer,负责产生消息并发送消息到meta服务器。

消息消费者

也称为Message Consumer(/kən’sjuːmə/消费者),一般简称为consumer,负责消息的消费,meta采用pull模型,由消费者主动从meta服务器拉取数据并解析成消息并消费。

Topic

消息的主题。用户定义并在服务器端配置。producer发送消息到某个topic下,consumer从某个topic下消费消息

分区(partition /pɑː’tɪʃ(ə)n/)

同一个topic(/'tɒpɪk/)下面还有分为多个分区,如meta-test这个topic我们可以分为10个分区,分别有两台服务器提供,那么可能每台服务器提供5个分区,假设服务器id分为0和1,则所有分区为0-0、0-1、0-2、0-3、0-4、1-0、1-1、1-2、1-3、1-4
分区跟消费者的负载均衡机制有很大关系。

集群和负载均衡

集群

Meta假定producer、broker(经纪人/ˈbrəʊkə®/)和consumer都是分布式的集群系统。
Producer可以是一个集群,多台服务器上的producer可以往同一个topic发送消息。Meta的服务器broker一般也是一个集群,多台broker组成一个集群提供一些topic服务,生产者按照一定的路由规则往集群里某台broker发送消息。
Consumer也可以组织成一个集群来消费同一个topic,发往这个topic的消息按照一定的路由规则发送到consumer集群里的某一台机器。Consumer集群每个conseumer必须拥有相同的分组名称。

Broker集群配置

Broker集群配置非常容易,假设你已经配置并启用了你的第一台broker,某一天你发现这个单台broker无法支撑更大的消息量,那么你可能就需要引入更多的broker作为集群来提供服务。

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

负载均衡和failover(/feil’əuvər/故障切换,失效备援-为系统备援能力的一种,当系统其中一项设备失效而无法运作时,另一项设备即可自动接手原失效系统所执行的工作)分不开,我们将分别讨论下生产者和消费者的负载均衡策略。我们先假定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消费者列表),然后重新进行负载均衡,保证所有的分区都有消费者进行消费。

Message

消息。负载用户数据并在生产者、服务端和消费者之间传输

Broker

就是meta的服务端或者说是服务器,在消息中间件中也通常称为broker

消费者分组(Group)

消费者可以是多个消费者共同消费一个topic下的消息。每个消费者消费部分消息。这些消息就组成一个分组。拥有同一个分组名称,通常也称为消费者集群。

Offset(/'ɒfset/抵消,补偿,偏移量)

消息在broker上的每个分区都是组成一个文件列表,消费者拉取数据需要知道数据在文件中偏移量,在这个偏移量及时所谓额offest。Offset是绝对偏移量,服务器会将offset转化为具体文件的相对偏移量。

消息的可靠性、顺序和重复

可靠性

其可靠性保证贯穿客户端和服务器

生产者的可靠性保证

消息生产者发送消息后返回SendResult(/rɪ’zʌlt/发送结果),如果isSuccess返回为true,则表示消息已经确认发送到服务器并被服务器接收存储。整个过程是一个同步的过程。保证消息送达服务器并返回结果。

服务器的可靠性保证

消息生产者发送的消息,meta服务器收到后做在必要的校验和检查之后的第一件事就是写入磁盘,写入成功之后返回应答给生产者。因此,确认每条放结果为成功的消息都是写入磁盘的。
写入磁盘,不意味着数据落到磁盘设备上,毕竟我们还隔着一层os(操作系统,操作系统控制设备的写入缓存,有时候断电就会丢东西),os对写有缓冲。Meta有两个特性来保证数据落在磁盘上

  • 每1000条(可配置),即强调用一次force来写入磁盘设备。
  • 每个10秒(可配置),即强调用一次force来写入磁盘设备。

因此,Meta通过配置可以保证在异常情况下(如磁盘掉电)10秒内最多丢失1000条消息。当然通过参数调整你甚至可以在掉电情况下不丢失任何消息。
服务器通常组织为一个集群,一条从生产者过来的消息可能按照路由规则存储到集群中的某台机器。
Meta已经实现高可用的HA(High Available,中文:双机集群系统)方案,类似MySQL的同步和异步复制,将一台meta服务器的数据完全复制到另一个台slave服务器,并且slace服务器还提供消费者功能(同步复制不提供消费)
HA–“是保证业务连续性的有效解决方案,一般有两个或两个以上的节点,且分为活动节点及备用节点。通常把正在执行业务的称为活动节点,而作为活动节点的一个备份的则称为备用节点。当活动节点出现问题,导致正在运行的业务(任务)不能正常运行时,备用节点此时就会侦测到,并立即接续活动节点来执行业务。从而实现业务的不中断或短暂中断。”

消费者的可靠性保证

massage的消费者是一条接着一条地消费消息,只有在成功消费一条消息后才会接着消费消费下一条。如果在消费某条消息失败(如异常),则会尝试重试消费这条消息(默认最大5次),超过最大次数后仍然无法消费,则将消息存储在消费者的本地磁盘,由后台线程继续做重试。而主线程继续往后走,消费后续的消息。因此,有在massageListener确认成功消费一条消息后,meta的消费者才会继续消费另一条消息。由此来保证消息的可靠消费。
消费的另一个可靠性的关键电视offset的存储,也就是拉取数据的偏移量。我们目前提供存储方案:

  • Zookeeper,默认存储在Zookeeper上,Zookeeper通过集群来保证数据的安全性。
  • MySQL,可以连接使用MySQL数据库,只要建立一张特定的表存储。完全由数据库来保证数据的可靠性。
  • file,文件存储。将offset信息存储在消费者本地文件中。
    Offset会定期保存,并且在每次重新负载均衡前都会强制保存一次。

顺序

很多人会关心,消息的顺序,希望消费者消费消息的顺序跟消息发送的顺序是一致的。比如,我发送消息顺序是abc,那么消费者消费的顺序也应该是abc。乱序对某些应用可能无法接受。
MQ对消息的顺序性的保证是有限的,默认情况下,消息的顺序以谁先达到服务器并写入磁盘,则谁就在先的原则处理。并且,发往同一个分区的消息保证按照写入磁盘的顺序让消费者消费。这是因为消费者针对每个分区都是按照从前到后递增offset的顺序拉取消息。
Meta可以保证,在单线程内使用producer发送的消息按照发送顺序达到服务器并存储,并按照相同顺序被消费,前提是这些消息发往同一台服务器的同一个分区。为了实现这一点,你还需要实现自己的PartitionSelector用于固定选择分区

public interface PartitionSelector {
    public Partition getPartition(String topic, List<Partition> partitions, Message message) throws MetaClientException;
}

选择分区可以按照一定的业务逻辑来选择,如根据业务id来取模。或者如果是传输文件,可以固定选择第n个分区使用。当然,如果传输文件,通常我们会建议你只配置一个分区,那也就无需选择了。

消息的顺序发送我们在1.2这个版本提供了OrderedMessageProducer,自定义管理分区信息,并提供故障情况下的本地存储功能。

消息重复

消息的重复包含两个方面,生产者重复发送消息以及消费者重复消费消息。

针对生产者来说,有可能发生这种情况,生产者发送消息,等待服务器应答,这个时候发生网络故障,服务器实际已经将消息写入成功,但是由于网络故障没有返回应答。那么生产者会认为发送失败,则再次发送同一条消息,如果发送成功,则服务器实际存储两条相同的消息。这种由故障引起的重复,meta是无法避免的,因为meta不判断消息的data是否一致,因为它并不理解data的语义,而仅仅是作为载荷来传输。

针对消费者来说也有这个问题,消费者成功消费一条消息,但是此时断电,没有及时将前进后的offset存储起来,则下次启动的时候或者其他同个分组的消费者owner到这个分区的时候,会重复消费该条消息。这种情况meta也无法完全避免。

Meta对消息重复的保证只能说在正常情况下保证不重复,异常情况无法保证,这些限制是由远程调用的语义引起的,要做到完全不重复的代价很高,meta暂时不会考虑。

开始使用MetaQ

文件下载

  1. Meta环境选择安装在虚拟机Linux Centos 7上。
  2. 为了方便快捷的开始使用,我选择使用yum的安装方式安装jdk,使用下条命令
    yum install java-1.8.0-openjdk* -y
  3. 把下载好的MetaQ安装包复制到Linux虚拟机上
  4. 在服务器上打开
    目录展示
    MetaQ目录结构
  5. 启动脚本放在bin目录下,主要的脚本是metaServer.sh
    日志在logs目录
    配置文件主要是conf目录下的server.ini,lib存放所有的依赖jar包,1,。4.6新增加的provided目录用于存放服务器的消息过滤器实现打包后的jar包以及用到的第三方依赖。
    MetaQ运行
    开启服务器命令,运行服务器效果图如上
    bin/metaServer.sh start local
    关闭服务器:
    bin/metaServer.sh stop
    查看服务器器是否正常运行
    MetaQ正常运行

参考文献

https://github.com/killme2008/Metamorphosis/wiki

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

园长的牧歌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值