这是我参与「第四届青训营 」笔记创作活动的第8天。
实时流计算框架
- 流计算中重要的两个基本组件:用于传递事件的队列和用于执行计算逻辑的线程
实现特征提取模块的DAG图
- 从source接收数据,发送给解码模块。
- 解码模块将数据解码:转换成json格式,交给特征分解模块。
- 特征分解对格式化后的数据进行特征分解,将任务发给多个计算模块。
- 计算模块进行并行分布式计算,将计算后的结果发送给聚合节点。
- 聚合节点将计算后的结果汇总聚合,发送给sink模块。
- sink模块将结果输出
造轮子
- 对照着特征提取模块的DAG,每个节点是一个完成特定功能的计算单元,不妨将每个节点抽象为一个服务类。在节点之间,用有向边来描述节点间的事件传递,因此很容易想到用队列Queue来作为服务类之间事件传递的载体。
- 定义一个抽象类AbstractStreamService 和它的一个子类SimpleStreamService。它们的功能是从其输入队列 inputQueues中不断读取(poll)消息,经过处理(process)后,再发送到下游的输入队列outputQueues中去。
- 在实现服务类时,定义消息传递的载体Queue接口,以及它的实现类BackPressureQueue。BackPressureQueue是基于 ArrayBlockingQueue的,它的容量是有限的,而且是一个阻塞队列。
实现特征提取DAG节点-----拉取数据
- Receiver模块:从Kafka拉取数据。
- Receiver的poll方法在Kafka中有数据可读时, 就将其读取出来,并发送到其输出队列,也就是其下游Decoder的输入队列。
实现特征提取DAG节点-----转json
- Decoder模块:将从Kafka中读取的数据解码为JSON对象。
- process方法从其输入队列中读取byte[]类型的消息后,解析为JSON对象,然后发送到其输出队列,也就是其下 游FeatureForker的输入队列。
实现特征提取DAG节点-----任务分解并行计算
- 在FeatureForker模块中,对任务进行分解。
实现特征提取DAG节点-----结果合并
- FeatureJoiner模块:将所有并行计算的特征计算结果合并起来。
- 由于在FeatureForker中已将所有结果用ListenableFuture<List>封装,所以在FeatureJoiner的process方法中,用future.get()即可获取所有特征计算结果。
- 当收集了所有的特征后,将其添加到消息JSON对象的features字段。
实现特征提取DAG节点-----发回kafka
- Sender模块:将提取了所有特征的消息发回Kafka等sink中。
完整的DAG
- 先创建了两个Receiver从Kafka拉取数据。
- 然后将数据发送给Decoder进行解码。
- 解码后的数据用JSON对象表示。
- FeatureForker则将需要计算的特征分发给多个特征计算节点进行计算,多个特征计算的结果由FeatureJoiner合并起来,然后添加到JSON对象中。
- 最后通过Sender发送出去。