引导Flink作业的API已经到来

Apache Flink是存在的最通用的数据流开源解决方案之一。 它支持典型批处理系统的所有主要功能,例如SQL,Hive连接器,分组依据等,同时提供容错和一次精确的语义。 因此,您可以使用它创建大量基于推送的应用程序。

但是,Apache Flink的主要缺点之一是无法修改程序的检查点状态。 首先让我明白我的意思。

检查点

Flink通过使用称为检查点的机制来提供容错功能。 它会定期为程序的所有有状态操作员/功能创建快照,并将其存储在高度持久的存储中,例如HDFS。
检查点允许Flink程序从该快照恢复。 如果由于某些错误(例如,未处理的简单异常或YARN / Mesos / k8s群集中的数据节点丢失)而导致失败,这将很有帮助。

该快照以二进制格式存储,只有Flink可以理解,这使得在重新启动之前很难修改状态。

为什么需要修改数据?

在很多情况下,您可能只需要来自检查点的部分数据,而您可能想要更新其他数据。 一个示例工作是

从一个Kafka主题中读取数值数据在1小时的窗口内聚合使用存储在操作员状态下的config提供的一些统计阈值进行分类。

public class TestCheckpointJob  {

    public static void main (String[] args) throws Exception  {
        final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime);

        Properties kafkaConsumerProperties = new Properties();
        kafkaConsumerProperties.setProperty( "bootstrap.servers" , "localhost:9092" );
        kafkaConsumerProperties.setProperty( "group.id" , "test_group_id" );

        ObjectMapper objectMapper = new ObjectMapper();
        FlinkKafkaConsumer010<String> kafkaConsumer010 = new FlinkKafkaConsumer010<>( "test_topic" , new SimpleStringSchema(), kafkaConsumerProperties);
        DataStream<String> kafkaSource =  env.addSource(kafkaConsumer010).name( "kafka_source" ).uid( "kafka_source" );
        DataStream<TestData> aggregatedStream = kafkaSource
                .map(row -> objectMapper.readValue(row, TestData.class))
                .keyBy(TestData::getKey)
                .timeWindow(Time.hours( 1 ))
                .reduce((rowA, rowB) -> {
                   TestData result = new TestData();
                    result.setKey(rowA.getKey());
                    result.setValue(rowA.getValue() + rowB.getValue());
                    result.setCreatedAt(System.currentTimeMillis());
                    return result;
                }).name( "aggregate_stream" ).uid( "aggregate_stream" );

        DataStream<LabeledTestData> labeledTestDataDataStream =  aggregatedStream.keyBy(TestData::getKey).flatMap( new ClassifyData()).name( "classify_data" ).uid( "classify_data" );
        labeledTestDataDataStream.map(row -> objectMapper.writeValueAsString(row)).print();
        env.execute();
    }
}
class ClassifyData extends RichFlatMapFunction < TestData , LabeledTestData > {

        ValueState<Integer> threshold;

        @Override
        public void open (Configuration parameters) throws Exception  {
            super .open(parameters);
            threshold = getRuntimeContext().getState( new ValueStateDescriptor<Integer>( "thresholdState" , Integer.class));
        }

        @Override
        public void flatMap (TestData testData, Collector<LabeledTestData> collector) throws Exception  {
            LabeledTestData labeledTestData = new LabeledTestData();
            labeledTestData.setKey(testData.getKey());
            labeledTestData.setValue(testData.getValue());
            labeledTestData.setCreatedAt(testData.getCreatedAt());
            String label = "UNCLASSIFIED" ;
            if (threshold.value() != null ){
                label = (testData.getValue() > threshold.value()) ? "L1" : "L2" ;
            }
            labeledTestData.setLabel(label);
            collector.collect(labeledTestData);
        }
}

假设您的工作被杀死,现在您想使用检查点重新启动它,但是您还需要修改配置。 早先,除了等待作业以旧配置开始并使用来自Kafka或文件系统的流覆盖它之外,没有其他方法可以这样做。

但是,现在,您可以使用新的API轻松地做到这一点。 让我们修改上面的例子。

引导状态

以下是引导您的状态所需的必要步骤

添加依赖

< dependency >
       < groupId > org.apache.flink </ groupId >
        < artifactId > flink-state-processor-api_2.11 </ artifactId >
         < version > 1.9.0 </ version >
</ dependency >

它不包括在默认的Flink依赖项中,需要单独添加到pom.xml文件中。

创建一个Bootstrap函数

class ConfigBootstrapper extends KeyedStateBootstrapFunction < String , TestConfig >  {
        ValueState<Integer> threshold;

        @Override
        public void open (Configuration parameters) throws Exception  {
            threshold = getRuntimeContext().getState( new ValueStateDescriptor<Integer>( "thresholdState" , Integer.class));
        }

        @Override
        public void processElement (TestConfig testConfig, Context context) throws Exception  {
            threshold.update(testConfig.getThresholdValue());
        }
}

此函数告诉Flink接收数据时要更新什么状态。 在此示例中,我们将使用收集的TestConfig数据更新阈值状态。

流动配置数据

BootstrapTransformation<TestConfig> getConfigTransformation (ExecutionEnvironment executionEnvironment) {
     TestConfig testConfig = new TestConfig();
        testConfig.setKey( "global" );
        testConfig.setThresholdValue( 10 );

        DataSet<TestConfig> configDataSet = executionEnvironment.fromElements(testConfig);
        BootstrapTransformation<TestConfig> transformation = OperatorTransformation
                .bootstrapWith(configDataSet)
                .keyBy(TestConfig::getKey)
                .transform( new ConfigBootstrapper());
        return transformation;
}

现在,您需要传输配置数据。 Flink状态处理器API与数据集API无缝协作。 这并不意味着您不能在Stream环境中使用引导程序。 只是引导数据只能使用Batch API加载。 您可以在单个作业中创建批处理和流环境。

在这里,我刚刚创建了一个配置对象,然后在其上面创建了一个数据集。 然后,我们创建一个转换。 它指定要与Bootstrap Function一起使用的数据集。

更新保存点

public class TestCheckpointJob  {

    public static void main (String[] args) throws Exception  {
      bootstrapConfig();
      //Rest same as previous code
    }
}

static void bootstrapConfig () throws IOException  {
        ExecutionEnvironment executionEnvironment = ExecutionEnvironment.getExecutionEnvironment();
        ExistingSavepoint existingSavepoint = Savepoint.load(executionEnvironment, "oldSavepointPath" , new MemoryStateBackend());
        BootstrapTransformation<TestConfig> configTransformation = getConfigTransformation(executionEnvironment);
        String newSavepointPath = "newSavepointPath" ;
        existingSavepoint.withOperator( "classify_data" , configTransformation).write(newSavepointPath);
}

接下来,我们从旧目录加载保存点,然后更新操作员的状态。 要更新状态,我们需要在流作业中指定操作员的UID,并在步骤中创建转换。

完成后,我们可以在新路径中重写此修改的保存点。 请注意,新路径包含旧路径中指针的浅表副本。 这意味着删除旧的保存点路径将损坏新的保存点路径,因此您应避免这样做。

现在,您可以使用此新的保存点路径恢复Flink作业。

bin/flink run -s newSavepointPath test- checkpoint .jar

您甚至可以创建一个新的保存点,而不用更新旧的保存点。 为此,您需要执行Savepoint.create()而不是Savepoint.load()

Flink的状态处理器API是最受欢迎的功能之一,现在终于来了。 该API仅在1.9.0及更高版本中可用。

您可以在官方文档中探索整个API。

LinkedIn Twitter上 与我联系, 发送电子邮件至 kharekartik@gmail.com

From: https://hackernoon.com/developers-the-api-to-bootstrap-your-flink-jobs-has-arrived-0h2c3zt9

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值