MetaQ和kafka的部署方式
由上文可知,MetaQ和kafka的元数据节点采用的方式不一样,MetaQ的master和slave都是物理上隔离的,所以对于MetaQ的Broker来说,是支持以下四种方式的部署:
- 单Master:单机模式, 即只有一个Broker, 如果Broker宕机了, 会导致MetaQ服务不可用, 不推荐使用;
- 多Master模式: 组成一个集群, 集群每个节点都是Master节点, 配置简单, 性能也是最高, 某节点宕机重启不会影响MetaQ服务;
缺点是如果某个节点宕机了, 会导致该节点存在未被消费的消息在节点恢复之前不能被消费;
- 多Master多Slave模式,异步复制:每个Master配置一个Slave, 多对Master-Slave, Master与Slave消息采用异步复制方式, 主从消息一致只会有毫秒级的延迟;
优点是弥补了多Master模式(无slave)下节点宕机后在恢复前不可订阅的问题。在Master宕机后, 消费者还可以从Slave节点进行消费。采用异步模式复制,提升了一定的吞吐量。总结一句就是,采用多Master多Slave模式,异步复制模式进行部署,系统将会有较低的延迟和较高的吞吐量;
缺点就是如果Master宕机, 磁盘损坏的情况下, 如果没有及时将消息复制到Slave, 会导致有少量消息丢失;
- 多Master多Slave模式,同步双写:与多Master多Slave模式,异步复制方式基本一致,唯一不同的是消息复制采用同步方式,只有master和slave都写成功以后,才会向客户端返回成功。
优点:数据与服务都无单点,Master宕机情况下,消息无延迟,服务可用性与数据可用性都非常高
缺点就是会降低消息写入的效率,并影响系统的吞吐量;
对于Kafka来说,Broker之间不存在master和slave的区别,每一个Broker之间都是平等的,kafka的partition是有master和slave的区别的,kafka将每个partition数据复制到多个server上,任何一个partition有一个leader和多个follower(可以没有);备份的个数可以通过broker配置文件来设定。leader处理所有的read-write请求,follower需要和leader保持同步。Kafka尽量的使所有分区均匀的分布到集群所有的节点上而不是集中在某些节点上,另外主从关系也尽量均衡这样每个几点都会担任一定比例的分区的leader。
MetaQ和kafka的消息可靠性
在介绍MetaQ和kafka的消息可靠性之前,我们先来介绍一下几个概念:同步异步复制、同步异步刷盘。
1)同步异步复制
同步复制和异步复制的区别在于producer发送消息到master节点之后,是否会等待slave节点复制结束之后再进行返回。
a.同步复制
当生产者将消息发送到broker的master节点时,master会首先将消息复制到所有的slave节点,等待复制动作完成之后,才会给客户端返回“发送成功”的响应,消息可靠性得到保证。
b.异步复制
当生产者将消息发送到broker的master节点时,并不会等待复制动作的结束,会直接返回一个发送成功的状态响应。当出现网络抖动,会导致消息复制不成功,这个时候消息可靠性不够高,消费者消费消息不及时的情况。
2)同步异步刷盘
同步异步刷盘的区别在于,消息存储在内存(memory)中以后,是否会等待执行完刷盘动作再返回,即是否会等待将消息中的消息写入磁盘中。
a. 异步刷盘
当消息写入到broker的内存中之后即返回写成功状态,并不会等待消息从内存中写入磁盘就返回。所以写操作的返回快,吞吐量大;当内存里的消息量积累到一定程度时,统一触发写磁盘操作,快速写入。
b. 同步刷盘
当消息被写入到内存之后,会立刻会立刻通知刷盘线程刷盘,然后等待刷盘完成,刷盘线程执行完成后唤醒等待的线程,返回消息写成功的状态。所以当返回写成功状态的时候,消息已经被写入磁盘了。
MetaQ和kafka都支持同步异步复制以及同步异步刷盘。
MetaQ的同步异步复制是通过Broker的配置文件中的brokerRole参数进行设置的,这个参数可以被设置成ASYNC_MASTER、SYNC_MASTER、SLAVE三个值中的一个。其中ASYNC_MASTER表示的是当前broker的角色是一个异步复制的master,生产者写入消息到Master后无需等待消息复制到slave即可返回;SYNC_MASTER表示当前的broker的角色是一个同步复制的master,Master写入完消息之后,需要等待Slave的复制成功,但是这边注意这里只需要有一个Slave复制成功并成功应答即算成功;SLAVE表示的是当前broker是一个slave。
MetaQ的同步异步刷盘是通过Broker配置文件里的flushDiskType参数设置的,这个参数被设置成SYNC_FLUSH, ASYNC_FLUSH中的一个,其中SYNC_FLUSH表示同步刷盘,ASYNC_FLUSH表示异步刷盘。
Kafka的同步异步复制可以通过acks配置来实现,当acks的参数设置为0,表示生产者把消息发送出去之后,不管消息有没有被接收,直接就认为消息发送成功;当acks的参数设置为1,表示生产者把消息发送出去之后,就认为消息发送成功,而不管其他的slave是否同步这个消息,相当于异步复制,该配置为kafka的默认配置;当acks的参数设置为all,表示生产者把消息发送出去之后,master收到消息之后,还必须等待ISR列表中跟master保持同步的那些slave都进行消息同步之后,才认为消息写入成功,相当于同步复制。
kafka可以通过配置flush.message和flush.ms来设置刷盘策略,如果flush.message设置为5,表示每5条消息进行一次刷盘,如果flush.message设置为1,表示每一条消息都进行一次刷盘。如果flush.ms设置为1000,表示每过1000ms进行一次刷盘,如果flush.ms设置为5000,表示每过5000ms进行一次刷盘。