Flink的基于两阶段提交协议的事务数据汇实现

背景

在flink中可以通过使用事务性数据汇实现精准一次的保证,本文基于Kakfa的事务处理来看一下在Flink 内部如何实现基于两阶段提交协议的事务性数据汇.

1。首先在开始进行快照的时候也就是收到checkpoint通知的时候,在snapshot方法中会开启一个新的事务,代码如下:

java 复制代码
   public void snapshotState(FunctionSnapshotContext context) throws Exception {
        // this is like the pre-commit of a 2-phase-commit transaction
        // we are ready to commit and remember the transaction

        checkState(
                currentTransactionHolder != null,
                "bug: no transaction object when performing state snapshot");

        long checkpointId = context.getCheckpointId();
        LOG.debug(
                "{} - checkpoint {} triggered, flushing transaction '{}'",
                name(),
                context.getCheckpointId(),
                currentTransactionHolder);

        preCommit(currentTransactionHolder.handle);
        // 调用kafkaProducer.flush();清理上一个事务的状态(注意不是提交),只是确保前一个事务的所有资源清理完毕
        pendingCommitTransactions.put(checkpointId, currentTransactionHolder);
        LOG.debug("{} - stored pending transactions {}", name(), pendingCommitTransactions);
// 调用producer.beginTransaction();方法开启一个新的kafka事务
        currentTransactionHolder = beginTransactionInternal();
        LOG.debug("{} - started new transaction '{}'", name(), currentTransactionHolder);

        state.clear();
        state.add(
                new State<>(
                        this.currentTransactionHolder,
                        new ArrayList<>(pendingCommitTransactions.values()),
                        userContext));
    }

2.其次在JobManager通知检查点完成的通知方法,也就是notifyCheckpointComplete方法中提交事务

java 复制代码
Iterator<Map.Entry<Long, TransactionHolder<TXN>>> pendingTransactionIterator =
                pendingCommitTransactions.entrySet().iterator();
        Throwable firstError = null;

        while (pendingTransactionIterator.hasNext()) {
            Map.Entry<Long, TransactionHolder<TXN>> entry = pendingTransactionIterator.next();
            Long pendingTransactionCheckpointId = entry.getKey();
            TransactionHolder<TXN> pendingTransaction = entry.getValue();
            if (pendingTransactionCheckpointId > checkpointId) {
                continue;
            }

            LOG.info(
                    "{} - checkpoint {} complete, committing transaction {} from checkpoint {}",
                    name(),
                    checkpointId,
                    pendingTransaction,
                    pendingTransactionCheckpointId);

            logWarningIfTimeoutAlmostReached(pendingTransaction);
            try {
            //调用producer.commitTransaction()方法提交事务
                commit(pendingTransaction.handle);
            } catch (Throwable t) {
                if (firstError == null) {
                    firstError = t;
                }
            }

            LOG.debug("{} - committed checkpoint transaction {}", name(), pendingTransaction);

            pendingTransactionIterator.remove();
        }

        if (firstError != null) {
            throw new FlinkRuntimeException(
                    "Committing one of transactions failed, logging first encountered failure",
                    firstError);
        }

至此,一个两阶段提交的flink事务性数据汇完成了,这个事务性数据汇可以构成端到端一致性的一部分

相关推荐
哦你看看37 分钟前
Elasticsearch+Logstash+Filebeat+Kibana部署[7.17.3版本]
大数据·elasticsearch·搜索引擎
陈果然DeepVersion1 小时前
Java大厂面试真题:Spring Boot+微服务+AI智能客服三轮技术拷问实录(四)
spring boot·redis·微服务·kafka·spring security·智能客服·java面试
小鹿学程序2 小时前
搭建hadoop集群
大数据·hadoop·分布式
ApacheSeaTunnel2 小时前
LLM 时代,DataAgent × WhaleTunnel 如何将数据库变更瞬时 “转译” 为洞察?
大数据·ai·开源·llm·数据同步·白鲸开源·whaletunnel
凯子坚持 c3 小时前
从零开始:开发一个仓颉三方库的完整实战
大数据·elasticsearch·搜索引擎
人大博士的交易之路4 小时前
今日行情明日机会——20251104
大数据·数据挖掘·数据分析·缠论·涨停回马枪·道琼斯结构
John Song4 小时前
用zookpeer搭建Hadoop的HA集群,组件启动的启动顺序是什么?
大数据·hadoop·debian
Hello.Reader4 小时前
Flink Table API & SQL 概念、常用 API 与工程落地
大数据·sql·flink
陈果然DeepVersion5 小时前
Java大厂面试真题:Spring Boot+Kafka+AI智能客服场景全流程解析(七)
java·人工智能·spring boot·微服务·kafka·面试题·rag
Empty_7777 小时前
Elasticsearch+Logstash+Filebeat+Kibana部署
大数据·elasticsearch·搜索引擎