文章目录
期间遇到的linux系统bug xfs dm-0 metadata io error
Ava重构
改进思路
并行计算,远程调度同步机制
开发计划
阅读split相关代码
看看split实现了什么,怎么实现的?能不能用远程调用的方法改进?
从哪几个角度看?
1.split算子本身的操作
2.split算子创建的时机
3.Master/Starter节点对split的操作以及算子链相关的构建
尝试使用线程同步机制
弄清楚撤回流机制,flink的相关计算模型
面试准备
项目介绍
有两个主要的程序,一个是Collaborator,一个是Master。Collaborator是从节点的主程序,他是一个actorsystem,负责托管创建在Collaborator上的actor。主节点的主程序是HttpServer,他是一个web服务,可以监听一个端口收到的请求。在接收到job的信息的时候,HttpServer会调用starter创建也就是Master节点上的ActorSystem,并且在ActorSystem里面创建Master,Source,Sink,解析job的信息调度Master去创建Worker也就是Actor。
序列化怎么做的
序列化是对对象进行序列化
配置哪个类应该用哪个序列化器
serializers {
java = "akka.serialization.JavaSerializer"
proto = "akka.remote.serialization.ProtobufSerializer"
}
serialization-bindings {
"java.lang.String" = java
"com.asoul.ava.workers.MapWorker" = proto
"com.asoul.ava.Job" = proto
}
消息传输的可靠性
可用性
须知
拿到大项目的时候要做的几件事:
1.弄清楚项目的各个模块都是干什么的
2.弄清楚数据流向,数据结构
其实是一个开发过程的记录
网上copy代码要去找依赖
maven中央仓库
/opt/apps/kafka_2.12-2.6.2/bin/kafka-topics.sh --zookeeper localhost:2181 --create --topic test-topic --replication-factor 3 --partitions 3
/opt/apps/kafka_2.12-2.6.2/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test-topic
kafka创建topic和启动报错,这是因为自己已经搭建了zookeeper集群。如果只启动单台服务器zookeeper在选举的时候将不可进行。所以zookeeper就会认为服务处于不可用状态。将node02和node03节点的zookeeper全部启动后创建topic成功。
参考资料
第一个是最合适的
看源码的方法
看源码的方法:
搜索类:双击shift/ctrl+n
查看类快捷键:Alt+7/ctrl+f12
在类中点来点去,返回上一步ctrl+alt+<-
在类里面ctrl+h可以查看继承关系,右键想要的类show diagram
项目要求
算子链数据结构的抽象这个,还有rpc的流程
首先应该关注核心逻辑:算子链、分布式
akka源码
akka梳理
网络基本概念介绍
akka介绍
akka实例
akka学习指南(akkaJavaApi介绍)
functions:提供自定义函数的接口
mailboxes:应该是rpc框架的内容
messages:带有message的类都是在节点之间传输的消息
nodes:
master:写了master节点的一些函数
sink
source
operators:对自定义fun的封装,增加了window,batchsize等属性
worker:是rpc通信的节点,也是对自定义fun的封装
为什么要整出两个对fun的封装呢?
Collaborator:是协作者结点的主程序入口,创建协作者节点
httpserver:
starter:主节点的入口,创建主节点
akka部署
从starter类来看似乎是要不一样的ip和端口
启动集群的命令:在三台机子上分别
/opt/apps/kafka_2.12-2.6.2/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test-topic
cd /opt/apps/akka-big-data/akka-project
mvn exec:java -Dexec.mainClass=“com.gof.akka.Collaborator” -Dexec.args=“192.168.19.3:6120”
mvn exec:java -Dexec.mainClass=“com.gof.akka.Collaborator” -Dexec.args=“192.168.19.5:6121”
mvn exec:java -Dexec.mainClass=“com.gof.akka.HttpServer” -Dexec.args=“-s 192.168.19.4:6000 -c 192.168.19.3:6120,192.168.19.5:6121”
默认的job是job1
split和merge算子不知道是干什么用的?
解决,split和merge可以看github的介绍
split相当于是增加并行度,创建新的worker
merge相当于是减小并行度,是split的逆向操作
job1:
map:给key+随机数,给v+middle
split:猜测是分裂到不同的机器上
map:给key+随机数,给v取前三个字符+words
filter:key的hashcode%2=0保留
merge:难道是shuffle?
job2:
flatmap:把一个message copy了两份,并且使用了map对k和v进行+x的处理
split:
aggregate:每个v取substring,然后拼一起
filter:过滤掉hashcode为偶数的
merge:
map:给v加了个job2
job3:
flatmap:把一个message copy了两份,并且使用了map对k和v进行+x的处理
split:
aggregate:把v拼在一起
filter:过滤掉hash为奇数
merge:
map:+job3
踩坑1: 带有触发时延的window逻辑设计,把这个List赋值为下一个List的时候直接用=,导致数据输出不对。了解List的性质。应该逐个赋值。
踩坑2: 实现带有延迟的窗口的时候,一批数据很快地发过来的时候,会出现连续输出好几个窗口信息再输出窗口中的数据的情况
分布式锁有木有
dispose源码
dispose梳理
disopose梳理:
client:
consumer&producer:不知道是啥,看起来是对stream进行操作但是好像并没有看到stream
Context是一个进行管理的类,管理各个节点和消息的收发,相当于是整个程序运行的环境
OP:对操作名字的枚举
stream会添加孩子,对应的是算子链?好像不是
operator是算子
log不用管,是日志信息。
net:猜测是在网络里跑的部分?
common:主要写的是基础的数据类型DataAtom还有子类FloatData,DataAtom的父类是
links:不同节点之间的连接?
ObjectFifoLink:传输的数据类型是Message,可能就是要处理的数据的传输
PipeLink:传输的数据类型也是Message
SocketLink:网络连接
Message:
节点之间通信的消息
node:
ckp
sink
source返回出去的是floatdata
operator:extend computeNode extend serilizable
threads
operatorthread比较关键,里面有单个算子的变量
computethread:是operatorthread等多个thread的父类,包含了Node对象和线程计算逻辑
operatorThread里面有operator,operatorThread继承自computeThread
Node里面有 private Map<Integer, ComputeThread> operators;
flink源码
算子链
题目要求:
把算子表现成DAG
支持按照DAG描述的上下游关系
CliFrontend:提交的前端,程序的入口
先找执行类的main方法
首先要判断Generic,yarn,default(standalone)
flink的算子链抽象:
Flink 中的执行图可以分成四层:StreamGraph -> JobGraph -> ExecutionGraph -> 物理执
行图。
StreamGraph(流图,客户端client生成):是根据用户通过 Stream API 编写的代码生成的最初的图。用来表示程序
的拓扑结构。要选择分分区器。
操作:名词改变,出现中间结果集,算子链优化
JobGraph(作业图,客户端client生成) :StreamGraph 经过优化后生成了 JobGraph,提交给 JobManager 的数据结构。
主要的优化为,将多个符合条件的节点 chain 在一起作为一个节点(代码中的体现为把流节点的出边分为可以串的和不可以串的,可以串的),在我们的项目中可以注意一下,这样可以减少数据在节优化后一个JobVertex(作业顶点)可以包含多个算子,边是数据传输通道,把中间结果数据集传到下一个算子
点之间流动所需要的序列化/反序列化/传输消耗。
操作:名词改变,并行化处理,中间结果集变成中间结果分区
最核心的是逻辑执行图(逻辑执行图,JobManager生成) ExecutionGraph:JobManager 根据 JobGraph 生成 ExecutionGraph。ExecutionGraph 是
JobGraph 的并行化版本,是调度层最核心的数据结构。
物 理 执 行 图 : JobManager 根 据 ExecutionGraph 对 Job 进 行 调 度 后 , 在 各 个
TaskManager 上部署 Task 后形成的“图”,并不是一个具体的数据结构。
边相当于网络传输
分布式
题目要求:
多节点
节点间数据shuffle
组件之间的通知:akka
数据的网络传输:netty
RPC:远程方法调用,akka和netty是rpc的实现
Akka是基于Actor模型的一种实现:
每个 actor 是一个单一的线程,它不断地从其邮箱中 poll(拉取)消息。有状态(启动停止),多个actor可以在一台机器共存。有本地。
Akka 系统的核心 ActorSystem 和 Actor,若需构建一个 Akka 系统,首先需要创建ActorSystem,创建完 ActorSystem 后,可通过其创建 Actor(注意:Akka 不允许直接 new 一 个 Actor,只能通过 Akka 提供的某些 API 才能创建或查找 Actor,一般会通过
ActorSystem#actorOf 和 ActorContext#actorOf 来创建 Actor),另外,我们只能通过 ActorRef
(Actor 的引用,其对原生的 Actor 实例做了良好的封装,外界不能随意修改其内部状态)
来与 Actor 进行通信。
若需要与远端 Actor 通信,路径中必须提供 ip:port。
flink自己封装的。
Flink 的 RPC 协议通过 RpcGateway 来定义,主要定义通信行为;用于远程调用
RpcEndpoint 的某些方法,可以理解为对方的客服端代理。
发送信息发到网关,转发。
RpcEndpoint 是通信终端,提供 RPC 服务组件的生命周期管理(start、stop)。每个
RpcEndpoint对应了一个路径(endpointId和actorSystem共同确定),每个路径对应一个Actor,
其实现了 RpcGateway 接口,
RpcService 和 RpcServer 是 RpcEndPoint 的成员变量。 1)RpcService 是 Rpc 服务的接口,其主要作用如下:
⚫ 根据提供的 RpcEndpoint 来启动和停止 RpcServer(Actor);
⚫ 根据提供的地址连接到(对方的)RpcServer,并返回一个 RpcGateway;
⚫ 延迟/立刻调度 Runnable、Callable;
RpcServer 负责接收响应远端 RPC 消息请求(接受网关的请求),自身的代理对象。有两个实现:
⚫ AkkaInvocationHandler
⚫ FencedAkkaInvocationHandler
P29重点关照
踩坑
窗口信息先于窗口数据输出,加锁不行,直接把窗口信息封装进批数据对象里面,在sink输出。
队列赋值问题,直接赋值不行。
脚本不能用,试试后台运行的命令?
1>/dev/null 2>/dev/null &