flink-RichAsyncFunction

本文测试了Flink中AsyncWaitOperator的基本功能,通过处理有限的数据流并将其值翻倍,验证了有序和无序模式下的操作效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
	 * Tests the basic functionality of the AsyncWaitOperator: Processing a limited stream of
	 * elements by doubling their value. This is tested in for the ordered and unordered mode.
	 */
@Test
public void testAsyncWaitOperator() throws Exception {
    final int numElements = 5;
    final long timeout = 1000L;
    StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
    DataStream<Tuple2<Integer, NonSerializable>> input = env.addSource(new NonSerializableTupleSource(numElements));
    AsyncFunction<Tuple2<Integer, NonSerializable>, Integer> function = new RichAsyncFunction<Tuple2<Integer, NonSerializable>, Integer>() {

        private static final long serialVersionUID = 7000343199829487985L;

        transient ExecutorService executorService;

        @Override
        public void open(Configuration parameters) throws Exception {
            super.open(parameters);
            executorService = Executors.newFixedThreadPool(numElements);
        }

        @Override
        public void close() throws Exception {
            super.close();
            executorService.shutdownNow();
        }

        @Override
        public void asyncInvoke(final Tuple2<Integer, NonSerializable> input, final AsyncCollector<Integer> collector) throws Exception {
            executorService.submit(new Runnable() {

                @Override
                public void run() {
                    collector.collect(Collections.singletonList(input.f0 + input.f0));
                }
            });
        }
    };
    DataStream<Integer> orderedResult = AsyncDataStream.orderedWait(input, function, timeout, TimeUnit.MILLISECONDS, 2).setParallelism(1);
    // save result from ordered process
    final MemorySinkFunction sinkFunction1 = new MemorySinkFunction(0);
    final List<Integer> actualResult1 = new ArrayList<>(numElements);
    MemorySinkFunction.registerCollection(0, actualResult1);
    orderedResult.addSink(sinkFunction1).setParallelism(1);
    DataStream<Integer> unorderedResult = AsyncDataStream.unorderedWait(input, function, timeout, TimeUnit.MILLISECONDS, 2);
    // save result from unordered process
    final MemorySinkFunction sinkFunction2 = new MemorySinkFunction(1);
    final List<Integer> actualResult2 = new ArrayList<>(numElements);
    MemorySinkFunction.registerCollection(1, actualResult2);
    unorderedResult.addSink(sinkFunction2);
    Collection<Integer> expected = new ArrayList<>(10);
    for (int i = 0; i < numElements; i++) {
        expected.add(i + i);
    }
    env.execute();
    Assert.assertEquals(expected, actualResult1);
    Collections.sort(actualResult2);
    Assert.assertEquals(expected, actualResult2);
    MemorySinkFunction.clear();
}

转载于:https://my.oschina.net/u/3005325/blog/3022137

### 腾讯云 Flink 实时处理事实表配置与使用 #### 1. 准备工作 在腾讯云上配置和使用Flink事实表之前,需先完成环境搭建。这包括创建Kubernetes集群并部署Flink作业管理器和服务组件。通过腾讯云容器服务TKE可以轻松实现这一目标[^2]。 ```bash kubectl create namespace flink-cluster helm repo add apache-flink https://apache.github.io/flink-helm helm install my-release --namespace flink-cluster apache-flink/flink ``` #### 2. 数据准备 针对事实表的数据源接入,考虑到数据源的多样性,在构建实时数仓时可选用多种采集工具来获取所需数据流。例如Flume适用于日志收集;Canal用于捕获MySQL数据库变更事件;而Logstash则能灵活对接各类输入插件以适应不同场景下的需求[^3]。 #### 3. 表定义 当涉及到具体的应用开发环节,比如利用SQL API进行操作时,则要依据实际业务逻辑设计相应的schema结构,并将其映射到外部系统的持久化层中形成所谓的“维表”。对于频繁更新但查询频率较低的情况可以选择Redis作为缓存介质;而对于那些读多写少的情形下HBase则是更好的选择之一。 ```sql CREATE TABLE fact_table ( id BIGINT, event_time TIMESTAMP(3), user_id STRING, item_id STRING, category_id STRING, behavior STRING, province STRING, city STRING, WATERMARK FOR event_time AS event_time - INTERVAL '5' SECOND ) WITH ( 'connector.type' = 'kafka', 'connector.version' = 'universal', 'connector.topic' = 'your_topic_name', 'connector.startup-mode' = 'earliest-offset', 'format.type' = 'json' ); ``` 此段代码展示了如何基于Apache Kafka连接器创建一张名为`fact_table`的事实表,其中包含了字段声明及其对应的物理属性描述,同时还指定了时间戳水印策略以便于后续的时间窗口聚合运算支持[^1]。 #### 4. 维度关联 为了能够高效地执行join操作而不影响整体吞吐量表现,建议预先加载静态维度信息至内存当中去。这里可以通过广播变量的方式让每一个taskmanager节点都持有完整的副本拷贝从而减少网络I/O开销。另外一方面也可以考虑引入异步lookup机制进一步优化延迟敏感型应用场景下的响应速度。 ```java // Java Code Example for Async Lookup Join with Redis as Dimension Cache public class AsyncDimJoinFunction extends RichAsyncFunction<String, Tuple2<String, String>> { private transient JedisPool jedisPool; @Override public void open(Configuration parameters) throws Exception { super.open(parameters); this.jedisPool = new JedisPool(new GenericObjectPoolConfig<>(), "localhost", 6379); } @Override public void close() throws Exception { if (jedisPool != null && !jedisPool.isClosed()) { jedisPool.close(); } super.close(); } @Override protected void asyncInvoke(String key, ResultFuture<Tuple2<String, String>> resultFuture) throws Exception { try (Jedis jedis = jedisPool.getResource()) { final String value = jedis.get(key); resultFuture.complete(Collections.singleton(Tuple2.of(key, value))); } catch (Exception e) { resultFuture.completeExceptionally(e); } } } ``` 上述Java片段提供了一个简单的例子说明怎样借助Redis作为辅助索引来加速查找过程中的效率问题解决思路。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值