订单中心的技术方案设计

2,192 阅读3分钟

问题描述

  1. 存储10E级别的订单
  2. 数据源多个,结构异同,不同数据源订单关联表在15-70不等,
  3. 有的数据源存储的是mongo,有的则是mysql
  4. 提供统一数据结构
  5. 提供统一的存储,查询

分析

  1. 存储选择:因为持续稳定的增量,使用mycat需要扩容,扩容是一件很复杂的事情,同时也需要长期维护。并且结构设计也异同,所以综合考虑采用mongo4.0.9
  2. mysql的binlog,期望做到无关业务系统改造,弱耦合,所以通过监听binlog实现事件通知机制,采用canal
  3. mongo的oplog,有数据源是基于mongo存储的,3.2版本不支持oplog,遂升级至4.0.9,增加replication,支持oplog的changestream通知。
  4. 消息通知,因为对数据丢失的零容忍,所以采用rocketmq的发送机制,broker不挂掉的情况下,是不会丢失数据的
  5. 缓存,采用redis cluster,因为事件是需要支持亿级别的,所以会有大量的cache hit,需要3台redis cluster实例
  6. 技术框架,基于生态考虑,采用springcloud
  7. 线程问题,提升单节点性能和线程安全,是重中之重

指标

  1. 项目周期:1.5月
  2. 平峰订单增量50w/day,高峰600w/day
  3. 事件数支持亿级别
  4. 单节点处理能力6kw/day

系统设计

系统设计

ococ-prepare模块设计

ococ-handler模块设计

核心模块交互设计

ococ-handler子流程

阶段分析

第一阶段:解决阿里云rds binlog同步过大的问题

  1. 通过在rds部署sync服务,过滤不关心ddl,减少binlog产生
  2. rds部署库,通过sync写入,产生binlog
  3. 公司机房部署从库,并行同步

第二阶段:ococ-collect收集过程

  1. 从库均部署在公司机房,减少跨机房查询延迟,通过测试,机房内部多线程batch query在1s,跨机房40s
  2. 通过canal监听mysql的binlog,通过mongo的changestream监听oplog
  3. binlog数据调用prepare模块进行解析,找到订单id
  4. mongo数据调用handler模块直接进行存储
  5. 定义事件规则json,如果命中则调用biz模块

第三阶段:ococ-prepare反查聚合阶段

  1. 定义队列数据,进行merge合并
  2. 多线程,分层级,非阻塞的batch query orderid
  3. 将反查的结果orderid调用handler模块

第四阶段:ococ-handler存储

  1. 通过订单id,多线程batch聚合数据,存储
  2. 手机号解析

第五阶段:ococ-biz业务中心

  1. 收到需要处理的订单id,命中匹配规则,触发调用其他业务系统逻辑
  2. 当modifyTime > binlogTime,代表数据为新,触发调用,否则阻塞

其他

mongodb.conf

systemLog:  
    quiet: false  
    path: /data0/mongodb_28019/logs/mongodb_28019.log
    logAppend: true  
    destination: file  
processManagement:  
    fork: true

net:  
    bindIp: 0.0.0.0  
    port: 28019
    maxIncomingConnections: 10000  
    wireObjectCheck: true  
    ipv6: false   
    compression:
        compressors: snappy
    serviceExecutor: adaptive

storage:  
    dbPath: /data0/mongodb_28019/data  
    journal:  
        enabled: true  
        commitIntervalMs: 100
    directoryPerDB: true
    engine: wiredTiger
    syncPeriodSecs: 60   
    wiredTiger:  
        engineConfig:  
            cacheSizeGB: 64  
            journalCompressor: snappy  
            directoryForIndexes: true
        collectionConfig:  
            blockCompressor: snappy  
        indexConfig:  
            prefixCompression: true  

setParameter: 
    maxIndexBuildMemoryUsageMegabytes: 5000


sharding:  
    clusterRole: shardsvr  
    archiveMovedChunks: false