当你点进这个博客的时候,你应该是遇到了和我一样的问题:通常情况下我们运行flink作业时,都会将State存储到HDFS,比如:
env.setStateBackend(new RocksDBStateBackend("hdfs://hadoop100:8020/tmp/flink/checkpoints",true).getCheckpointBackend());
当checkpoint被触发时,我们作业中使用的state(ListState、MapState等),都会被存储到/tmp/flink/checkpoints目录下。
不管是在两阶段提交时某个并行度的chk失败,还是我们的应用挂掉,通过flink run -s hdfs://hadoop100:8020/tmp/flink/checkpoints/xxx/chk-x/_metedate来进行重启(可继续使用之前应用的state中的数据),这都需要依赖一个统一的文件系统。
但是,当我们希望flink独立运行,不依赖hadoop的时候,比如我们的服务根本就用不到hadoop这么重量级的框架,我们又该如何保存state呢?
针对这个问题,想到了两个解决方法:
1、RocksDBStateBackend("file:///opt/zxcvb",true).getCheckpointBackend());
2、使用ftp。
第一种方式,作业可以正常运行,且state可以正常存储,但是每个节点上存储的chk文件只是整个作业的一部分。当作业失败,我们想通过指定chk文件的方式重启作业时,会抛异常(文件找不到,一个节点上需要另一个节点上的文件)。如果我们希望在这种方式下启动,就需要把每个节点上的chk文件都拷贝到其他节点,保证每个节点上的chk文件都相同,就可以了。但是当我们的节点比较多的时候呢?
第二种方式,既然我们想将chk文件放到同一个地方,在重新启动作业的时候大家都可以访问,那么我们可以在一台机器上安装一个ftp服务,让flink所有的节点都将chk数据存储到ftp机器上的某个文件夹下,这样,问题得到了很好的解决。
步骤:
1、安装ftp服务(网上资料很多):
yum install -y vsftpd
开启ftp服务:
service vsftpd start
添加用户:
useradd abc
passwd def
2、配置chk目录,可以在flink-conf.yaml配置state.checkpoints.dir,也可以在创建RocksDBStateBackend时传入
env.setStateBackend(new RocksDBStateBackend("ftp://abc:def@192.168.1.xx:21/home/abc/chk",true).getCheckpointBackend());
这样,当作业启动后,可以在ftp目录下看到chk文件。当作业失败时,也可以通过-s 指定chk的目录。
需要有hadoop的jar包依赖: