Kafka中如何做到数据唯一,即数据去重?

1.至少一次(At Least Once)= ACK级别设置为-1 + 分区副本大于等于2 + ISR里应答的最小副本数量大于等于2

2.最多一次(At Most Once= ACK级别设置为0

3.精确一次(Exactly Once):对于一些非常重要的信息,比如和钱相关的数据,要求数据既不能重复也不丢失。

优缺点:At Least Once可以保证数据不丢失,但是不能保证数据不重复;

                At Most Once可以保证数据不重复,但是不能保证数据不丢失。

                Exactly Once--幂等性和事务可以保障数据精确一次

4.Kafka 0.11版本以后,引入了一项重大特性:幂等性和事务。

5.幂等性

        1)原理

幂等性就是指Producer不论向Broker发送多少次重复数据,Broker端都只会持久化一条,保证了不重复。

举例: 订单支付--> 用户付款--调用支付宝接口-->回写订单数据--> 发起一个异步线程,用于修改订单数据。 此时会遇到一个问题,支付的订单修改状态,修改了两次。

精确一次(Exactly Once) = 幂等性 + 至少一次( ack=-1 + 分区副本数>=2 + ISR最小副本数量>=2) 。

重复数据的判断标准:具有<PID, Partition, SeqNumber>相同主键的消息提交时,Broker只会持久化一条。其 中PID是Kafka每次重启都会分配一个新的;Partition 表示分区号;Sequence Number是单调自增的。

所以幂等性只能保证的是在单分区单会话内不重复。

如果kafka集群挂了,重启了,此时以前的数据还会发送一回,数据又重复了。

         2)如何使用

开启参数 enable.idempotence 默认为 true,false 关闭。

6.生产者事务

        使用原因:幂等性只能保障服务器不挂掉的情况下,发送数据是唯一的,假如发送者服务器挂掉了,那么重启之后还是会发送重复的数据,所以需要使用事务

1)kafka事务原理

每一个broker都有一个事务协调器

 2)共有5个api

// 1 初始化事务
void initTransactions();
// 2 开启事务
void beginTransaction() throws ProducerFencedException;
// 3 在事务内提交已经消费的偏移量(主要用于消费者)
void sendOffsetsToTransaction(Map<TopicPartition, OffsetAndMetadata> offsets,
 String consumerGroupId) throws 
ProducerFencedException;
// 4 提交事务
void commitTransaction() throws ProducerFencedException;
// 5 放弃事务(类似于回滚事务的操作)
void abortTransaction() throws ProducerFencedException;

3)单个生产者,使用事务保证消息的仅一次发送

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,要使用Flink CDC将数据同步到Kafka,需要在Flink任务引入Flink CDC库。然后,可以通过以下步骤实现数据同步: 1. 配置Flink CDC连接到源数据库:需要指定数据库类型、主机、端口、数据库名称、用户名和密码等信息。 2. 配置Flink CDC连接到目标Kafka:需要指定Kafka的地址和端口。 3. 定义数据源并创建CDC Source:使用Flink CDC提供的JDBC Source Function从源数据读取数据。 4. 定义数据的序列化和反序列化方法:Flink CDC会自动将从源数据读取的数据序列化成JSON格式,需要将其反序列化成Java对象。 5. 将数据写入Kafka:使用Flink Kafka Producer将数据写入Kafka。 下面是一个实现Flink CDC将数据同步到Kafka的示例代码: ```java StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 配置Flink CDC连接到源数据库 JdbcConnectionOptions connectionOptions = JdbcConnectionOptions .builder() .withDriverName("org.postgresql.Driver") .withUrl("jdbc:postgresql://localhost:5432/mydb") .withUsername("user") .withPassword("password") .build(); // 配置Flink CDC连接到目标Kafka Properties kafkaProperties = new Properties(); kafkaProperties.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); // 定义数据源并创建CDC Source CDCSource<RowData> source = CDCSource .<RowData>builder() .jdbcConnectionOptions(connectionOptions) .tableList("mytable") .deserializer(new RowDataDebeziumDeserializeSchema()) .build(); // 定义数据的序列化和反序列化方法 SerializationSchema<MyObject> serializationSchema = new MyObjectSerializationSchema(); DeserializationSchema<MyObject> deserializationSchema = new MyObjectDeserializationSchema(); // 将数据写入Kafka FlinkKafkaProducer<MyObject> kafkaProducer = new FlinkKafkaProducer<>( "my-topic", serializationSchema, kafkaProperties, FlinkKafkaProducer.Semantic.EXACTLY_ONCE); DataStream<MyObject> stream = env .addSource(source) .map(new MyObjectMapFunction()) .returns(MyObject.class); stream .addSink(kafkaProducer); env.execute("Flink CDC to Kafka"); ``` 在上面的示例代码,`MyObject`代表从源数据读取的数据,`RowDataDebeziumDeserializeSchema`代表将从Flink CDC读取的数据反序列化成`RowData`对象,`MyObjectSerializationSchema`代表将`MyObject`对象序列化成JSON格式,`MyObjectDeserializationSchema`代表将JSON格式的数据反序列化成`MyObject`对象,`MyObjectMapFunction`代表将`RowData`对象转换成`MyObject`对象。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值