线上设置的Kafka默认配置是3个Partition,设我们传递的数据是用户的信息如下
用户id | 用户名 | 具体信息 | 动作 |
---|---|---|---|
001 | zhangsan | … | 插入 |
001 | zhangsan | … | 修改 |
001 | zhangsan | … | 删除 |
002 | lisi | … | 插入 |
生产者分别向不同的主Partition发送数据,消费者每5秒去消费数据,因为Kafka是全局无序且局部数据有序,所以可能会出现的结果是这样的:
按照业务来说第001条数据是被删除的,但是入湖同步后数据是修改后的数据,另外002是正确的。上面的问题主要来自,相同的数据在不同SparkStreaming的分区中运行,将数据的 id 进行Hash取模再写到对应的分区中,相同id的数据在同一分区中,局部有序可以解决问题。如下图:
原理只有1个,保证相同的业务数据在同一分区中。如果id是数字,直接%numPartition即可,如果id很长,也可以截取一部分在去取模。方法不止一种。