1、kafka 的 message 包括哪些信息
一个Kafka 的 Message 由一个固定长度的 header 和一个变长的消息体 body 组成
header 部分由一个字节的 magic(文件格式)和四个字节的 CRC32(用于判断 body 消息体
是否正常)构成。当 magic 的值为 1 的时候,会在 magic 和 crc32 之间多一个字节的数据:
attributes(保存一些相关属性,比如是否压缩、压缩格式等等);如果 magic 的值为 0,那
么不存在attributes 属性
body 是由 N 个字节构成的一个消息体,包含了具体的 key/value 消息
2、怎么查看 kafka 的 offset
0.9 版本以上,可以用最新的 Consumer client 客户端,有 consumer.seekToEnd() / c
onsumer.position() 可以用于得到当前最新的 offset:
3、hadoop 的 shuffle 过程
4、spark 集群运算的模式
Spark 有很多种模式,最简单就是单机本地模式,还有单机伪分布式模式,复杂的则运行
在集群中,目前能很好的运行在Yarn 和 Mesos 中,当然 Spark 还有自带的 Standalone 模式,对于大多数情况 Standalone 模式就足够了,如果企业已经有 Yarn 或者 Mes
os 环境,也是很方便部署的。
standalone(集群模式):典型的 Mater/slave 模式,不过也能看出 Master 是有单点故障的;
Spark 支持 ZooKeeper 来实现 HA
on yarn(集群模式): 运行在 yarn 资源管理器框架之上,由 yarn 负责资源管理,Spar
k 负责任务调度和计算
on mesos(集群模式): 运行在 mesos 资源管理器框架之上,由 mesos 负责资源管理,
Spark 负责任务调度和计算
on cloud(集群模式):比如 AWS 的 EC2,使用这个模式能很方便的访问 Amazon 的 S
3;Spark 支持多种分布式存储系统:HDFS 和 S3
5、HDFS 读写数据的过程
读:
1、跟 namenode 通信查询元数据,找到文件块所在的 datanode 服务器
2、挑选一台 datanode(就近原则,然后随机)服务器,请求建立 socket 流
3、datanode 开始发送数据(从磁盘里面读取数据放入流,以 packet 为单位来做校验)
4、客户端以 packet 为单位接收,现在本地缓存,然后写入目标文件
写:
1、根 namenode 通信请求上传文件,namenode 检查目标文件是否已存在,父目录是否
存在
2、namenode 返回是否可以上传
3、client 请求第一个 block 该传输到哪些 datanode 服务器上4、namenode 返回 3 个 datanode 服务器 ABC
5、client 请求 3 台 dn 中的一台 A 上传数据(本质上是一个 RPC 调用,建立 pipeline),
A 收到请求会继续调用 B,然后 B 调用 C,将真个 pipeline 建立完成,逐级返回客户端
6、client 开始往 A 上传第一个 block(先从磁盘读取数据放到一个本地内存缓存),以 p
acket 为单位,A 收到一个 packet 就会传给 B,B 传给 C;A 每传一个 packet 会放入一个
应答队列等待应答
7、当一个 block 传输完成之后,client 再次请求 namenode 上传第二个 block 的服务器。
6、RDD 中 reduceBykey 与 groupByKey 哪个性能好,为什么
reduceByKey:reduceByKey 会在结果发送至 reducer 之前会对每个 mapper 在本地
进行merge,有点类似于在 MapReduce 中的 combiner。这样做的好处在于,在 map 端
进行一次reduce 之后,数据量会大幅度减小,从而减小传输,保证 reduce 端能够更快的
进行结果计算。
groupByKey:groupByKey 会对每一个 RDD 中的 value 值进行聚合形成一个序列
(Iterator),此操作发生在 reduce 端,所以势必会将所有的数据通过网络进行传输,造成不
必要的浪费。同时如果数据量十分大,可能还会造成OutOfMemoryError。
通过以上对比可以发现在进行大量数据的reduce 操作时候建议使用 reduceByKey。不仅
可以提高速度,还是可以防止使用groupByKey 造成的内存溢出问题。
7、spark2.0 的了解更简单:ANSI SQL 与更合理的 API
速度更快:用Spark 作为编译器
更智能:Structured Streaming
8、 rdd 怎么分区宽依赖和窄依赖
宽依赖:父RDD 的分区被子 RDD 的多个分区使用 例如 groupByKey、reduceByKey、
sortByKey 等操作会产生宽依赖,会产生 shuffle
窄依赖:父RDD 的每个分区都只被子 RDD 的一个分区使用 例如 map、filter、union 等
操作会产生窄依赖
9、spark streaming 读取 kafka 数据的两种方式
这两种方式分别是:
Receiver-base
使用Kafka 的高层次 Consumer API 来实现。receiver 从 Kafka 中获取的数据都存储在
Spark Executor 的内存中,然后 Spark Streaming 启动的 job 会去处理那些数据。然而,
在默认的配置下,这种方式可能会因为底层的失败而丢失数据。如果要启用高可靠机制,让
数据零丢失,就必须启用Spark Streaming 的预写日志机制(Write Ahead Log,WAL)。
该机制会同步地将接收到的Kafka 数据写入分布式文件系统(比如 HDFS)上的预写日志中。
所以,即使底层节点出现了失败,也可以使用预写日志中的数据进行恢复。
Direct
Spark1.3 中引入 Direct 方式,用来替代掉使用 Receiver 接收数据,这种方式会周期性地
查询Kafka,获得每个 topic+partition 的最新的 offset,从而定义每个 batch 的 offset的范围。当处理数据的 job 启动时,就会使用 Kafka 的简单 consumer api 来获取 Kafka
指定offset 范围的数据。
全部评论
(2) 回帖