1.什么是kafka? (开放性问题)
Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。 这种动作是在现代网络上的许多社会功能的一个关键因素。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。
2.流式计算?
strom sparkStreaming flink
流式计算:数据实时产生、数据实时传输、数据实时计算、实时展示
代表技术:Flume实时获取数据、Kafka/metaq实时数据存储、Storm/JStorm实时数据计算、Redis实时结果缓存、持久化存储(mysql)。
一句话总结:将源源不断产生的数据实时收集并实时计算,尽可能快的得到计算结果
3.JMS 消息传输模型?
JMS(Java消息服务),JMS支持两种消息模型:Point-to-Point(P2P)和Publish/Subscribe(Pub/Sub),即点对点和公布订阅模型。
1 点对点消息模型(p2p)
点对点消息模型既支持 异步“即发即弃”的消息传送方式,也支持同步的“请求响应”的消息传送方式。
点对点消息模型的特点:
- 消息通过一个名为消息队列的虚拟通道来交换消息。队列即是消息生产者发送消息的目的地,也是消息消费者获取消息的消息源。
- 每一条消息只能传送给一个接受者,可能会有多个接收者在一个队列侦听,但是每个消息队列中的消息只能被一个接受者所消费
- 消息队列中的消息是由先后顺序的。先进入队列的会优先被消费,除非使用了消息优先级。
- 消费者和生产者之间没有耦合。消费者和生产者可以在运行时动态的添加,这使得系统的发杂性可以随着时间的增长而降低。
即发即弃模型是指:消息生产者向某个队列发送一条消息,他不会期望得到消息消费者的一个响应(至少不是立刻得到响应)。
2 发布订阅消息模型
发布订阅消息的特点:
- 信息通过一个成为主题(topic)的虚拟通道交换
- 每条消息都会传送给多个称为订阅者的消费者。订阅者有许多类型,包括持久订阅者、非持久订阅者、动态订阅者。
- 发布者通常不会意识到有多少个订阅者在接收主题消息
- 消息被推送给消费者,这意味着消息会传给消费者,而无需消费者去请求。
- 生产者和消费者之间没有耦合,订阅者和发布者可以动态的添加。
- 订阅一个主题的每个客户端都会受到发布该主题的副本。发布者生产的一条消息可以被复制并分发给成千上万的订阅者
4.总结flume? source sink channel 常用的类型?
flume中几种常见的source、channel、sink
5.flume和 kafka 有什么区别?
定义:
Flume:是Cloudera提供的一个分布式的海量日志采集、聚合和传输的系统;
Kafka:是一种高吞吐量的分布式发布订阅消息系统;
各特点:
场景:
Flume主要是和HDFS\HBase结合,有特殊优化效率更好;
Kafka 是一个通用型系统,开发商 Cloudera 推荐如果数据需要被多个应用程序消费的话,推荐使用 Kafka。
实时过滤:
Flume 可以在拦截器里面实时处理数据。这个特性对实时过滤数据非常有用。Kafka 需要一个外部系统帮助处理数据。
数据保存:
kafka更适合做日志缓存:两个系统都可以保证不丢失数据。但Flume 不会复制事件,如果 Flume agent 所在的这个节点宕机了,你会失去所有的事件访问能力直到你修复这个受损的节点。使用 Kafka 的管道特性不会有这样的问题。
两者可协作工作:
kafka + flume:如果你需要把流式数据从 Kafka 转移到 Hadoop,可以使用 Flume 代理 (agent),将 kafka 当作一个来源 (source),这样可以从 Kafka 读取数据到 Hadoop。
flume + kafka:做日志缓存;flume的数据采集部分做的很好,可以定制很多数据源,减少开发量(kafka没有直接可用的生产者与消息者,需要自己实现),然后利用kafuka分发到多个系统;
6.Kafka与传统消息系统之间有三个关键区别?
实际上,Kafka 并非传统意义上的消息队列,它与 RabbitMQ 等消息系统并不一样。它更像是一个分布式的文件系统或数据库。Kafka 与传统消息系统之间有三个关键区别。
- Kafka 持久化日志,这些日志可以被重复读取和无限期保留
- Kafka 是一个分布式系统:它以集群的方式运行,可以灵活伸缩,在内部通过复制数据提升容错能力和高可用性
- Kafka 支持实时的流式处理
以上三点足以将 Kafka 与传统的消息队列区别开,我们甚至可以把它看成是流式处理平台。因此,在 Kafka 里存储数据并不是什么疯狂事,甚至可以说 Kafka 本来就是设计用来存储数据的。数据经过校验后被持久化在磁盘上,并通过复制副本提升容错能力。再多的数据都不会拖慢 Kafka,在生产环境中,有些 Kafka 集群甚至已经保存超过 1 TB 的数据。
7.JMS消息传输模型?
- 点对点模式(一对一,消费者主动拉取数据,消息收到后消息清除)
点对点模型通常是一个基于拉取或者轮询的消息传送模型,这种模型从队列中请求信息,而不是将消息推送到客户端。这个模型的特点是发送到队列的消息被一个且只有一个接收者接收处理,即使有多个消息监听者也是如此。
- 发布/订阅模式(一对多,数据生产后,推送给所有订阅者)
发布订阅模型则是一个基于推送的消息传送模型。发布订阅模型可以有多种不同的订阅者,临时订阅者只在主动监听主题时才接收消息,而持久订阅者则监听主题的所有消息,即时当前订阅者不可用,处于离线状态。
8.总结常用的 MQ? 消息队列
9.消息系统的核心作用? 解耦 异步 并行
-
第一点:解耦
在项目启动之初来预测将来项目会碰到什么需求,是极其困难的。消息系统在处理过程中间
插入了一个隐含的、基于数据的接口层,两边的处理过程都要实现这一接口。这允许你独立
的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。 -
第二点:冗余
有些情况下,处理数据的过程会失败。除非数据被持久化,否则将造成丢失。消息队列把数
据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。许多消息队列
所采用的”插入-获取-删除”范式中,在把一个消息从队列中删除之前,需要你的处理系统
明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕。 -
第三点:扩展性
因为消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的,只要另外
增加处理过程即可。不需要改变代码、不需要调节参数。扩展就像调大电力按钮一样简单。 -
第四点:灵活性 & 峰值处理能力
在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见;如果
为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够
使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。 -
第五点:可恢复性
系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即
使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。 -
第六点:顺序保证
在大多使用场景下,数据处理的顺序都很重要。大部分消息队列本来就是排序的,并且能保 证数据会按照特定的顺序来处理。Kafka 保证一个
Partition 内的消息的有序性。 -
第七点:缓冲
在任何重要的系统中,都会有需要不同的处理时间的元素。例如,加载一张图片比应用过滤
器花费更少的时间。消息队列通过一个缓冲层来帮助任务最高效率的执行。写入队列的处理会尽可能的快速。该缓冲有助于控制和优化数据流经过系统的速度。 -
第八点:异步通信
很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一
个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时 候再去处理它们。
10.Kafka核心组件和作用?
订单 浏览 支付
Producer :消息生产者,就是向kafka broker发消息的客户端
Consumer :消息消费者,向kafka broker取消息的客户端
Topic :消息主题
ConsumerGroup(CG):这是kafka用来实现一个topic消息的广播(发给所有的consumer)和单播(发给任意一个consumer)的手段。一个topic可以有多个CG。topic的消息会复制(不是真的复制,是概念上的)到所有的CG,但每个partition只会把消息发给该CG中的一个consumer。如果需要实现广播,只要每个consumer有一个独立的CG就可以了。要实现单播只要所有的consumer在同一个CG。用CG还可以将consumer进行自由的分组而不需要多次发送消息到不同的topic。
Broker :一台kafka服务器就是一个broker。一个集群由多个broker组成。一个broker可以容纳多个topic。
Partition:为了实现扩展性,一个非常大的topic可以分布到多个broker(即服务器)上,一个topic可以分为多个partition,每个partition是一个有序的队列。partition中的每条消息都会被分配一个有序的id(offset)。kafka只保证按一个partition中的顺序将消息发给consumer,不保证一个topic的整体(多个partition间)的顺序。
Offset:kafka的存储文件都是按照offset.kafka来命名,用offset做名字的好处是方便查找。例如你想找位于2049的位置,只要找到2048.kafka的文件即可。当然the first offset就是00000000000.kafka
kafka架构
11.CG 作用?
consumer group是kafka提供的可扩展且具有容错性的消费者机制。既然是一个组,那么组内必然可以有多个消费者或消费者实例(consumer instance),它们共享一个公共的ID,即group ID。组内的所有消费者协调在一起来消费订阅主题(subscribed topics)的所有分区(partition)。当然,每个分区只能由同一个消费组内的一个consumer来消费。理解consumer group记住下面这三个特性就好了:
1)consumer group下可以有一个或多个consumer instance,consumer instance可以是一个进程,也可以是一个线程
2)group.id是一个字符串,唯一标识一个consumer group
3)consumer group下订阅的topic下的每个分区只能分配给某个group下的一个consumer(当然该分区还可以被分配给其他group)
12.CG的Consumer与topic下的partition关系? 一一对应的关系,一个partition同时只能被一个消费者消费
- 在kafka中,一个partition中的消息只会被group中的一个consumer消费(同一时刻);
一个Topic中的每个partions,只会被一个"订阅者"中的一个consumer消费,不过一个consumer可以同时消费多个partitions中的消息。 - kafka的设计原理决定,对于一个topic,同一个group中不能有多于partitions个数的consumer同时消费,否则将意味着某些consumer将无法得到消息。
kafka只能保证一个partition中的消息被某个consumer消费时是顺序的;事实上,从Topic角度来说,当有多个partitions时,消息仍不是全局有序的。
13.kafka 消息有序论? 如何保证消息全局有序? 伪命题 生产有序 存储有序 消费有序
两种方案:
方案一,kafka topic 只设置一个partition分区
方案二,producer将消息发送到指定partition分区
解析:
- 方案一:kafka默认保证同一个partition分区内的消息是有序的,则可以设置topic只使用一个分区,这样消息就是全局有序,缺点是只能被consumer
group里的一个消费者消费,降低了性能,不适用高并发的情况 - 方案二:既然kafka默认保证同一个partition分区内的消息是有序的,则producer可以在发送消息时可以指定需要保证顺序的几条消息发送到同一个分区,这样消费者消费时,消息就是有序。
producer发送消息时具体到topic的哪一个partition分区,提供了三种方式
1)指定分区
2)不指定分区,有指定key 则根据key的hash值与分区数进行运算后确定发送到哪个partition分区
3)不指定分区,不指定key,则轮询各分区发送
14.Kafka消息的分发策略?
Producer客户端负责消息的分发
- kafka集群中的任何一个broker都可以向producer提供metadata信息,这些metadata中包含"集群中存活的servers列表"/"partitions
leader列表"等信息; - 当producer获取到metadata信息之后, producer将会和Topic下所有partition
leader保持socket连接; - 消息由producer直接通过socket发送到broker,中间不会经过任何"路由层",事实上,消息被路由到哪个partition上由producer客户端决定;
比如可以采用"random"“key-hash”"轮询"等,如果一个topic中有多个partitions,那么在producer端实现"消息均衡分发"是必要的。 - 在producer端的配置文件中,开发者可以指定partition路由的方式。
15.Producer消息发送的应答机制? ACK机制? 如果保证数据不丢失?
Producer消息发送的应答机制 :ACK
设置发送数据是否需要服务端的反馈,有四个值: 0,1,-1,All
0: producer不会等待broker发送ack
1: 当leader接收到消息之后发送ack
-1: 当所有的follower都同步消息成功后发送ack
All:
request.required.acks=0
16.partition本质? 命名? 保存的什么文件?
Partition是作用于具体的Topic而已的,而不是一个独立的概念。Partition能水平扩展客户端的读写性能,是高吞吐量的 保障。通俗的将,Partition就是一块保存具体数据的空间,本质就是磁盘上存放数据的文件夹,所以Partition是不能跨Broker存在,也不能在同一个Broker上跨磁盘。对于一个Topic,可以根据需要设定Partition的个数;Kafka默认的Partition个数num.partitions为1($KAFKA_HOME/config/server.properties),表示该Topic的所有数据均写入至一个文件夹下;用户也可以在新建Topic的时候通过显示的指定–partitions 参数实现自定义Partition个数。在数据持久化时,每条消息都是根据一定的分区规则路由到对应的Partition中,并append在log文件的尾部(这一点类似于HDFS);在同一个Partition中消息是顺序写入的且始终保持有序性;但是不同Partition之间不能保证消息的有序性(高吞吐量的保障)。
Partition是用来存储数据的,但并不是最小的数据存储单元。Partition下还可以细分成Segment,每个Partition是由一个或多个Segment组成。每个Segment分别对应两个文件:一个是以.index结尾的索引文件,另一个是以.log结尾的数据文件,且两个文件的文件名完全相同。所有的Segment均存在于所属Partition的目录下。
Segment的必要性:如果以partition作为数据存储的最小单元,那么partition将会是一个很大的数据文件,且数据量是持续递增的;当进行过期数据清理或消费指定offset数据时,操作如此的大文件将会是一个很严重的性能问题。
17.partition的数据如何保存在磁盘?
18.partition如何分布在broker?
根据hash值
19.kafka 独特的特点?
pagecache sendfile:零拷贝
20.pagecache?
kafka 充分利用当前物理机的空闲内存做缓存
21.消费者如何标记消费状态?
22.sparkStreaming 消费kafka数据的两种方式?
receiver:高阶API zk管理偏移量 不能保证消息的可靠性
direct:低阶API 自己管理偏移量 可以保证消息的可靠性
官方文档