怎么做到Kafka顺序读写

1、业务场景

一个大的binlog数据库,还原出来了很多SQL语句
binlog生成SQL语句方式

SQL语句需要顺序执行,因为不顺序执行,比如先新增了一条数据,才有可能修改这条数据,假如先执行修改操作,后执行新增操作,那这个数据就错了

2、技术方案选型

  1. 如果表的binlog文件很小,直接执行就可以了;
  2. 如果表的binlog太大,那直接执行效率非常低,而且如果某个是否读写出了问题都不知道要从哪里重新执行(如执行时机器出现问题,执行SQL不仅需要读入binlog文件,还要执行SQL语句,频繁的执行SQL可能到至数据库CPU等飙升,可能存在一些执行错误的问题);
  3. 借助消息队列,可以重复消费来实现,并且通过代码抓取异常来判断是否消费成功,是否重复消费,并且也可以做削峰填谷,批量消费,控制流量,防止Mysql宕机或拒绝连接等;

3、消息队列选型

选择kafka,因为kafka写入同一个partition(目录)的数据是顺序的,写入的offset是递增的,我们只需要保证同一个partition消费是顺序的就可以了
Kafka原理

4、设计思路

前提条件:数据库没有做物理外键处理,否则每张表的消息处理可能都存在先后顺序,那个就需要逻辑代码实现

发送端

  1. 把同一张表,通过表名求hash,发送到指定的分区,这样,同一个表名的执行SQL在队列的partition中肯定是有序的;

消费端

  1. 使用单线程,完全没有问题,但性能太低;
  2. 直接使用多线程;因为在发送的时候,同一张表存储的partition是顺序的,这样消费的时候,对同一张partion消费是有序的;
  3. 批量拉取,使用手动提交,使用CountDownLatch保证所有的线程执行完成才能提交偏移量;
  4. 线程池执行SQL,如果某个SQL消费异常,抓取异常(如果是重试能解决的异常就通过重试解决,比如数据库连接过多等),记录失败SQL,停止消费,提交偏移量,存在执行失败的SQL,抛出异常,停止继续消费,分析SQL执行失败原因,订正消费代码,手动执行完成失败SQL,之后重新执行,继续开始消费;

你可能感兴趣的:(所遇问题,kafka)