消息队列两种模式
点对点模式
优点:消费客户端可控制消费消息的速度
缺点:消费客户端需要一个线程不断监控队列中的消息
发布/订阅模式
不需要线程监控队列,但不能考虑客户端消费数据的速度
为什么需要消息队列?
1.解耦:A B不需要直接相连,不需要同步,通过中间件通信
2.冗余:消息队列具有缓存,也可以备份数据.
3.扩展:比如kafka集群
4.灵活性和峰值处理能力:扩展的灵活性,以及扩展带来的性能的提升处理峰值
5.可恢复性:冗余备份带来的可恢复性
6.顺序保证(分区内)
7.缓冲:均衡发送和消费的速度
8.异步通信
Kafka架构&工作流程
- Kafka集群有一个至多个Broker,一个Broker就是集群中的一台机器
- 一个topic可以有一个至多个分区Partition,一个partition可以有多个副本Replication;存在多个副本时,有leader和Follower,同一时间只有leader对外工作,follower只和leader通信维护副本.leader和follower不能在同一台机器上;这么做主要是为了负载均衡
3.消费者有消费者组,Consumer Group, 同一个group的consumer不能消费同一个分区;可以通过线程实现同一个group的consumer同时读取不同的分区的数据以提高并发
生产数据流程
写入方式
producer采用push方式把消息发布到broker,每条消息都被追加(append)到相应的partition 当中,属于顺序写磁盘(比随机写内存高,保证吞吐率)
分区
每个Partition中的消息都是有序的,生产的消息不断被追加到partition log上,其中每一个消息都有一个在其所在partition中的offset值
分区原因
上面讲过,为了负载均衡和提高并发
分区原则
1.自定义的分区
2.如果未自定义分区,但每条消息有Key值,根据Key的hash分区
3.如果既未指定分区方法 也没有Key值,则通过轮询的方式(轮询也是为了负载均衡)
Producer写入流程
- producer根据分区原则确定自己需要发送到的Partition后,先从broker-list 获取该Partition的leader
- producer将消息发送给Leader
- leader将该消息写入本地log
(若ACK=“all”) - follwers从leader pull消息
- 写入本地log后向leader发送ack
- leader收到所有follower的ACK后向Producer发送ack
ACK确认机制:
ACK = "0" , producer发送完数据不再等待leader的确认消息
ACK = "1", producer 等待leader的确认消息
ACK = "all", leader 等待所有follower的确认消息,follower接收到所有的确认消息后向Producer发送确认消息,producer等待leader的确认消息
Broker保存消息
存储方式
物理上把topic分成一个或多个partition,每个Partition对应一个文件夹,该文件夹存储了该partition的所有消息和索引文件
如果指定了zk的调度,那么consumer的元数据(如当前读取的offset)会存放在zk上
与Flume对比及集成
定位
flume:
1.适合多个生产者
2.适合下游消费者不多的情况(每个消费者都要配置副本 channel)
3.适合数据安全性要求不高(企业中为了效率大多使用memory channel)
4.适合和Hadoop生态圈对接的操作
kafka:
1.适合数据下游消费众多的情况(消费者数量的改变不需要改变kafka集群的配置,需要新增消费者的时候只需要再起一个消费者就行了)
2.适合数据安全要求性高的情况,支持replication
公司中的业务模式一般是:
flume多个agent(收集日志) => flume单个agent聚合 =>kafka
到Kafka之后有两条线
- kafka => (flume=>) => HDFS, 保存日志,做离线分析,如凌晨更新等业务
- kafka => spark streaming ,在线业务
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。