文章插图
上图是 Kubernetes 上线后双十一大促当天的发送 RT 统计,可见大促期间的发送 RT 较为平稳,整体符合预期,云原生化实践完成了关键性的里程碑 。
性能优化背景RocketMQ 至今已经连续七年 0 故障支持集团的双十一大促 。自从 RocketMQ 诞生以来,为了能够完全承载包括集团业务中台交易消息等核心链路在内的各类关键业务,复用了原有的上层协议逻辑,使得各类业务方完全无感知的切换到 RocketMQ 上,并同时充分享受了更为稳定和强大的 RocketMQ 消息中间件的各类特性 。
当前,申请订阅业务中台的核心交易消息的业务方一直都在不断持续增加,并且随着各类业务复杂度提升,业务方的消息订阅配置也变得更加复杂繁琐,从而使得交易集群的进行过滤的计算逻辑也变得更为复杂 。这些业务方部分沿用旧的协议逻辑(Header过滤),部分使用 RocketMQ 特有的 SQL 过滤 。
主要成本目前集团内部 RocketMQ 的大促机器成本绝大部分都是交易消息相关的集群,在双十一零点峰值期间,交易集群的峰值和交易峰值成正比,叠加每年新增的复杂订阅带来了额外 CPU 过滤计算逻辑,交易集群都是大促中机器成本增长最大的地方 。
优化过程由于历史原因,大部分的业务方主要还是使用Header过滤,内部实现其实是aviator表达式( https://github.com/killme2008/aviatorscript ) 。仔细观察交易消息集群的业务方过滤表达式,可以发现绝大部分都指定类似 MessageType == xxxx 这样的条件 。翻看aviator的源码可以发现这样的条件最终会调用JAVA的字符串比较 String.compareTo() 。
由于交易消息包括大量不同业务的MessageType,光是有记录的起码有几千个,随着交易业务流程复杂化,MessageType的增长更是繁多 。随着交易峰值的提高,交易消息峰值正比增长,叠加这部分更加复杂的过滤,持续增长的将来,交易集群的成本极可能和交易峰值指数增长,因此决心对这部分进行优化 。
原有的过滤流程如下,每个交易消息需要逐个匹配不同group的订阅关系表达式,如果符合表达式,则选取对应的group的机器进行投递 。如下图所示:
文章插图
对此流程进行优化的思路需要一定的灵感,在这里借助数据库索引的思路:原有流程可以把所有订阅方的过滤表达式看作数据库的记录,每次消息过滤就相当于一个带有特定条件的数据库查询,把所有匹配查询(消息)的记录(过滤表达式)选取出来作为结果 。为了加快查询结果,可以选择 MessageType 作为一个索引字段进行索引化,每次查询变为先匹配 MessageType 主索引,然后把匹配上主索引的记录再进行其它条件(如下图的 sellerId 和 testA )匹配,优化流程如下图所示:
文章插图
以上优化流程确定后,要关注的技术点有两个:
- 如何抽取每个表达式中的 MessageType 字段?
- 如何对 MessageType 字段进行索引化?
http://en.wikipedia.org/wiki/Recursive_descent_parser
同时需要考虑到提取后父表达式的短路问题 。
在编译过程中针对 messageType==XXX 这种类型进行提取后,把原有的 message==XXX 转变为 true/false 两种情况,然后针对 true、false 进行表达式的短路即可得出表达式优化提取后的情况 。例如:
表达式:messageType=='200-trade-paid-done' && buyerId==123456提取为两个子表达式:子表达式1(messageType==200-trade-paid-done):buyerId==123456 子表达式2(messageType!=200-trade-paid-done):false
具体到 aviator 的实现里,表达式编译会把每个 token 构建一个 List ,类似如下图所示(为方便理解,绿色方框的是 token ,其它框表示表达式的具体条件组合):文章插图
提取了 messageType ,有两种情况:
- 情况一:messageType == '200-trade-paid-done',则把之前 token 的位置合并成true,然后进行表达式短路计算,最后优化成 buyerId==123456 ,具体如下:
- 情况二:messageType != '200-trade-paid-done',则把之前 token 的位置合并成 false ,表达式短路计算后,最后优化成 false ,具体如下:
推荐阅读
- Zero-Copy 还不懂零拷贝?怎么称得上高级程序员
- 电脑常见问题与故障有哪些
- 图解Kubernetes故障排查指南
- 零距离感受台湾茶文化,广西六堡茶顺利出口马来西亚
- 遭遇勒索软件袭击,如何快速遏制病毒扩散,并找到“零号患者”?
- 从零开始入门K8S| 从Spring Cloud到Kubernetes的微服务迁移实践
- 零基础学会广域网远程启动家中电脑
- 汽车故障灯红色扳手怎么消除?
- 魔芋|春天减肥,这一盘要多吃,低脂零卡,饱腹不怕胖,做法简单还便宜
- 线上故障如何快速排查?来看这套技巧大全