Redis分布式锁实现数据写入幂等性
程序简要设计Flink时间窗口计算将计算结果写入Druid.io的拓补图结构如下:Flink从kafka消费数据,进行分别进行计量和及时的计算,最终将计算结果写入到kafka,最终druid.io使用kafka-inex-service从kafka中拉取数据,将结果写入到Druid.io程序中的问题在程序运行的过程中,由于非常偶然的原因,Flink程序异常了,然后Flink从最近的che...
程序简要设计
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操作频度,提高了程序的并发性.
更多推荐
所有评论(0)