作者介绍
侯阳
SphereEx 中间件研发工程师,Apache ShardingSphere Contributor。
目前专一于 ShadowDB 及全链路压测相干的设计和研发。
什么是全链路压测
随着互联网行业的疾速倒退,业务也进入了疾速扩张阶段,多变的用户需要对整个零碎的稳定性冲击可想而知。比方外卖平台大量用户产生的订单集中散布在中午和黄昏两个时间段,再比方电商平台的购物节、秒杀流动等。
每种业务都由一系列不同的业务零碎来提供服务,每个业务零碎都分布式地部署在不同的机器上。“流量布局” 既能保障系统稳定性、又能节约老本对于技术团队来说是一重大难题,为了精准地获取到单台机器的服务能力,压力测试要在生产环境进行。既能保障环境的真实性,也能保障流量的真实性,大大提高“流量布局”的准确性。
影子库与全链路压测
但在线上业务零碎做压测,危险显而易见,比方数据净化问题或是性能问题。试想一下,如果压测完结后用户发现自己订单失落了或是凭空多出一批待领取的订单,是否极大影响用户体验?
全链路在线压测是一项简单而宏大的工作,须要各个微服务、中间件之间配合实现。Apache ShardingSphere 关注于全链路在线压测场景下数据库层面的解决方案,推出压测影子库性能。借助于 ShardingSphere 弱小的 SQL 解析能力,对执行 SQL 进行影子断定,同时联合影子算法灵便的配置,满足简单业务场景的在线压测需要;压测流量路由到影子库,线上失常流量路由到生产库,从而帮忙用户对压测数据进行隔离,解决数据净化问题。
影子库性能降级
影子库性能最早实现于 v4.1.0 期间,通过增加一个逻辑的影子列,Apache ShardingSphere 通过解析执行 SQL,对其进行路由并改写,删除逻辑的影子列与列值。用户无需关注具体过程,应用时仅对 SQL 进行相应革新,增加影子字段与相应的配置即可。
增加影子列的形式有两个痛点:
- 用户在进行压力测试前须要依据理论的业务需要,对压测相干 SQL 进行相应革新。
- SQL 改写操作会减少执行损毁,升高压测后果的准确性。
通过 ShardingSphere 社区的探讨,决定对影子库性能进行重构。
Apache ShardingSphere 4.1.1 GA 版影子库 API,总体上性能较为简单,依据逻辑列对应的值判断是否开启影子库。
rules:- !SHADOW column: # 影子字段名称名称 shadowMappings: ds: shadow_ds # 生产数据源名称列表:影子数据库名称列表
5.0.0 GA 重构当前的影子库 API 更加弱小。 用户能够通过 enable
属性管制是否开启影子库性能,可配置影子表能够依照表的维度管制须要进行压测的范畴,并反对多种不同的影子算法,例如:列值匹配算法、列正则表达式匹配算法以及 SQL 正文匹配算法。
rules:- !SHADOW enable: true # 影子库开关。 可选值:true/false,默认为false dataSources: shadowDataSource: sourceDataSourceName: ds # 生产数据源名称 shadowDataSourceName: shadow_ds # 影子数据源名称 tables: <shadow-table-name>: dataSourceNames: shadowDataSource # 影子表关联影子数据源名称列表(多个值用","隔开) shadowAlgorithmNames: - <shadow-algorithm-name> # 影子表关联影子算法名称列表 shadowAlgorithms: <shadow-algorithm-name>: type: # 影子算法类型 props: xxx: xxx # 影子算法属性配置
影子库实战
在线全链路压测架构图:
筹备压测环境
假如一个电商网站要对下单业务进行在线压测。(演示应用单机部署形式)
假如压测相干表 t_order
订单表,测试用户的 ID 为 0。测试用户下单产生的数据执行到 ds_shadow
影子库,生产数据执行到 ds 生产数据库。
测试环境筹备:
- 下载 ShardingSphere-Proxy 5.0.0 GA Download Page,装置配置详情参考ShardingSphere-Proxy-Quick-Start
- 配置 ShardingSphere-Proxy 以上文假如压测场景为例:
server.yaml
rules: - !AUTHORITY users: - root@%:root - sharding@:sharding provider: type: NATIVE - !TRANSACTION defaultType: XA providerType: Atomikosprops: max-connections-size-per-query: 1 executor-size: 16 # Infinite by default. proxy-frontend-flush-threshold: 128 # The default value is 128. proxy-opentracing-enabled: false proxy-hint-enabled: false sql-show: true check-table-metadata-enabled: false lock-wait-timeout-milliseconds: 50000 # The maximum time to wait for a lock show-process-list-enabled: false # Proxy backend query fetch size. A larger value may increase the memory usage of ShardingSphere Proxy. # The default value is -1, which means set the minimum value for different JDBC drivers. proxy-backend-query-fetch-size: -1 check-duplicate-table-enabled: false sql-comment-parse-enabled: true proxy-frontend-executor-size: 0 # Proxy frontend executor size. The default value is 0, which means let Netty decide. # Available options of proxy backend executor suitable: OLAP(default), OLTP. The OLTP option may reduce time cost of writing packets to client, but it may increase the latency of SQL execution # if client connections are more than proxy-frontend-netty-executor-size, especially executing slow SQL. proxy-backend-executor-suitable: OLAP
config-shadow.yaml
schemaName: shadow_poc_databasedataSources: ds: url: jdbc:mysql://127.0.0.1:3306/ds?serverTimezone=UTC&useSSL=false username: root password: connectionTimeoutMilliseconds: 30000 idleTimeoutMilliseconds: 60000 maxLifetimeMilliseconds: 1800000 maxPoolSize: 50 minPoolSize: 1 ds_shadow: url: jdbc:mysql://127.0.0.1:3306/ds_shadow?serverTimezone=UTC&useSSL=false username: root password: connectionTimeoutMilliseconds: 30000 idleTimeoutMilliseconds: 60000 maxLifetimeMilliseconds: 1800000 maxPoolSize: 50 minPoolSize: 1rules:- !SHADOW enable: true dataSources: shadowDataSource: sourceDataSourceName: ds shadowDataSourceName: ds_shadow tables: t_order: dataSourceNames: - shadowDataSource shadowAlgorithmNames: - user-id-insert-match-algorithm - simple-note-algorithm shadowAlgorithms: user-id-insert-match-algorithm: type: COLUMN_REGEX_MATCH props: operation: insert column: user_id regex: "[0]" simple-note-algorithm: type: SIMPLE_NOTE props: foo: bar
- 订单服务
这里不探讨订单相干业务,以最简略的收申请直接插入订单表为例。订单表构造如下:
- 订单表构造
CREATE TABLE `t_order` ( `id` INT(11) AUTO_INCREMENT COMMENT '订单ID', `user_id` VARCHAR(32) NOT NULL COMMENT '下单用户ID', `sku` VARCHAR(32) NOT NULL COMMENT '订单商品sku', PRIMARY KEY (`id`))ENGINE = InnoDB COMMENT = '订单表';
模仿压测过程
- 应用
postman
模仿测试用户创立订单申请如下图:
- ShardingSphere-Proxy 中执行日志能够看到 执行 SQL 被路由到影子库执行
验证压测后果
- 影子库
ds_shadow
执行查问语句
SELECT * FROM t_order;
查问后果:
- 生产库 ds 执行查问语句
SELECT * FROM t_order;
查问后果:
测试用户创立订单产生的数据会路由到影子库中。更多简单配置请参考 ShardingSphere 官网文档影子库压测。
全链路在线压测残缺解决方案-CyborgFlow
前文中也提到全链路在线压测是一项简单而宏大的工作,须要各个微服务、中间件之间配合与调整,以应答不同流量以及压测标识的透传,而且要做到测试服务无状态并且开箱即用。
由 Apache ShardingSphere 联结 Apache APISIX、Apache SkyWalking 独特保护的我的项目 CyborgFlow 提供开箱即用 (OOTB) 解决方案来在您的在线零碎上执行负载测试。
Apache APISIX 负责在网关层对测试数据进行标记,并由 Apache SkyWalking 负责在整个调用链路上进行传递,最初交由 Apache ShardingSphere-Proxy 做数据隔离,压测数据路由到影子库中。
我的项目已公布 0.1.0 版本,欢送下载应用:
https://github.com/SphereEx/CyborgFlow/releases
欢送增加社区经理微信(ss_assistant_1)退出微信交换群,与更多 ShardingSphere 爱好者一起交换探讨。