kafka是一种高吞吐量的分布式发布订阅消息系统。和rabbitMq各占半臂江山
java
消息队列中间件(简称消息中间件)是指利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通讯来进行分布式系统的集成。经过提供消息传递和消息排队模型,它能够在分布式环境下提供应用解耦、弹性伸缩、冗余存储、流量削峰、异步通讯、数据同步等等功能
mysql
RabbitMQ 是采用 Erlang 语言实现的 AMQP 协议的消息中间件,最初起源于金融系统,用于在分布式系统中存储转发消息。RabbitMQ 发展到今天,被愈来愈多的人承认,这和它在可靠性、可用性、扩展性、功能丰富等方面的卓越表现是分不开的。
linux
Kafka 起初是由 LinkedIn 公司采用 Scala 语言开发的一个分布式、多分区、多副本且基于 zookeeper 协调的分布式消息系统,现已捐献给 Apache 基金会。它是一种高吞吐量的分布式发布订阅消息系统,以可水平扩展和高吞吐率而被普遍使用。目前愈来愈多的开源分布式处理系统如 Cloudera、Apache Storm、Spark、Flink 等都支持与 Kafka 集成。
c++
1.Rabbitmq在与routing 而kafka在于streaming
2.kafka不支持延迟队列,死信队列 rabbitmq支持死信队列
3.都支持持久化
4.kafka不支持多租户,rabbitmq支持
5.广播消费 kafka支持较好,更加正统
6.rabbitmq支持优先级队列,优先级设置在0-10之间
7.消息堆积,kafka比rabbitmq要好不少
8.消息跟踪 kafka不支持 rabbitmq支持 但大幅度影响性能
9.kafka消息直接写入磁盘,而不是内存当中,kafka的log文件目录就是kafka数据文件。
不写入内存,消息不容易丢失。
web
rabbitMQ安装请参考
juejin.im/post/5cce82…sql
kafka特色:
1.以时间复杂度为 O(1) 的方式提供消息持久化能力,即便对 TB 级以上数据也能保证常数时间复杂度的访问性能。 2.高吞吐率。即便在很是廉价的商用机器上也能作到单机支持每秒 100K 条以上消息的传输
数据库
kafka设计思想
1.Consumergroup:各个consumer能够组成一个组,每一个消息只能被组中的一个consumer消费,若是一个消息能够被多个consumer消费的话,那么这些consumer必须在不一样的组。
bootstrap
2.消息状态:在Kafka中,消息的状态被保存在consumer中,broker不会关心哪一个消息被消费了被谁消费了,只记录一个offset值(指向partition中下一个要被消费的消息位置),这就意味着若是consumer处理很差的话,broker上的一个消息可能会被消费屡次。
缓存
3.消息持久化:Kafka中会把消息持久化到本地文件系统中,而且保持极高的效率。
安全
4.消息有效期:Kafka会长久保留其中的消息,以便consumer能够屡次消费,其中不少细节是可配置的。
5.批量发送:Kafka支持以消息集合为单位进行批量发送,以提升push效率。
6.push-and-pull : Kafka中的Producer和consumer采用的是push-and-pull模式,即Producer只管向broker push消息,consumer只管从broker pull消息,二者对消息的生产和消费是异步的。
7.Kafka集群中broker之间的关系:不是主从关系,各个broker在集群中地位同样,咱们能够随意的增长或删除任何一个broker节点。
8.负载均衡方面: Kafka提供了一个 metadata API来管理broker之间的负载(对Kafka0.8.x而言,对于0.7.x主要靠zookeeper来实现负载均衡)。
9.同步异步:Producer采用异步push方式,极大提升Kafka系统的吞吐率(能够经过参数控制是采用同步仍是异步方式)。
10.分区机制partition:Kafka的broker端支持消息分区,Producer能够决定把消息发到哪一个分区,在一个分区中消息的顺序就是Producer发送消息的顺序,一个主题中能够有多个分区,具体分区的数量是可配置的。分区的意义很重大,后面的内容会逐渐体现。
11.离线数据装载:Kafka因为对可拓展的数据持久化的支持,它也很是适合向Hadoop或者数据仓库中进行数据装载。
12.插件支持:如今很多活跃的社区已经开发出很多插件来拓展Kafka的功能,如用来配合Storm、Hadoop、flume相关的插件。
kafka 应用场景
1.日志收集:一个公司能够用Kafka能够收集各类服务的log,经过kafka以统一接口服务的方式开放给各类consumer,例如hadoop、Hbase、Solr等。
2.消息系统:解耦和生产者和消费者、缓存消息等。
3.用户活动跟踪:Kafka常常被用来记录web用户或者app用户的各类活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,而后订阅者经过订阅这些topic来作实时的监控分析,或者装载到hadoop、数据仓库中作离线分析和挖掘。
4.运营指标:Kafka也常常用来记录运营监控数据。包括收集各类分布式应用的数据,生产各类操做的集中反馈,好比报警和报告。
5.流式处理:好比spark streaming和storm
6.事件源
官网kafka实例版本的问题。
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning
当kafka的版本是 kafka_2.12-2.1.1,不支持bootstrap-server
报错"bootstrap-server is not a recognized option"
option,换成版本kafka_2.12-2.2.0就ok了。应该是2.2.0的新特性。<br
kafka isr机制
isr的全称是In-Sync Replicas isr(已同步的副本) 是一个副本的列表,里面存储的都是能跟leader 数据一致的副本,肯定一个副本在isr列表中,有2个判断条件
条件1:根据副本和leader 的交互时间差,若是大于某个时间差 就认定这个副本不行了,就把此副本从isr 中剔除,此时间差根据
配置参数rerplica.lag.time.max.ms=10000 决定 单位ms
条件2:根据leader 和副本的信息条数差值决定是否从isr
中剔除此副本,此信息条数差值根据配置参数rerplica.lag.max.messages=4000 决定单位条
isr 中的副本删除或者增长 都是经过一个周期调度来管理的
request.required.acks 的参数说明:
0:生产者只管发送,无论服务器,消费者是否收到信息
1:只有当leader 确认了收到消息,才确认此消息发送成功
-1:只有isr 中的n-1个副本(leader 除外因此n-1)都同步了消息 此消息才确认发送成功
生产者发送的消息只有在确认发送成功后 才能被消费者消费
kafka设计
一个Topic能够认为是一类消息,每一个topic将被分红多个partition(区),每一个partition在存储层面是append log文件。任何发布到此partition的消息都会被直接追加到log文件的尾部,每条消息在文件中的位置称为offset(偏移量),offset为一个long型数字,它是惟一标记一条消息。它惟一的标记一条消息。kafka并无提供其余额外的索引机制来存储offset,由于在kafka中几乎不容许对消息进行“随机读写” offset 是保存在zookeeper之中的。
kafka消费
对于consumer而言,它须要保存消费消息的offset,对于offset的保存和使用,有consumer来控制;当consumer正常消费消息时,offset将会"线性"的向前驱动,即消息将依次顺序被消费.事实上consumer可使用任意顺序消费消息,它只须要将offset重置为任意值。
kafka状态
kafka集群几乎不须要维护任何consumer和producer状态信息,这些信息有zookeeper保存;所以producer和consumer的实现很是轻量级,它们能够随意离开,而不会对集群形成额外的影响。
kafka的leader选举规则
当leader失效时,需在followers中选取出新的leader,可能此时follower落后于leader,所以须要选择一个"up-to-date"的follower.选择follower时须要兼顾一个问题,就是新leader上所已经承载的partition leader的个数,若是一个server上有过多的partition leader,意味着此server将承受着更多的IO压力.在选举新leader,须要考虑到"负载均衡"。
kafka日志删除
日志文件的删除策略很是简单:启动一个后台线程按期扫描log file列表,把保存时间超过阀值的文件直接删除(根据文件的建立时间).为了不删除文件时仍然有read操做(consumer消费),采起copy-on-write方式。
CopyOnWrite机制
当咱们往容器中添加一个元素的时候,不是直接添加,而是对当前容器copy,复制一个容器,在这个复制的容器中添加元素,添加完以后,再将引用指向这个新容器。
优势:CopyOnWrite容器能够并发的进行读操做,而不须要加锁,由于 当前容器不会添加任何元素,因此这也是一种读写分离的思想,读和写的操做分开了。
缺点:
1.内存占用问题,产生了两个容器
2.只能保持数据的最终一致性,没法保持 实时性,因此若是但愿读到新数据,不要用copyOnWrite
RabbitMQ与kafka的消息队列模式
1.生产端发送一条消息经过路由投递到Queue,只有一个消费者能消费到。
kafka
Kafka只支持消息持久化,消费端为拉模型,消费状态和订阅关系由客户端端负责维护,消息消费完后不会当即删除,会保留历史消息。所以支持多订阅时,消息只会存储一份就能够了。可是可能产生重复消费的状况。
以下图,kafka集群中,leader标识的是brokerid,后面的Isr(已同步的副本)也是brokerid。 从后面的一条记录能够看出,当其中一个broker down了之后会从Isr列表中清除掉。可是Replicas仍然保存。
kafka Connect 导入导出数据
kafka Connect是kafka附带的一个工具,用于将数据导入和导出到kafka。是一个可扩展的工具,运行链接器,实现与外部系统的交互的自定义逻辑。
官网的例子分为如下几个步骤:(以单个broker为例)
kafka Streams
kafka Streams是kafka的0.10提供的新能力,用于实时处理kafka中的数据流。和现有的流处理技术如SparkStreaming,Storm,Flink仍是有些区别的。
Kafka Streams是一套处理分析Kafka中存储数据的客户端类库,处理完的数据或者写回Kafka,或者发送给外部系统。它构建在一些重要的流处理概念之上:区分事件时间和处理时间、开窗的支持、简单有效的状态管理等。
Kafka Streams入门的门槛很低:很容易编写单机的示例程序,而后经过在多台机器上运行多个实例便可水平扩展从而达到高吞吐量。Kafka Streams利用Kafka的并发模型以实现透明的负载均衡。
Kafka Streams的价值体如今如下几点,首先它提供了两套轻量且易用的API有效下降了Kafka数据流处理的开发成本,在这以前可使用SparkStreaming(不支持单条消费)、Storm(必须使用Trident才支持时间窗),或者本身写consumer(之前高层API还好,低层API是初学者的噩梦,最欢乐的是官方将低层API称为“Simple API”),如今至少又多了一种选择。其次用它开发的应用支持跑在Yarn、Mesos、Docker或者纯Java应用内,比较灵活。再次是数据流的两种抽象比较有意思,目前我尚未深刻研究,但以为用来处理不去重/去重的场景简直太方便了。固然缺点也有,首先目前不支持异步操做,这就须要开发者当心在处理方法中不能有高开销动做,不然整个处理线程阻塞。另外若是须要SQL接口或者ML能力,那仍是去找SparkStreaming吧。
下图展现了Kafka Streams应用程序的解剖图,让咱们来看一些细节。
kafka的流实例参考
juejin.im/post/5cd50a…
kafka 消费的时候为何每一个consumer只能消费一个partition? 为何每一个partition只能有一个consumer。
kafka参数理解
登陆zookeeper客户端,查看zookeeper中存储的信息
linux IO过程
kafka实现高吞吐量的零拷贝机制
传统的IO机制
传统的以下图所示
这一过程实际上发生了四次数据拷贝。首先经过系统调用将文件数据读入到内核态 Buffer(DMA 拷贝),而后应用程序将内存态 Buffer 数据读入到用户态 Buffer(CPU 拷贝),接着用户程序经过 Socket 发送数据时将用户态 Buffer 数据拷贝到内核态 Buffer(CPU 拷贝),最后经过 DMA 拷贝将数据拷贝到 NIC Buffer。同时,还伴随着四次上下文切换.
kafka在zookeeper中存储结构
ActiveMQ
基于java开发,是Apache出品的、采用Java语言编写的彻底基于JMS1.1规范的面向消息的中间吗件。其最新架构被命名为Apollo,京东的消息中间件就是基于activeMQ开发的。
优势:
缺点:
zeroMQ
基于C开发,号称史上最快的队列。虽然大多数时候咱们习惯将其纳入消息队列家族之中,可是其和前面的几款有着本质的区别,ZeroMQ自己就不是一个消息队列服务器,更像是一组底层网络通信库,对原有的Socket API上加上一层封装而已。
优势:
缺点:
RocketMQ
基于java开发的,阿里消息中间。件目前已经捐献个Apache基金会,它是由Java语言开发的,具有高吞吐量、高可用性、适合大规模分布式系统应用等特色,经历过双11的洗礼。
优势 :
选取理由:
缺点:
Jafka 是在 Kafka 之上孵化而来的,即 Kafka 的一个升级版。具备如下特性:快速持久化,能够在 O(1) 的系统开销下进行消息持久化;高吞吐,在一台普通的服务器上既能够达到 10W/s 的吞吐速率;彻底的分布式系统,Broker、Producer、Consumer 都原生自动支持分布式,自动实现负载均衡;支持 Hadoop 数据并行加载,对于像 Hadoop 的同样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。