BenchmarkSQL 支持 TiDB 驱动以及 tidb-loadbalance

作者: GangShen 原文来源: https://tidb.net/blog/3c274180

使用 BenchmarkSQL 对 TiDB 进行 TPC-C 测试

   众所周知 TiDB 是一个兼容 MySQL 协议的分布式关系型数据库,用户可以使用 MySQL 的驱动以及连接方式连接 TiDB 进行使用,并且使用语法上与 MySQL 也没有差异。TPC-C 是一个对 OLTP(联机交易处理)系统进行测试的规范,模拟的是一个商品销售模型的场景,包括新订单生成、订单付款、最近订单查询、配送、库存缺货状态分析。PingCAP 在早期通过在开源的 BenchmarkSQL5.0 的基础上添加了对 MySQL 协议的支持,实现对 TiDB 进行 TPC-C 测试。具体可以参考 PingCAP 官方文档:https\://docs.pingcap.com/zh/tidb/v3.0/benchmark-tidb-using-tpcc

TiDB-JDBC 以及 tidb-loadbalance 介绍

   由于早期版本 TiDB 计算节点并不支持负载均衡,所以 TiDB 集群需要配合 HAProxy、LVS 或者 F5 等负载均衡使用,将应用连接分发到不同的计算节点上。TiDB 官方在 6.1 版本之后针对 Java 程序推出了 TiDB 自己的驱动 TiDB-JDBC和 Java 客户端负载均衡 tidb-loadbalance:
  • TiDB-JDBC **是基于 MySQL 8.0.29 的定制版本。TiDB-JDBC 基于 MySQL 官方 8.0.29 版本编译,修复了原 JDBC 在 prepare 模式下多参数、多字段 EOF 的错误,并新增 TiCDC snapshot 自动维护和 SM3 认证插件等功能。
  • tidb-loadbalance 是应用端的负载均衡组件。通过 tidb-loadbalance,你可以实现自动维护 TiDB server 的节点信息,根据节点信息使用 tidb-loadbalance 策略在客户端分发 JDBC 连接。客户端应用与 TiDB server 之间使用 JDBC 直连,性能高于使用负载均衡组件。目前 tidb-loadbalance 已实现轮询、随机、权重等负载均衡策略。

适配 BenchmarkSQL

   我们希望让 BenchmarkSQL 支持 TiDB-JDBC 驱动以及 tidb-loadbalance 应用端负载均衡,这样在对 TiDB 进行 TPC-C 测试时可以不用额外部署负载均衡软件来支持连接分发。先附上修改适配之后的 Github 仓库链接:https\://github.com/Win-Man/benchmarksql/tree/5.0-tidb-support本节将详细介绍如何通过修改 BenchmarkSQL 代码来支持 TiDB 驱动。

增加 TiDB 数据库类型定义

修改 src/client/jTPCC.java 文件,增加 TiDB 数据库定义:

        if (iDB.equals("firebird"))dbType = DB_FIREBIRD;else if (iDB.equals("oracle"))dbType = DB_ORACLE;else if (iDB.equals("postgres"))dbType = DB_POSTGRES;else if (iDB.equals("mysql"))dbType = DB_MYSQL;else if (iDB.equals("tidb"))dbType = DB_TIDB;else{log.error("unknown database type '" + iDB + "'");return;}

修改 src/client/jTPCCConfig.java 文件,增加 TiDB 数据库类型:

    public final static int     DB_UNKNOWN = 0,DB_FIREBIRD = 1,DB_ORACLE = 2,DB_POSTGRES = 3,DB_MYSQL = 4,DB_TIDB = 5;

SQL 子查询增加别名

修改 src/client/jTPCCConnection.java 在 SQL 子查询中增加 AS L 别名,否则会出现语法错误。

            default:stmtStockLevelSelectLow = dbConn.prepareStatement("SELECT count(*) AS low_stock FROM (" +"    SELECT s_w_id, s_i_id, s_quantity " +"        FROM bmsql_stock " +"        WHERE s_w_id = ? AND s_quantity < ? AND s_i_id IN (" +"            SELECT ol_i_id " +"                FROM bmsql_district " +"                JOIN bmsql_order_line ON ol_w_id = d_w_id " +"                 AND ol_d_id = d_id " +"                 AND ol_o_id >= d_next_o_id - 20 " +"                 AND ol_o_id < d_next_o_id " +"                WHERE d_w_id = ? AND d_id = ? " +"        ) " +"    )AS L");break;

修改测试运行脚本

修改 run/funcs.sh 文件,添加 TiDB 驱动拷贝操作

function setCP()
{case "$(getProp db)" infirebird)cp="../lib/firebird/*:../lib/*";;oracle)cp="../lib/oracle/*"if [ ! -z "${ORACLE_HOME}" -a -d ${ORACLE_HOME}/lib ] ; thencp="${cp}:${ORACLE_HOME}/lib/*"ficp="${cp}:../lib/*";;postgres)cp="../lib/postgres/*:../lib/*";;mysql)cp="../lib/mysql/*:../lib/*";;tidb)cp="../lib/tidb/*:../lib/*";;esacmyCP=".:${cp}:../dist/*"export myCP
}# ----
# Make sure that the properties file does have db= and the value
# is a database, we support.
# ----
case "$(getProp db)" infirebird|oracle|postgres|mysql|tidb);;"")        echo "ERROR: missing db= config option in ${PROPS}" >&2exit 1;;*)        echo "ERROR: unsupported database type 'db=$(getProp db)' in ${PROPS}" >&2exit 1;;
esac

新增 TiDB 配置文件模板 props.tidb

新增 run/props.tidb 配置文件:

db=tidb
driver=com.tidb.jdbc.Driver
conn=jdbc:tidb://127.0.0.1:4000/tpcc?useSSL=false&useServerPrepStmts=true&useConfigs=maxPerformance&rewriteBatchedStatements=true&cachePrepStmts=true&prepStmtCacheSize=1000&prepStmtCacheSqlLimit=2048
user=root
password=warehouses=1
loadWorkers=4terminals=1
//To run specified transactions per terminal- runMins must equal zero
runTxnsPerTerminal=0
//To run for specified minutes- runTxnsPerTerminal must equal zero
runMins=10
//Number of total transactions per minute
limitTxnsPerMin=0//Set to true to run in 4.x compatible mode. Set to false to use the
//entire configured database evenly.
terminalWarehouseFixed=true//The following five values must add up to 100
//The default percentages of 45, 43, 4, 4 & 4 match the TPC-C spec
newOrderWeight=45
paymentWeight=43
orderStatusWeight=4
deliveryWeight=4
stockLevelWeight=4// Directory name to create for collecting detailed result data.
// Comment this out to suppress.
resultDirectory=my_result_%tY-%tm-%td_%tH%tM%tS
//osCollectorScript=./misc/os_collector_linux.py
//osCollectorInterval=1
//osCollectorSSHAddr=user@dbhost
//osCollectorDevices=net_eth0 blk_sda

添加 TiDB-JDBC 驱动以及 tidb-loadbalance jar 包

新建 lib/tidb 目录并放入 jar 包

测试使用

  1. 下载测试程序
git clone -b 5.0-tidb-support https://github.com/Win-Man/benchmarksql.git
  1. 安装 java 和 ant,以 CentOS 为例,可以执行以下命令进行安装
sudo yum install -y java ant
  1. 进入 benchmarksql 目录并执行 ant 构建
cd benchmarksql
ant
  1. 修改 benchmarksql/run/props.tidb 文件
conn=jdbc:mysql://{TiDB-IP}:{TiDB-PORT}/tpcc?useSSL=false&useServerPrepStmts=true&useConfigs=maxPerformance
warehouses=1000 # 使用 1000 个 warehouse
terminals=500   # 使用 500 个终端
loadWorkers=32  # 导入数据的并发数

{TiDB-IP}:{TiDB-PORT} 只需要填 TiDB 集群任意一个 TiDB Server 计算节点的 IP 地址与端口就可以,程序启动之后 tidb-loadbalance 会自动发现集群内部所有的计算节点并进行连接的分发。

  1. 在 TiDB 中创建 TPCC 测试库
create database tpcc;
  1. 运行 BenchmarkSQL 建表脚本并导入数据:
cd run && \
./runSQL.sh props.tidb sql.mysql/tableCreates.sql && \
./runSQL.sh props.tidb sql.mysql/indexCreates.sql
./runLoader.sh props.tidb
  1. 运行测试
./runBenchmark.sh props.tidb

TPCC测试对于分布式数据库测试的意义

   分布式数据库在近两年的热度一直非常高,由于 OceanBase 以及腾讯的 TPCC 打榜:
  • 世界第一!腾讯云数据库 TDSQL 登顶 TPC-C 榜,刷新全球纪录

  • OceanBase 登顶 TPC-C:无关比赛,只是在追求自我的极致

     很多人在数据库选型的时候会关注 TPCC 的测试结果,所以也有很多数据库厂商会在 TPCC 测试上进行专门的优化以此来提升在 POC 节点的测试成绩。但是往往有很多客户在做了数据库选型之后,将数据库产品应用于真实业务场景时发现,一些在 POC 时 TPCC 测试成绩优异的产品,对于真实业务的性能提升非常有限,甚至有些还不如没做分布式改造之前的性能。所以在做数据库选型测试,我们规划测试案例的时候,我们需要非常清楚我们设计的测试案例所要测试的目的以及测试案例设计的是否合理。完整的数据库选型如何设计这是一个非常大的题目,我这边不做展开讲述,但是在客户选择使用 TPCC 作为数据库选型中的性能指标这一点上,我有一些自己的想法。首先我们先了解 TPCC 这个测试的业务场景,这是一个典型的商品销售模型的场景,包括新订单生成、订单付款、最近订单查询、配送、库存缺货状态分析。交易的业务逻辑主要有:
    
  1. 仓库(Warehouse),有很多的仓库,每个仓库有很多的商品(Item),每个商品在每个仓库有自己的库存数目。仓的数目很多,比如一般测试都是1000仓起步(这个与一些电商平台是不一样的,例如淘宝,核心单元可能就个位数)。

  2. 买家(Customer),绝大多数情况下,买家只会从绑定的一个仓库买东西;少数情况下,买家才会从其他仓库买东西

    基于这样的业务特征,很容易想到将数据库按照仓库 ID 进行分片,大多数的事务可以在单个分片内完成。对仓库 ID 进行分片这个第一反应就是很适合分库分表的分布式数据库解决方案。对数据进行分片之后,事务都在单个分片内执行,也就是在分库分表方案底下的单个数据库实例中实现,通过增加分片数量就可以很好的扩展整体的 TPCC 测试性能,从这个逻辑上 TPCC 体现的是单个数据库实例的性能,并不是一个分布式数据库整体的分布式能力。合理的设计分片字段后,只有少量的跨节点分布式事务,这对于分布式数据库的选型其实绕过了重要的分布式事务性能测试的点。而很多 TPC-C 测试性能优异但是真实业务场景性能平平的原因,原因在于 TPCC 的测试模型相对简单,真实世界是非常复杂的,真实的业务场景也不一定能够完美的设计分片键将所有的数据库按照分片规则去分布,在单个数据库实例内部完成事务。一旦涉及到跨节点的分布式事务,分库分表的分布式解决方案在性能上会大幅下降,因为基于分库分表的方案底层还是 MySQL 或者 PostgreSQL ,这些数据库不是原生的分布式数据库,要实现分布式事务需要通过 XA 事务接口或者其他方式实现,其性能不如原生的分布式数据库。并且原生分布式数据库从架构设计上就是为分布式考虑的,所以在分布式事务优化方面有更大的空间以及灵活度。总结来说,TPCC 的性能测试仅建议做参考不建议作为选型依据,如果是希望数据库选型的性能测试,建议使用真实业务场景进行测试更为准确靠谱。可以通过 JMeter 压测业务接口模拟不同的业务压力。
    

其他可参考文档

  • tidb-loadbalance 客户端方式软负载均衡配置实践
  • 选择驱动或 ORM 框架
  • PolarDB-X 数据分布解读(三) :TPCC与透明分布式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/26845.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git从远程仓库中删除文件,并上传新文件

目录 删除&#xff1a; 拉取远程分支的更新&#xff1a; ​编辑 首先查看git状态&#xff1a; ​编辑 删除文件并提交版本库&#xff1a; 提交&#xff1a; 上传新文件&#xff1a; 首先查看git状态&#xff1a; 提交到暂存区&#xff1a; 提交到版本库&#xff1a; 上…

基于Spring Boot的在线视频教育培训网站设计与实现(Java+spring boot+MySQL)

获取源码或者论文请私信博主 演示视频&#xff1a; 基于Spring Boot的在线视频教育培训网站设计与实现&#xff08;Javaspring bootMySQL&#xff09; 使用技术&#xff1a; 前端&#xff1a;html css javascript jQuery ajax thymeleaf 微信小程序 后端&#xff1a;Java sp…

Python插件PyAutoGui的使用方法

Python插件PyAutoGui的使用方法 一、控制鼠标二、图片处理三、控制键盘四、其他方法 一、控制鼠标 pyautogui.moveTo(w - 100, h - 100, duration0.25) # 立即移动到指定x&#xff0c; y位置坐标&#xff0c; duration表示移动花费的时间,0表示立即 pyautogui.moveRel(100, 0…

skywalking日志收集

文章目录 一、介绍二、添加依赖三、修改日志配置1. 添加链路表示traceId2. 添加链路上下文3. 异步日志 四、收集链路日志 一、介绍 在上一篇文章skywalking全链路追踪中我们介绍了在微服务项目中使用skywalking进行服务调用链路的追踪。 本文在全链路追踪的基础上&#xff0c…

没有fastjson,rust怎么方便的解析提取复杂json呢?

在 Rust 中解析和提取复杂的 JSON 结构&#xff0c;你可以使用 serde_json 库来处理。 serde_json 提供了一组功能强大的方法来解析和操作 JSON 数据。 下面是一个示例&#xff0c;展示了如何解析和提取复杂的 JSON 结构&#xff1a; use serde_json::{Value, Result}; fn mai…

gradle项目Connection timed out,build时先下载gradle问题download gradle-x.x-bin.zip

IDEA 导入 Gradle 项目&#xff0c;编译的时候会默认下载 配置版本的Gradle.zip问题&#xff0c;一般会下载失败&#xff0c;提示Connection timed out&#xff0c;连接超时。 解决办法&#xff1a; 修改项目根目录下gradle目录下的gradle-wrapper.properties文件&#xff0c;…

探索 Go 语言中 iota 的神奇力量,优雅定义常量!

大家好&#xff01;在今天的文章中&#xff0c;我将为大家介绍一下关于 golang 中的 iota 的使用技巧和注意事项。作为一种枚举常量生成器&#xff0c;iota 在 golang 中被广泛使用&#xff0c;可以简化代码和提高可读性。下面就让我们来了解一些关键的使用技巧和注意事项吧&am…

前端开发中如何进行多主题配置

在前端开发中实现多主题配置可以让用户根据个人喜好或者场景需求选择不同的界面风格&#xff01; 下面来为大家一一介绍实现切换主题配置的方法&#xff01; 1、CSS 变量 使用CSS变量来定义主题相关的颜色、字体、间距等属性&#xff0c;然后在不同主题下修改这些变量的值。…

【操作系统】进程和线程对照解释

进程&#xff08;Process&#xff09;和线程&#xff08;Thread&#xff09;都是操作系统中用于执行任务的基本单位&#xff0c;但它们有着不同的特点和使用方式。 进程&#xff08;Process&#xff09;&#xff1a; 进程是正在运行的程序的实例。一个程序在运行时会被操作系统…

LLM as Co-pilot:AutoDev 1.0 发布,开源全流程 AI 辅助编程

四月&#xff0c;在那篇《AutoDev&#xff1a;AI 突破研发效能&#xff0c;探索平台工程新机遇》&#xff0c;我们初步拟定了 AI 对于研发的影响。我们有了几个基本的假设&#xff1a; 中大型企业将至少拥有一个私有化的大语言模型。只有构建端到端工具才能借助 AI 实现增质提效…

STM32入门——定时器

内容为江科大STM32标准库学习记录 TIM简介 TIM&#xff08;Timer&#xff09;定时器定时器可以对输入的时钟进行计数&#xff0c;并在计数值达到设定值时触发中断16位计数器、预分频器、自动重装寄存器的时基单元&#xff0c;在72MHz计数时钟下可以实现最大59.65s的定时&…

React、Vue和Angular的优缺点

React React 是一个用于构建用户界面的 JAVASCRIPT 库。React 主要用于构建 UI&#xff0c;很多人认为 React 是 MVC 中的 V&#xff08;视图&#xff09;。React 起源于 Facebook 的内部项目&#xff0c;用来架设 Instagram 的网站&#xff0c;并于 2013 年 5 月开源。React …

Unity3D GPU Selector/Picker

Unity3D GPU Selector/Picker 一、概述 1.动机 Unity3D中通常情况下使用物理系统进行物体点击选择的基础&#xff0c;对于含大量对象的场景&#xff0c;添加Collider组件会增加内容占用&#xff0c;因此使用基于GPU的点击选择方案 2.实现思路 对于场景的每个物体&#xff0c;…

批量导出pdf为zip文件(可以修改zip中pdf名称)

核心代码 public static void compressZip1(HashMap<String,File> map, String rootPath, String zipFileName) throws FileNotFoundException {FileOutputStream fileOutputStream new FileOutputStream(zipFileName);ZipOutputStream zipOutputStream new ZipOutputS…

Java超级玛丽小游戏制作过程讲解 第四天 创建并完成常量类03

今天继续来完成常量类。 package com.sxt;import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List;public class StaticValue {//背景public static Buff…

【Docker】性能测试监控平台搭建:InfluxDB+Grafana+Jmeter+cAdvisor

前言 在做性能测试时&#xff0c;如果有一个性能测试结果实时展示的页面&#xff0c;可以极大的提高我们对系统性能表现的掌握程度&#xff0c;进而提高我们的测试效率。但是我们每次打开Jmeter都会有几个硕大的字提示别用GUI模式进行负载测试&#xff0c;而且它自带的监视器效…

系统架构设计师-软件架构设计(7)

目录 大型网站系统架构演化 一、第一阶段&#xff1a;单体架构 到 第二阶段&#xff1a;垂直架构 二、第三阶段&#xff1a;使用缓存改善网站性能 1、缓存与数据库的数据一致性问题 2、缓存技术对比【MemCache与Redis】 3、Redis分布式存储方案 4、Redis集群切片的常见方式 …

FFmpeg中相关结构体介绍

AVFormatContext&#xff1a;此结构体存储音视频封装格式中包含的信息&#xff0c;并且这个结构体是贯穿整个播放流程的。在这个结构体中主要包含AVInputFormat&#xff0c;AVOutputFormat、AVStream等。 struct AVInputFormat *iformat; // 输入数据的封装格式 AVIOContext *…

PostGIS v3.4.0Orc1版本特性

PostGIS 3.4.0rc1 2023/08/05自 3.4.0beta2 发布以来的变化- &#xff03;5442&#xff0c;[postgis_tiger_geocoder&#xff0c;postgis_topology]数据库search_path不做它打算做什么&#xff08;Jelte Fennema&#xff09;PostGIS 3.4.0beta2 2023/07/29自 3.4.0beta1 发布以…

解决log4j.xml的url没有注册问题

在对log4j.xml配置文件配置时出现http//jakarta.apache.org/log4j/爆红&#xff0c;IDEA提示uri is not registered。源代码如下 <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j"http://jakarta.apache.org/lo…