kafka
- 一个topic多个partition,一个partition一主多从,leader承担所有的读写,然后同步到follower。
- 老版本producer/consumer需要直接和zk交互,新版本直接和broker交互,因为zk写性能不好。
- producer内部维护内存队列,异步一定间隔或数量发送到broker,失败的话,默认重试3次;同步发送,需要实时调用flush。
- 每个partition分布在不同server,一个partition只能被同组的一个consumer消费,一个consumer可以消费多个partition,所以一个topic在多个partition的情况下是无法保证有序的,为了简单和有序,consumer的数量不能大于partition的数量。
- 某个消息只有当所有follower都保存成功,这条消息才能被消费。
- 一旦出现leader出现故障,follower选举新leader时,可能遇到所有follower都落后于leader的情况,这时候可以选择最新的follower成为leader,但是可能碰到partition过多的问题。
- kafka使用pull模式,好处是消费速度可控,消费进度也可控。
- kafka消息投递机制推荐至少一次投递,如果未接收成功重新投递直到成功,对于服务端而言,重复消费要比丢数据好处理。
- kafka写入高性能(1. 单个文件顺序写,多个文件或者磁盘会出现随机写;2. 先写buff再flush到磁盘,减小io次数)
- kafka读取指定offset(1. 文件大小指定,可以通过offset和文件大小计算出数据在哪个文件,2. 通过chunk size以及基于有序消息的二分查找,可以快速定位到指定offset)
- producer/consumer信息存储zookeeper,kafka的consumer本地记录offset,一定时间间隔注册zk。
- 据说机械硬盘顺序写比内存随机读要快。
- partition删数据:partition其实是个文件夹,segment是文件夹里面的小文件,过期或者磁盘不足可以删除比较老的segment。
- 消息路由默认实现,消息轮流选择partition,好处:负载均衡,坏处:同一个用户的消息可能放到不同的partition。
- 自治rebalance机制(旧):每次group的consumer出现变更,所有consumer都退出group然后,重新加入group触发分配partition。自治rebalance,通过zk保存状态,自身计算自己应该消费partition,坏处:这种情况依赖了zk的数据一致性,可能出现脑裂,不可控;每次变更都触发计算;好处:简单。
- 集中rebalance机制(新):zk为每个group选定一个leader,由leader计算分配方案,存放在syncGroup,然后每个consumer主动syncGroup拉去方案并且执行监听。
- ISR机制:partition的follower异步同步,但是需要所有follower成功commited,消息才能被消费。这里的异步指的是leader已经接收到消息并且写入磁盘,但是还没commited,目前可以配置时间间隔,如果落后时间大于指定配置,把备份从ISR剔除,可以保证吞吐率和一致性。如果leader挂了,从ISR中选择活的节点选为leader,原本故障节点恢复时,首先先剔除未commit的消息,然后同步当前leader的节点数据,直到一致才能重新加入ISR。如果ISR都不可用,两种策略:1. 等待以前ISR中的任何一个备份恢复(慢,但是数据不丢失),2. 等待任何一个备份恢复无论以前是否在ISR(默认策略,快,数据丢失,比如故障节点)
nsq
- 所有消息存在nsqd里面,存内存不落盘,消息可能丢失
- 至少一次成功发送,大致保证这个特性,因为内存消息会丢
- topic逻辑概念,多个channel,消息发至topic,会复制到每个channel
- 每一个channel有完整的消息,多个channel类比于广播
- 无序:1. 特色功能,处理消息失败requeue,延迟消费defer。2. 一旦内存无法存下,会写磁盘,但是这个是无序的。
- 不可回溯,channel成功消费后会删除消息。
- push:相对于pull更实时,流量监控。
kafka与nsq的对比:https://www.codercto.com/a/30746.html