美团业务正确性校验平台 BCP的设计与实践
如果无法正常显示,请先停止浏览器的去广告插件。
1. 美团业务正确性校验平台
BCP的设计与实践
美团基础架构部
2. 个人简介
叶明
基础架构部-服务保障组
2017 年加入美团,先后参与过Squirrel分布式缓存、DTS数据传输服务、BCP业务正确性校验平
台、SWAN分布式事务等中间件建设。目前,主要负责BCP和SWAN相关的研发工作
3. 目录
01 背景介绍
02 技术设计
03 最佳实践
04 未来规划
CONTENTS
目
录
4. BCP产生背景-数据异常问题
分布式环境下,RPC调用超时、MQ丢消息、存储组件读写失败难以避免,导致服务内部/服务之间出现数据问题
一致性:异地多活场景,同步出现问
题导致数据不一致
时效性:系统原因用户下单后没有准时
收到外卖
正确性:核对账单,
少了一笔费用导致对账不平衡
结算单1
上海DB
北京DB
外卖下单
结算单2
数据同步
结算单n
账单
5. BCP产生背景-数据问题处理流程
用户投诉 客服处理 技术人员排查
BCP实时核对 发现异常 自动修复
事后排查,时效性差,影响口碑
事中校验,实时发现数据异常
6. BCP是什么
订阅事件
编写规则
BCP管理平台
BCP(Business Check Platform)美团业务正确性校验平台
标准化数据源接入,基于事件触发核对规则的执行,实时发现
异常数据并及时订正
Binlog接入 Java规则 规则执行统计
MQ接入 Aviator规则 异常数据告警
数据订正
Redis接入
事件管理器
规则管理器
BCP核对方案
监控告警
7. BCP接入规模
3000+ 200亿+/天
规则个数 规则核对次数
400亿+/天
Binlog订阅量
50亿+/天
MQ订阅量
多次帮助业务发现数据异常
8. 目录
01 背景介绍
02 技术设计
03 最佳实践
04 未来规划
CONTENTS
目
录
9. BCP技术设计
整体架构
系统处理过程
整体架构
稳定性保
障设计
10. BCP系统处理流程
购买逻辑涉及更新订单和支付单状态,假设我们需要校验用户下单 60s 内是否完成支付且金额是
否一致。我会从系统(宏观)和规则(微观)两个层面叙述系统行为。
订单
订阅Binlog
消息订阅服务
匹配键:订单id
缓存
支付
订阅Binlog
消息订阅服务
匹配键:订单id
延时时间
规则执行服务
一致?
N
告警
11. BCP规则执行流程
T1
延时时间
T3
订单表(触发消息)
检验每一笔交易60s内是否完成支付
T2
① 订单表产生Binlog,订单 ID 为匹配键
支付表(目标消息)
②支付表产生Binlog,订单 ID 为匹配键
③60s之后根据匹配键触发消息组装
BCP规则执行
执行核对规则
order.id == payment.id &&
order.amount == payment.amount
12. BCP整体架构
BCP核心服务包括消息订阅服务和规则执行服务,基于事件驱动的方式进行实时校验。
支付 trigger queue
订单
enqueue
触发消息
dequeue
订单binlog
60后触发组装
write
支付
延时
队列
目标消息
支付binlog
是否熔断
缓存
read
filter
推送
check
泛化调用
泛化调用
金融
外卖
组装
数据不完整告警
alarm
数据错误告警
自动修复
到店
业务服务
消息订阅服务
规则执行服务
13. BCP整体架构-消息订阅服务
消息订阅服务主要包含:数据订阅、数据转换模块
DB
变更 Binlog Parser
MQ
变更 MQ
Consumer
Redis
变更 Redis Aof
Parser
ES
变更
延时触发队列
TTL 分钟小时级别
触发消息数据
Redis
TTL 天级别
ES Translog
Parser 目标消息数据
数据订阅 数据转换
Tair
14. 消息订阅服务-增量订阅组件
标准化的数据订阅CDC组件
DB
变更 Binlog Parser MQ
变更 MQ
Consumer 新创建一个单独消费组
Redis
变更 Redis Aof
Parser 实现redis 主从协议
ES
变更 ES Translog
Parser
对接Binlog、MQ、Redis、ES
binlog dump
调研中
15. 消息订阅服务-数据转换
延时触发队列
延时队列:基于触发消息时间戳生成
触发消息:用来驱动规则校验的事件
订单
TTL 分钟小时级别
触发消息
触发消息数据
目标消息:被驱动事件
Redis
TTL 天级别
支持双向校验:订单和支付双向触发
支付
目标消息
目标消息数据
Tair
16. 分布式延时队列-背景
双流核对的场景,需要设计一个延时队列,将触发消息先投递到队列,一定延时时间以后再执行
T1
延时时间
T3
订单表(驱动)
T2
支付表(被驱动)
T1时刻触发核对,
缺支付消息告警
T3时刻订单和支付信息匹配
校验通过
17. 分布式延时队列-整体设计
整体设计思路:基于Redis zset和list实现分布式延时队列
zset:存储时间戳,时间戳有序递增
list:触发消息和目标消息体、规则id、触发消息匹配键值(订单id)、
拆分时间戳和消息体,避免Redis zset大Value问题
zset
score 1588305600 1588305601 1588305603 1588305605
member 1588305600 1588305601 1588305603 1588305605
list2
data1 data2 data3
data2 data3 …
list1
data1
…
18. 分布式延时队列-整体执行过程
规则执行服务读取延时消息
规则执行服务
消息订阅服务存储延时消息
订单
根据规则延时时间
计算时间戳
zadd时间戳
lpush消息体
消息生成时间 +规则延时时间 Redis Lua脚本保证事务操作
延时队列
规则执行服务
规则执行服务
执行服务获取无状态设计
19. 分布式延时队列-读取过程
如何保证执行服务负载均衡和不重复获取时间戳
实现思路:中心时钟设计、Redis Lua脚本、Redis单线程
调用zset zrange获取第一个元素
规则执行服务
规则执行服务
规则执行服务
T1
Lua命令获取消息
T2
Lua命令获取消息
T3
score 1588305600 1588305601 1588305603
member 1588305600 1588305601 1588305603
list2
Redis
Lua命令获取消息
基于Redis Lua脚本获取时间戳
1. 判断zset中首元素是否大于Redis系统时间
2. 根据时间戳获取对应的member
3. 删除zset中首元素
智能调速策略尽最大可能平衡执行机器负载
zset
data1
list1
data1
…
…
20. BCP整体架构-规则执行服务
规则执行服务主要包含2个模块:数据组装、规则执行引擎
延时触发队列
1.触发校验
Aviator规则引擎
Java规则引擎
触发消息数据
read
目标消息数据
组装
1.启动编译加载所有规则
DB
数据组装
规则执行引擎
21. 规则执行服务-数据组装
延时触发队列
轮询从延时队列中获取待校验消息
1.触发校验
触发消息数据
根据消息中的匹配键获取触发和目标消息
read
根据消息中的规则id获取规则脚本交由执行引擎执行
目标消息数据
组装
22. 规则执行服务-执行引擎
BCP管理平台
2.修改规则脚本
动态编译
动态编译规则脚本:Aviator、Java
校验不一致数据实时告警
Aviator规则引擎
核对不一致告警
Java规则引擎
1.启动编译加载所有规则
DB
23. 规则执行引擎-Aviator
Aviator是一门高性能、轻量级寄宿于 JVM 之上的脚本语言。适用核对场景:
1. 触发消息和目标消息是否同时存在
2. 比较触发消息和目标消息的字段值的关系:是否相等,是否包含某些特定的字符串
triggerMsg.id.newValue == targetMsg.id.newValue &&
triggerMsg.column1.newValue == targetMsg.column2.newValue
24. 规则执行引擎-Java
适用于复杂定制化的核对逻辑
filter
check
alarm
泛化调用
泛化调用
自动修复
金融
外卖
到店
业务服务
25. Java规则执行引擎-常用中间件sdk
触发和目标消息本身不足以完成校验,某些核对规则需要RPC调用或者访问第三方存储,核对结果希望通过MQ通知下游
RPC调用
金融
KV Client
到店
缓存常用组件实例,提供熔断、限流
等功能保护第三方服务或者/存储
DB Client
外卖
ES Client
优选
MQ Client
常用中间件sdk
业务服务/存储
26. BCP技术设计
整体架构
稳定性保
障设计
执行服务无状态、水平扩容
订阅服务有状态、高性能、高可用、负
载均衡设计
27. 服务高性能设计
生产消费者模型,生产Binlog或者消费Binlog过慢都会导致消息出现延时,一旦超过规则延时时间就会导致规则误告。
TTL 分钟小时级别
DB
解析Binlog
生产Binlog
解析Binlog过程
阻塞队列
消费Binlog
将Binlog写入缓存过程
写入缓存
Redis
TTL 天级别
Tair
28. 生产Binlog-串行Dump性能瓶颈
常规的Binlog Dump过程采用单线程拉取解析Binlog,吞吐量低
伪装成Mysql slave,拉取Binlog
DB
Dump
Binlog
网络接收
Binlog Event
基本解析
解析事件类型、表名、位点信息
该过程微秒级别
Binlog Event
字段深度解析
解析变更前后具体字段的值
该过程毫秒级别
29. 生产Binlog-局部并行化
单线程拉取解析Binlog,Event字段解析慢导致瓶颈?
Event深度解析并行化处理
如何保证最终有序性?
耗时部分引入RingBuffer
局部并行解析
Binlog 1
DB
Binlog Event基本
解析
网络接收
Binlog 2
网络接收
Binlog n
网络接收
根据表名过滤
Binlog Event基本
解析
Binlog Event基本
解析
Binlog Event字段
解析
根据表名过滤
Binlog Event字段
解析
根据表名过滤
网络接收和基本解析串行提交到RingBuffer
提前过滤不需要的表
避免浪费cpu
Binlog Event字段
解析
阻塞队列
30. 服务高性能设计-消费Binlog
消费Binlog过程主要是从阻塞队列中获取将解析好的Binlog及时写入Redis缓存
优化点:基于业务主键hash多线程处理、非阻塞方式批量提交
Binlog queue1
Binlog队列
订单id
hash取模
线程1处理
每间隔一段时
间批量写入
TTL 分钟小时级别
Redis
TTL 天级别
Binlog queue2
线程2处理
Tair
31. 服务高性能设计-减少网络IO次数
基于Redis HashTag(类似Kafka Partition) Redis key: {订单id}+key_suffix,Redis保证相同id的订单写入同一Redis节点
订单
支付
订阅Binlog
订阅Binlog
消息订阅服务
消息订阅服务
分片1 Redis
master1 Redis
slave1
分片2 Redis
master2 Redis
slave2
匹配键:订单id
规则执行服务
只需从分片2获取订单和支付消息
匹配键:订单id
分片3
Redis
master3
Redis
slave3
32. 服务高可用设计-订阅服务宕机问题
订阅支付库的订阅机器宕机,无法拉取Binlog写入缓存,造成组装模块组装失败,最终由于缺失支付Binlog导致告警
延时消息
订单
订阅Binlog
消息订阅服务
延时队列
匹配键:订单id
订单Binlog
60后触发组装
订单Binlog
支付
订阅Binlog
消息订阅服务
支付Binlog
匹配键:订单id
组装
缓存
支付Binlog
执行
规则
数据不
完整告警
33. 消息订阅服务高可用设计-宕机切换
高可用设计思路:主从架构的方案保证消息处理的 不重、不漏、低延时
从订阅机器
主订阅机器
主从切换
DB
主订阅机器
缓存
DB
从订阅机器
异步上传Gtid消费位点和心跳信息 Ha服务发现主宕机,同步
消费位点给从机器
Ha服务 Ha服务
主定时上报消费的位点信息,切换时候从拉取主消费的位点信息开始订阅,保证不漏
主从之前基于zk选主,同时订阅Binlog基于Gtid位点订阅,保证切换低延时
跟MQ类似,发生位点信息交互时很难保证主宕机前把所有位点上报完成,因此从消费时会重复消费一部分Binlog,如何保证不重?
缓存
34. 消息订阅服务消费过程幂等设计
基于Redis Lua脚本实现CAS操作,保证永远只会写入Gtid较大的Binlog:
Redis Key:订单Id
Redis Value:40位Gtid+toByte(Binlog本身)
N
从Redis中获取订单Id
Value前40位
写入Value
是否存在
Y
Y
待写入
Gtid是否
大于前40
位
N
写入Value
忽略该条Binlog
35. 消息订阅服务负载动态均衡设计
如何解决DB流量突增导致的机器负载飙高,避免单机性能瓶颈问题
36. 目录
01 背景介绍
02 技术设计
03 最佳实践
04 未来规划
CONTENTS
目
录
37. 最佳实践-数据一致性校验
触发消息和目标消息订阅不同的表,使用Aviator表达式判断字段值是否一致
38. 最佳实践-数据时效性校验
触发和目标消息订阅相同的表,校验zcm_acquirer_register表的任务任务状态500s后是否能从1变成7或者10
39. 最佳实践-数据自动订正
覆写BCP的alarm方法,收到告警后调用业务提供数据二次复核接口,确认数据有误进行自动订正
40. 目录
01 背景介绍
02 技术设计
03 最佳实践
04 未来规划
CONTENTS
目
录
41. 未来规划
新的CDC
数据源接入 离线核
对支持
ES增量变更接入
Blade(Tidb)增量变更接入 支持文件核对
T+D,T+H核对
42. 基础架构 - Java技术专家/资深工程师
岗位职责
1. 负责美团分布式配置系统、稳定性保障组件、混沌工程、应用
容器、业务正确性校验、分布式事务等中间件产品设计与研发工
作,不断提升服务稳定性和完善系统功能,满足业务多样化的应
用场景。
2. 参与混沌工程领域和稳定性保障能力前沿技术的调研选型,并
在项目中落地与推广。
3. 负责设计开发高效的自动化运维平台,提升运维效率;应对突
发场景,能够快速发现问题、定位问题和解决问题。
招聘:基础架构 - Java技术专家/资深工程师
邮箱:yeming@meituan.com
更多技术干货
欢迎关注“美团技术团队”
43.