zoukankan      html  css  js  c++  java
  • 从解决一个精卫数据同步问题想到的

    今天,同事武杨发现使用精卫做一个商品排期表的数据同步有问题,问题表现在重新排期的商品在一个终搜查询系统里面查不到记录了。

    1、分析精卫中间件的数据同步机制,它是分析mysql binlog ,解析成RowChangeEvent以后,包装成消息通过消息中间件Meta发送消息到消息网关

    MetaServer,然后再由消息订阅者消费消息,解析消息中的RowChangeEvent以后,同步到搜索系统的。

    2、而从业务逻辑上看,排期操作是先逻辑删除旧的排期记录,再插入一条新的排期记录,update和insert是在一个事务的。 示意如下:

    set autocommit =0 ;

    #这条update操作因为有 KEY `idx_iod_jid` (`ju_id`,`is_deleted`,`online_end_time`) 这个索引的存在保证了A商品的排期不会影响到B商品,

    #即采用了行锁。

    update item_online_detail set is_deleted=1 where is_deleted=0 and ju_id in (?)

    insert into item_online_detail (?,?,...,?)

    commit; 

    而武杨查看日志,发现insert 和update操作有乱序 。造成插入的记录,被错误的delete了。

    3、进一步分析精卫中间件,结合源码发现精卫在提取binlog(DbExtractor) 和消费binlog时(HdfsApplier),可以配置多线程,而精卫通过把一行记录hash到一个线程,来保证一行记录的处理不会乱序。而消息中间件Meta,则在消息发送时一个线程的消息发送到一个分区,消息订阅时一个分组中的一台机器负责一个分区的消息,来保证顺序。

    最后发现问题是在于在数据提取时(DbExtractor)配置了多线程,而对记录hash到binlog提取线程的操作使用了item_online_detail表的id,而不是ju_id,

    而每次排期操作的id是会变的,这就导致对一个ju_id的操作会交给不同的线程处理而导致乱序。而且武杨在快速多次对同一商品进行排期时重现了这一问题。

    总结原因:1、可能我们对系统的压力测试还要做充分一些,才能发现这种问题。2、对中间件的使用还要更慎重,少踩雷。 

  • 相关阅读:
    LeetCode-Pascal's Triangle
    macOS Sierra 10.12版本 显示隐藏文件
    Android主页导航:fragment+viewpager
    (转)Android工程出现 java.lang.NoClassDefFoundError错误解决方法
    Android Studio安装以及Fetching android sdk component information超时的解决方案
    Android项目使用Ant多渠道打包(最新sdk)
    eclipse或Myeclipse中web项目没有run on server时怎么办?
    mysq查询语句包含中文以及中文乱码,字符集 GBK、GB2312、UTF8的区别
    论HTML的div、span和label的区别
    斐波那契数列
  • 原文地址:https://www.cnblogs.com/dongqingswt/p/3095974.html
Copyright © 2011-2022 走看看