程序简要设计

Flink时间窗口计算将计算结果写入Druid.io的拓补图结构如下:
在这里插入图片描述
Flink从kafka消费数据,进行分别进行计量和及时的计算,最终将计算结果写入到kafka,最终druid.io使用kafka-inex-service从kafka中拉取数据,将结果写入到Druid.io

程序中的问题

在程序运行的过程中,由于非常偶然的原因,Flink程序异常了,然后Flink从最近的checkpoint中恢复数据,但是在druid.io的记过中发现,在checkpoit这段时间内,数据发生了重复,虽然该问题出现概率非常小,但是由于系统对精度要求比较搞,对于该问题,还是需要处理的.
解决方案如下:
1.调整checkpoint快照的市价间隔,如果时间间隔比较小,那么发生该数据重复的概率就会更小,
2.可以实现在结果数据写入到kafka时,使用kafka producer实现写入的幂等性来保证重复的数据无法写入到druid.io
由于需要考虑到程序的数据恢复问题,方法二能够很好的兼顾数据恢复的问题,所以下面就讨论一下如果实现kakka producer的幂等性问题.

使用Redis分布所实现幂等性

为了实现幂等性,那么久必须保证已经写入的数据,不会再在写入了,为了充分利用redis的高并发行,以及考虑到程序的高并发行,所以要尽可能的减少redis的操作次数,这样很容易实现10W/s的并发.那么根据redis的setnx的操作,这样分布式锁目前来看,是比较符合我们的要求的.
代码实现如下:

 /**
     * 计算结果写入到kafka幂等性的实现
     *
     * @param json
     * @return
     */
    public boolean idempotent(String json) {
        try {
            RedisPool redisPool = RedisPool.instance(properties);
            Jedis jedis = redisPool.getResource();
            String value = "1";
            if (jedis.setnx(json, value) > 0) {
                jedis.expire(json, 24 * 3600);
                redisPool.returnResource(jedis);
                return true;
            }
            redisPool.returnResource(jedis);
        } catch (Exception e) {
            System.err.println("redis pool get redis failed: " + json);
        }
        return false;
    }```
优点:
1.程序可以分组,可以分布式,亦可以用于数据恢复程序
2.减少了对redis操作频度,提高了程序的并发性.
Logo

Kafka开源项目指南提供详尽教程,助开发者掌握其架构、配置和使用,实现高效数据流管理和实时处理。它高性能、可扩展,适合日志收集和实时数据处理,通过持久化保障数据安全,是企业大数据生态系统的核心。

更多推荐