MetaQ初探
http://yale.iteye.com/blog/1856916
http://www.cnblogs.com/muzhongjiang/p/3757586.html
MetaQ(全称Metamorphosis)是一个高性能、高可用、可扩展的分布式消息中间件,,MetaQ具有消息存储顺序写、吞吐量大和支持本地和XA事务等特性,适用于大吞吐量、顺序消息、广播和日志数据传输等场景,METAQ在阿里巴巴各个子公司被广泛应用,每天转发250亿+条消息。主要应用于异步解耦,Mysql数据复制,收集日志等场景。
总体结构
主要特点
- 生产者、服务器和消费者都可分布式
- 消息存储顺序写
- 性能极高,吞吐量大
- 支持消息顺序
- 支持本地和XA事务
- 客户端pull,随机读,利用sendfile系统调用,zero-copy ,批量拉数据
- 支持消费端事务
- 支持消息广播模式
- 支持异步发送消息
- 支持http协议
- 支持消息重试和recover
- 数据迁移、扩容对用户透明
- 消费状态保存在客户端
- 支持同步和异步复制两种HA
主要特性
数据完整性
消息生产者发送的消息,meta服务器收到后在做必要的校验和检查之后的第一件事就是写入磁盘,写入成功之后返回应答给生产者,生产者发送消息返回SendResult,如果isSuccess返回为true,则表示消息已经确认发送到服务器并被服务器接收存储。整个发送过程是一个同步的过程。保证消息送达服务器并返回结果。因此,可以确认每条发送结果为成功的消息服务器都是写入磁盘的。
写入磁盘,不意味着数据落到磁盘设备上,毕竟我们还隔着一层os,os对写有缓冲。Meta有两个特性来保证数据落到磁盘上:每1000条(可配置),即强制调用一次force来写入磁盘设备。每隔10秒(可配置),强制调用一次force来写入磁盘设备。因此,Meta通过配置可保证在异常情况下(如磁盘掉电)10秒内最多丢失1000条消息。当然通过参数调整你甚至可以在掉电情况下不丢失任何消息。
虽然消息在发送到broker之后立即写入磁盘才返回客户端告诉消息生产者消息发送成功,通过unflushThreshold和unflushInterval两个参数的控制,可以保证单机消息数据的安全性,只要机器的磁盘没有永久损坏,消息总可以在重启后恢复并正常投递给消费者们。但是,如果遇到了磁盘永久损坏或者数据文件永久损坏的情况,那么该broker上的消息数据将可能永久丢失。为了防止这种情况的发生,一个可行的方案就是将消息数据复制到多台机器,类似mysql的主从复制功能(异步复制和同步功能)
数据可靠性
服务器通常组织为一个集群,一条从生产者过来的消息可能按照路由规则存储到集群中的某台机器。Meta已经实现高可用的HA方案,类似mysql的同步和异步复制,将一台meta服务器的数据完整复制到另一台slave服务器,并且slave服务器还提供消费功能(同步复制不提供消费)。消息的消费者是一条接着一条地消费消息,只有在成功消费一条消息后才会接着消费下一条。如果在消费某条消息失败(如异常),则会尝试重试消费这条消息(默认最大5次),超过最大次数后仍然无法消费,则将消息存储在消费者的本地磁盘,由后台线程继续做重试。而主线程继续往后走,消费后续的消息。因此,只有在MessageListener确认成功消费一条消息后,meta的消费者才会继续消费另一条消息。由此来保证消息的可靠消费。
消费者的另一个可靠性的关键点是offset的存储,也就是拉取数据的偏移量。我们目前提供了以下几种存储方案zookeeper,默认存储在zoopkeeper上,zookeeper通过集群来保证数据的安全性。mysql,可以连接到您使用的mysql数据库,只要建立一张特定的表来存储。完全由数据库来保证数据的可靠性。file,文件存储,将offset信息存储在消费者的本地文件中。Offset会定期保存,并且在每次重新负载均衡前都会强制保存一次
下载、配置、运行
首先需要安装配置Zookeeper,如果不知道怎么配置的,看我的文章,有一章讲解过!
https://code.google.com/p/meta-queue/downloads/list选择最新版本的服务器并下载到本地解压缩文件,bin目录存放的脚本文件,日志在logs目录,而配置文件主要是conf目录下server.ini,lib存放所有的依赖jar包。
zk.zkConnect=localhost:2181 zk的服务器列表
zk.zkSessionTimeoutMs=30000 zk心跳超时,单位毫秒,默认30秒 zk.zkSessionTimeoutMs=30000
zk.zkConnectionTimeoutMs=30000 zk连接超时时间,单位毫秒,默认30秒
zk.zkSyncTimeMs=5000 zk数据同步时间,单位毫秒,默认5秒
brokerId:服务器ID(必须是集群内唯一)
serverPort:服务器端口
hostName:默认将取本机IP (多机网卡,需要指明)
dataLogPath:日志数据文件路径,默认跟dataPath一样
dataPath:于指定默认的数据存储路径(慎重设置,默认在user.home/meta下)
numPartitions:默认topic的分区数目(慎重设置)
maxSegmentSize:单个文件的最大大小,实际会超过此值,默认1G
maxTransferSize:传输给客户端每次最大的缓冲区大小,默认1M
unflushThreshold:最大允许的未flush间隔时间,毫秒,默认10秒
putProcessThreadCount:;处理put请求线程数,默认cpus*10
deletePolicy=delete,168(数据删除策略,默认超过7天即删除,这里的168是小时,10s表示10秒,10m表示10分钟,10h表示10小时,默认为小时)
deleteWhen: 何时执行删除策略的cron表达式,默认是0 0 6,18 * * ?,也就是每天的早晚6点执行处理策略。deleteWhen: 删除策略的执行时间,cron表达式
maxCheckpoints: 最大保存事务checkpoint数目,默认为3
checkpointInterval: 事务checkpoint时间间隔,单位毫秒,默认1小时(3600000)
maxTxTimeoutTimerCapacity=30000最大事务超时事件数,用于监控事务超时
maxTxTimeoutInSeconds=60最大事务超时时间,单位秒
flushTxLogAtCommit=1事务日志的同步设置,0表示让操作系统决定,1表示每次commit都同步,2表示每隔1秒同步一次,此参数严重影响事务性能,可根据你需要的性能和可靠性之间权衡做出一个合理的选择。通常建议设置为2,表示每隔1秒刷盘一次,也就是最多丢失一秒内的运行时事务。这样的可靠级别对大多数服务是足够的。最安全的当然是设置为1,但是将严重影响事务性能。而0的安全级别最低。安全级别上 1>=2>0,而性能则是0 >= 2 > 1。
diamondZKGroup=DEFAULT_GROUP zk在diamond中配置存储的group
acceptPublish: 是否接收消息,默认为true;如果为false,则不会注册发送信息到zookeeper上,客户端当然无法发送消息到该broker。本参数可以被后续的topic配置覆盖。
acceptSubscribe: 与acceptPublish类似,默认也为true;如果为false,则不会注册消费信息到zookeeper上,消费者无法发现该broker,当然无法从该broker消费消息。本参数可以被后续的topic配置覆盖。
unflushInterval: 间隔多少毫秒定期做一次磁盘sync,默认是10秒。也就是说在服务器掉电情况下,最多丢失10秒内发送过来的消息。不可设置为小于或者等于0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|