消息队列有哪些 消息队列( 六 )


生产者
负载均衡: producer将会和Topic下所有partition leader保持socket连接;消息由producer直接通过socket发送到broker , 中间不会经过任何“路由层“ 。事实上 , 消息被路由到哪个partition上 , 有producer客户端决定 。比如可以采用“random““key-hash““轮询“等 , 如果一个topic中有多个partitions , 那么在producer端实现“消息均衡分发“是必要的 。
其中partition leader的位置(host:port)注册在zookeeper中 , producer作为zookeeper client , 已经注册了watch用来监听partition leader的变更事件 。
异步发送:将多条消息暂且在客户端buffer起来 , 并将他们批量的发送到broker , 小数据IO太多 , 会拖慢整体的网络延迟 , 批量延迟发送事实上提升了网络效率 。不过这也有一定的隐患 , 比如说当producer失效时 , 那些尚未发送的消息将会丢失 。
消费者
consumer端向broker发送“fetch”请求 , 并告知其获取消息的offset;此后consumer将会获得一定条数的消息;consumer端也可以重置offset来重新消费消息 。
在JMS实现中 , Topic模型基于push方式 , 即broker将消息推送给consumer端 。不过在kafka中 , 采用了pull方式 , 即consumer在和broker建立连接之后 , 主动去pull(或者说fetch)消息;这中模式有些优点 , 首先consumer端可以根据自己的消费能力适时的去fetch消息并处理 , 且可以控制消息消费的进度(offset);此外 , 消费者可以良好的控制消息消费的数量 , batch fetch 。
其他JMS实现 , 消息消费的位置是有prodiver保留 , 以便避免重复发送消息或者将没有消费成功的消息重发等 , 同时还要控制消息的状态 。这就要求JMS broker需要太多额外的工作 。在kafka中 , partition中的消息只有一个consumer在消费 , 且不存在消息状态的控制 , 也没有复杂的消息确认机制 , 可见kafka broker端是相当轻量级的 。当消息被consumer接收之后 , consumer可以在本地保存最后消息的offset , 并间歇性的向zookeeper注册offset 。由此可见 , consumer客户端也很轻量级 。
对于JMS实现 , 消息传输担保非常直接:有且只有一次(exactly once) 。
在kafka中稍有不同:
at most once: 消费者fetch消息 , 然后保存offset , 然后处理消息;当client保存offset之后 , 但是在消息处理过程中出现了异常 , 导致部分消息未能继续处理 。那么此后"未处理"的消息将不能被fetch到 , 这就是"at most once" 。
at least once: 消费者fetch消息 , 然后处理消息 , 然后保存offset 。如果消息处理成功之后 , 但是在保存offset阶段zookeeper异常导致保存操作未能执行成功 , 这就导致接下来再次fetch时可能获得上次已经处理过的消息 , 这就是"at least once" , 原因offset没有及时的提交给zookeeper , zookeeper恢复正常还是之前offset状态 。
exactly once: kafka中并没有严格的去实现(基于2阶段提交 , 事务) , 我们认为这种策略在kafka中是没有必要的 。
通常情况下“at-least-once”是我们首选 。(相比at most once而言 , 重复接收数据总比丢失数据要好) 。
kafka高可用由多个broker组成 , 每个broker是一个节点;
创建一个topic , 这个topic会划分为多个partition , 每个partition存在于不同的broker上 , 每个partition就放一部分数据 。
kafka是一个分布式消息队列 , 就是说一个topic的数据 , 是分散放在不同的机器上 , 每个机器就放一部分数据 。
在0.8版本以前 , 是没有HA机制的 , 就是任何一个broker宕机了 , 那个broker上的partition就废了 , 没法写也没法读 , 没有什么高可用性可言 。
0.8版本以后 , 才提供了HA机制 , 也就是就是replica副本机制 。每个partition的数据都会同步到其他的机器上 , 形成自己的多个replica副本 。然后所有replica会选举一个leader出来 , 那么生产和消费都跟这个leader打交道 , 然后其他replica就是follower 。
写的时候 , leader会负责把数据同步到所有follower上去 , 读的时候就直接读leader上数据即可 。

秒懂生活扩展阅读