Flink ClickHouse Sink如何打造生产级高可用写入方案?

2026-05-30 09:385阅读0评论建站教程
  • 内容介绍
  • 文章标签
  • 相关推荐

你有没有遇到过那种情况嗯?就是你辛辛苦苦搭了个Flink作业, 想把数据写进ClickHouse,后来啊发现官方的Sink根本扛不住生产环境的折腾?别骗自己了那玩意儿就是个玩具。我们今天就来聊聊怎么 搞出一套能用、好用、还特么稳定的Flink + ClickHouse写入方案,太硬核了。。

为什么说官方的Flink ClickHouse Sink是“玩具”?

先说个实话:Flink官方提供的那个jdbc sink, 虽然名字听着挺高大上,但一到生产环境就露怯了。它最大的问题就是——没有基于数据量的攒批机制。啥意思呢?就是它只能按记录数攒批, 我悟了。 比如你设置batchSize=1000,那它就等buffer里攒够1000条再刷一次。但如果每条数据都特别大,那还没攒够1000条内存就爆了。你说这能叫高可用吗?

Flink ClickHouse Sink:生产级高可用写入方案|得物技术

而且, 它还不支持动态节点发现、不支持本地表直写、 上手。 不支持重试机制……一句话:太脆了扛不住压力。

痛点一:缺乏基于数据量的攒批机制

代码看起来是这样的:

// Flink 官方 JD娱乐 Sink 的实现
public class JdbcSink extends RichSinkFunction {
    private final int batchSize;// 固定批次大小
    @Override
    public void invoke {
        bufferedValues.add;
        if  == batchSize) {
            flush;
        }
    }
}

看出来了吧?它只看记录数,不管数据大小。这简直就是个定时炸弹。

我们怎么搞?

我们搞了一套自研的Flink ClickHouse Sink,专门用来解决这些痛点。这套方案的核心思 绝绝子! 想是:本地表直写 + 节点动态发现 + 攒批限流 + 重试机制 + Checkpoint保障数据语义。

本地表直写

我们不走分布式表,直接写本地表。为啥?主要原因是分布式表虽然看起来高大上,但性能损耗大,而且容易出问题。我们直接写本地表,再通过分布式表做查询聚合,这样既快又稳。

节点动态发现

ClickHouse集群里的节点会变,你不能写死IP。我们通过ZooKeeper或者配置中心动态获取节点列表,然后自动分配数据到不同的节点上。这样就算某个节点挂了也能自动切换,不影响整体写入,太顶了。。

攒批限流

我们搞了个基于数据量的攒批机制。不光看记录数,还看数据大小。比如你设置最大批次为1MB, 嚯... 那不管多少条记录,只要攒够1MB就刷一次。这样既能控制内存,又能提高写入效率。

重试机制

写入失败?别怕,我们有重试。而且是指数退避重试,不是那种死板的重试3次。 躺平... 我们还加了写入失败的告警机制,出问题了立马通知你。

Checkpoint保障数据语义

Flink的Checkpoint机制是我们的救命稻草。我们把每次Checkpoint的状态都保存下来 一旦出问题,就能从最近的Checkpoint恢复,保证数据不丢不重。

性能调优

光有机制还不够,还得调优。我们从以下几个方面入手:

  • 并行度调优根据数据量和集群规模, 合理设置Flink作业的并行度,避免资源浪费或瓶颈。
  • 内存调优:合理设置Flink的内存参数,避免OOM。
  • 网络调优调整网络缓冲区大小,提高网络传输效率。
  • SQL优化优化ClickHouse的表结构和索引,提高查询和写入性能。

对比一下市面上的几种方案

方案 优点 缺点 适用场景
官方Flink JD娱乐 Sink 简单易用, 官方支持 功能简陋,不支持动态节点发现、攒批机制差 小数据量、测试环境
自研Flink ClickHouse Sink 高可用、高性能、支持动态节点发现和本地表直写 开发成本高 生产环境、大数据量场景
第三方开源方案 功能丰富,社区支持 稳定性参差不齐,需要二次开发 中等规模项目

代码示例

下面是一个简单的代码示例,展示如何使用自研的 PTSD了... Flink ClickHouse Sink:

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment;
// 设置Checkpoint
env.enableCheckpointing;
// 添加数据源
DataStream source = env.addSource, properties));
// 自定义Sink
ClickHouseSinkFunction sink = new ClickHouseSinkFunction(
    "jdbc:clickhouse://localhost:8123/default",
    "table_name",
    "user",
    "password"
);
source.addSink;
env.execute;

常见问题和解决方案

  • 问题1:数据写入延迟高
    • 解决方案优化攒批策略,增加并行度,调整网络参数。
  • 问题2:数据丢失
    • 解决方案启用Checkpoint机制,确保数据语义。
  • 问题3:节点故障导致写入失败
    • 解决方案实现节点动态发现和重试机制。

Flink + ClickHouse的组合虽然强大,但要真正用好,还得自己动手丰衣足食。官方的方案只能作为参考,真正落地还得靠自研的高可用写入方案。我们这套方案,从本地表直写、 你看啊... 节点动态发现、攒批限流到重试机制,全方位保障了数据写入的稳定性和高效性。如果你也在搞Flink + ClickHouse,不妨试试我们这套方案,保证让你少走弯路,多睡好觉。

你有没有遇到过那种情况嗯?就是你辛辛苦苦搭了个Flink作业, 想把数据写进ClickHouse,后来啊发现官方的Sink根本扛不住生产环境的折腾?别骗自己了那玩意儿就是个玩具。我们今天就来聊聊怎么 搞出一套能用、好用、还特么稳定的Flink + ClickHouse写入方案,太硬核了。。

为什么说官方的Flink ClickHouse Sink是“玩具”?

先说个实话:Flink官方提供的那个jdbc sink, 虽然名字听着挺高大上,但一到生产环境就露怯了。它最大的问题就是——没有基于数据量的攒批机制。啥意思呢?就是它只能按记录数攒批, 我悟了。 比如你设置batchSize=1000,那它就等buffer里攒够1000条再刷一次。但如果每条数据都特别大,那还没攒够1000条内存就爆了。你说这能叫高可用吗?

Flink ClickHouse Sink:生产级高可用写入方案|得物技术

而且, 它还不支持动态节点发现、不支持本地表直写、 上手。 不支持重试机制……一句话:太脆了扛不住压力。

痛点一:缺乏基于数据量的攒批机制

代码看起来是这样的:

// Flink 官方 JD娱乐 Sink 的实现
public class JdbcSink extends RichSinkFunction {
    private final int batchSize;// 固定批次大小
    @Override
    public void invoke {
        bufferedValues.add;
        if  == batchSize) {
            flush;
        }
    }
}

看出来了吧?它只看记录数,不管数据大小。这简直就是个定时炸弹。

我们怎么搞?

我们搞了一套自研的Flink ClickHouse Sink,专门用来解决这些痛点。这套方案的核心思 绝绝子! 想是:本地表直写 + 节点动态发现 + 攒批限流 + 重试机制 + Checkpoint保障数据语义。

本地表直写

我们不走分布式表,直接写本地表。为啥?主要原因是分布式表虽然看起来高大上,但性能损耗大,而且容易出问题。我们直接写本地表,再通过分布式表做查询聚合,这样既快又稳。

节点动态发现

ClickHouse集群里的节点会变,你不能写死IP。我们通过ZooKeeper或者配置中心动态获取节点列表,然后自动分配数据到不同的节点上。这样就算某个节点挂了也能自动切换,不影响整体写入,太顶了。。

攒批限流

我们搞了个基于数据量的攒批机制。不光看记录数,还看数据大小。比如你设置最大批次为1MB, 嚯... 那不管多少条记录,只要攒够1MB就刷一次。这样既能控制内存,又能提高写入效率。

重试机制

写入失败?别怕,我们有重试。而且是指数退避重试,不是那种死板的重试3次。 躺平... 我们还加了写入失败的告警机制,出问题了立马通知你。

Checkpoint保障数据语义

Flink的Checkpoint机制是我们的救命稻草。我们把每次Checkpoint的状态都保存下来 一旦出问题,就能从最近的Checkpoint恢复,保证数据不丢不重。

性能调优

光有机制还不够,还得调优。我们从以下几个方面入手:

  • 并行度调优根据数据量和集群规模, 合理设置Flink作业的并行度,避免资源浪费或瓶颈。
  • 内存调优:合理设置Flink的内存参数,避免OOM。
  • 网络调优调整网络缓冲区大小,提高网络传输效率。
  • SQL优化优化ClickHouse的表结构和索引,提高查询和写入性能。

对比一下市面上的几种方案

方案 优点 缺点 适用场景
官方Flink JD娱乐 Sink 简单易用, 官方支持 功能简陋,不支持动态节点发现、攒批机制差 小数据量、测试环境
自研Flink ClickHouse Sink 高可用、高性能、支持动态节点发现和本地表直写 开发成本高 生产环境、大数据量场景
第三方开源方案 功能丰富,社区支持 稳定性参差不齐,需要二次开发 中等规模项目

代码示例

下面是一个简单的代码示例,展示如何使用自研的 PTSD了... Flink ClickHouse Sink:

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment;
// 设置Checkpoint
env.enableCheckpointing;
// 添加数据源
DataStream source = env.addSource, properties));
// 自定义Sink
ClickHouseSinkFunction sink = new ClickHouseSinkFunction(
    "jdbc:clickhouse://localhost:8123/default",
    "table_name",
    "user",
    "password"
);
source.addSink;
env.execute;

常见问题和解决方案

  • 问题1:数据写入延迟高
    • 解决方案优化攒批策略,增加并行度,调整网络参数。
  • 问题2:数据丢失
    • 解决方案启用Checkpoint机制,确保数据语义。
  • 问题3:节点故障导致写入失败
    • 解决方案实现节点动态发现和重试机制。

Flink + ClickHouse的组合虽然强大,但要真正用好,还得自己动手丰衣足食。官方的方案只能作为参考,真正落地还得靠自研的高可用写入方案。我们这套方案,从本地表直写、 你看啊... 节点动态发现、攒批限流到重试机制,全方位保障了数据写入的稳定性和高效性。如果你也在搞Flink + ClickHouse,不妨试试我们这套方案,保证让你少走弯路,多睡好觉。