什么是消息队列
队列提供了一种异步通信协议。这意味着消息的发送者和接受者不需要同时与消息保持联系,发送者发送的消息会存储在队列中,直到接受者拿到他。
消息的发送者称为生产者,消息的接收者为消费者。
通常生产者的生产速度与消费者的消费速度是不相等的,如果两个程序持续运行的话,消费者的消费平均速度一定要大于生产者的平均生产速度,否则就会导致消息在队列中堆积。
消息队列的作用
1.解耦
在项目启动之初来预测将来项目会碰到什么需求,是极其困难的。消息系统在处理过程中间插入了一个隐含的,基于数据的接口层,两边的处理过程都要事先这一接口.这允许你独立的扩展或修改两边的处理过程,只要确保他们遵守相同的接口约束.
2.冗余
有些情况下,处理数据的过程会失败。除非数据被持久化,否则将造成丢失。消息队列把数据进行持久化直到他们已经被完全处理,通过这一方式规避了数据丢失风险,许多消息队列所采用的的'插入 - 获取 - 删除'范式中,在把一个消息从队列中删除之前,需要你的处理系统明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕.
3.削峰/平谷(缓冲处理压力)
在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见;
如果为以处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费,使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷请求完全崩溃.
4.顺序保证
在大多数使用场景下,数据处理的顺序都很重要,大部分消息队列本来就是排序的,并且保证数据会按按照特定的顺序来处理,kafka保证了一个Partition内的消息的有序性.
5.异步通信
很多时候,用户不想也不需要立即处理消息,消息队列提供了异步处理机制,允许用户把一个消息放入队列,但不立即处理他,想向队列放入多少消息就放多少,然后在需要的时候再去集中处理他们.这样消息生产者只负责生产而不去等待消费完就能处理其他事情。从而提速。
什么是Kafka
Kafka是一个开源的分布式消息引擎/消息中间件,同时Kafka也是一个流处理平台。Kakfa支持以发布/订阅的方式在应用间传递消息。Kafka也是目前性能最好的消息中间件。
在Kafka集群(Cluster)中,一个Kafka节点就是一个Broker,消息由Topic来负载,可以存储在1个或多个Partition中,发布消息的应用为Producer、消费消息的应用为Consumer,多个Consumer可以促成Consumer Group共同消费一个Topic中的消息。
消息 Massage
Kafka处理的数据单元叫做消息,一种类似于数据库中一条记录的概念。
这些数据单元,对于Kafka而言,并没有特殊意义,都是字节数组,但是每个消息可以拥有描述性的元数据---key,这些key通常用来表示消息应该存放的分区。为了效率,Kafka里的消息都是批处理的,同一批(Batch)的消息主题和分区相同,这样的设计有助于减少单消息在网络传输带来的开销,当然,这种处理方式,也是一种在吞吐量和网络延时的折中的方案.
模式
为了让消息具备更加的可读性,Kafka使用模式(Schema)来管理数据类型,如JSON,XML等等。为了向后兼容,或者做到可扩展性,选择合适的Schema非常重要.
主题 Topic 和 分区Partition
Kafka里的消息按主题分类,鉴于Kafka里的消息是按追加,从头到尾读取的方式,使用分区可以大大提高Kafka的读取效率,也提供了系统的可扩展性,消息写入分区的方式如下图所示:
Topic是逻辑层面的,而Partition是物理层面的。一个Topic可以放在多个分区(提高该Topic的运行效率,多核处理器一样)分区是最小文件单位,一个分区只能对应一个Topic,但是注意,不同分区会导致数据消费无序,因此对于需要有序的数据,要保证不仅在同一个Topic,还需要在同一个分区(对应的是key)。
分区有备份的概念,一个主分区(Leader)可以有多个备份分区(Follower)。备份分区只同步主分区的数据。然后对外提供访问权限。
生产者与消费者
生产者:创建消息的主题。可以通过不同的Key把消息发往不同的主题中去,还可以根据用户自定义的行为发送日志.
消费者: 读取消息的主体,消费者追踪每个分区的offset的值,决定从哪里去取消息,Zookeeper或者Kafka可以存储offset的值,共同消费一个主题。