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、对中间件的使用还要更慎重,少踩雷。 

  • 相关阅读:
    洛谷 P1508 Likecloud-吃、吃、吃
    Codevs 1158 尼克的任务
    2017.10.6 国庆清北 D6T2 同余方程组
    2017.10.6 国庆清北 D6T1 排序
    2017.10.3 国庆清北 D3T3 解迷游戏
    2017.10.3 国庆清北 D3T2 公交车
    2017.10.3 国庆清北 D3T1 括号序列
    2017.10.4 国庆清北 D4T1 财富
    2017.10.7 国庆清北 D7T2 第k大区间
    2017.10.7 国庆清北 D7T1 计数
  • 原文地址:https://www.cnblogs.com/dongqingswt/p/3095974.html
Copyright © 2011-2022 走看看