分布式消息系统研究报告之Kafka

最近在看消息系统方面的东西。作为一个实践主义者,在看消息系统的各种实现时,不妨先粗略思考一下如何设计一个消息系统。我总觉出来有这么几个点(比较粗陋,以后继续补充):

  1. 队列的存储和管理

    用什么方式存储消息决定了这个消息系统的最终表现。

  2. push还是pull

    producer没啥好说的,肯定是push,这里主要说consumer,pull的好处是可以根据consumer消费能力来处理消息,而push的好处则是实时性

  3. 服务横向扩展

    是否存在单点?如何进行横向扩展的?failover如何做?

  4. 保证一次消费

    消息不丢失;不会重复消费。

  5. topic模式

    是否支持单条message多个comsumer同时消费?用什么机制保证其工作?

  6. 监控

    有没有监控手段?

好了,现在先来看Kafka。Kafka是LinkedIn的一个消息系统。主要用来处理日志并进行实时分析。
Kafka有一篇翻译好的文章http://www.oschina.net/translate/kafka-design。

Kafka要解决的是大吞吐量下的消息队列问题。

  1. 队列过长时,很多消息系统都不给力
    Kafka使用文件系统来进行存储,基本没有什么限制。文件都是立刻flush。
  2. 将消息打包成MessageSet,本身是Buffer的思想,例如nagle算法
  3. 消息压缩 支持GZIP
  4. 将消息强制排序,并用“最高水位标记”(high water mark)“来记录消费者状态
  5. 用groupId+atomicInteger代替guid来标识每一条消息,减少复杂性

一些与结构无关的notes:

  1. Java实用sendfile FileChannel.transferTo

  2. flush与分页缓存的关系

实际中这么做意味着,数据被传输到OS内核的页面缓存中了,OS随后会将这些数据刷新到磁盘的。
这段话的思路可以考虑一下。

  1. 问题4的科学称呼:消息传递语义(Message delivery semantics)

    系统可以提供的几种可能的消息传递保障如下所示:

    1. 最多一次—这种用于处理前段文字所述的第一种情况。消息在发出后立即标示为已使用,因此消息不会被发出去两次,但这在许多故障中都会导致消息丢失。

    2. 至少一次—这种用于处理前文所述的第二种情况,系统保证每条消息至少会发送一次,但在有故障的情况下可能会导致重复发送。

    3. 仅仅一次—这种是人们实际想要的,每条消息只会而且仅会发送一次。

    这个问题已得到广泛的研究,属于“事务提交”问题的一个变种。提供仅仅一次语义的算法已经有了,两阶段或者三阶段提交法以及Paxos算法的一些变种就是其中的一些例子,但它们都有与生俱来的的缺陷。这些算法往往需要多个网络往返(round trip),可能也无法很好的保证其活性(liveness)(它们可能会导致无限期停机)。FLP结果给出了这些算法的一些基本的局限。

你可能感兴趣的:(kafka,MQ)