ProxySQL 集成指南
本文简要介绍 ProxySQL,描述如何在开发环境和生产环境中将 ProxySQL 与 TiDB 集成,并通过查询规则的场景展示集成的主要优势。
关于 TiDB 和 ProxySQL 的更多信息,请参考以下文档:
什么是 ProxySQL?
ProxySQL 是一个高性能的开源 SQL 代理。它具有灵活的架构,可以通过多种方式部署,适合各类使用场景。例如,ProxySQL 可以通过缓存频繁访问的数据来提高性能。
ProxySQL 的设计目标是快速、高效且易于使用。它完全兼容 MySQL,并支持高质量 SQL 代理的所有功能。此外,ProxySQL 还提供了许多独特功能,使其成为各种应用程序的理想选择。
为什么集成 ProxySQL?
- ProxySQL 可以通过降低与 TiDB 交互的延迟来提升应用程序性能。无论你构建什么,无论是使用 Lambda 等无服务器函数的可扩展应用程序(其工作负载不确定并且可能激增),还是构建执行大量数据查询的应用程序,都可以利用 ProxySQL 的强大功能(例如连接池和缓存常用查询)。
- ProxySQL 可以作为应用程序安全防护的附加层,使用查询规则防止 SQL 漏洞(例如 SQL 注入)。
- 由于 ProxySQL 和 TiDB 都是开源项目,你可以享受到零供应商锁定的好处。
部署架构
将 ProxySQL 与 TiDB 集成的最直接方式是在应用层和 TiDB 之间添加 ProxySQL 作为独立中介。但是,这种方式无法保证可扩展性和容错性,而且可能因为网络跳转而增加延迟。为避免这些问题,一种替代部署架构是将 ProxySQL 作为附属容器部署,如下图所示:
开发环境
本节介绍如何在开发环境中将 TiDB 与 ProxySQL 集成。在满足前提条件的情况下,你可以根据 TiDB 集群类型选择以下选项之一开始集成 ProxySQL:
前提条件
根据选择的方案,你可能需要以下依赖:
你可以按照下面的说明进行安装:
- macOS
- CentOS
- Windows
下载并启动 Docker,其中 Docker Desktop 已包含 Docker Compose。
运行以下命令安装 Python 和
mysql-client
:/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" brew install python mysql-client
curl -fsSL https://get.docker.com | bash -s docker
yum install -y git python39 docker-ce docker-ce-cli containerd.io docker-compose-plugin mysql
systemctl start docker
下载并安装 Git。
从 Download for Windows 页面下载 64-bit Git for Windows Setup 安装程序。
按照安装向导提示安装 Git。你可以多次点击 Next 使用默认的安装设置。
下载并安装 MySQL Shell。
从 MySQL Community Server Download 页面下载 MySQL Installer 的 ZIP 文件。
解压文件,并在
bin
文件夹中找到mysql.exe
。你需要将该bin
文件夹的路径添加到系统变量中,并在 Git Bash 中将其设置到PATH
变量中。echo 'export PATH="(your bin folder)":$PATH' >>~/.bash_profile source ~/.bash_profile例如:
echo 'export PATH="/c/Program Files (x86)/mysql-8.0.31-winx64/bin":$PATH' >>~/.bash_profile source ~/.bash_profile
下载并安装 Docker。
从 Docker Download 页面下载 Docker Desktop 安装程序。
双击安装程序运行。安装完成后,会提示你重新启动。
从 Python Download 页面下载最新版的 Python 3 安装程序并运行。
选项 1: 集成 TiDB Cloud 与 ProxySQL
在这个集成中,你将使用 ProxySQL Docker 镜像以及 TiDB Cloud Serverless 集群。下面的步骤将在端口 16033
上设置 ProxySQL,请确保此端口可用。
步骤 1. 创建一个 TiDB Cloud Serverless 集群
参考创建一个 TiDB Cloud Serverless 集群文档。记住为集群设置的 root 密码。
获取集群的
hostname
、port
及username
供后续使用。- 在 Clusters 页面,点击你的集群名称,进入集群概览页面。
- 在集群概览页面的 Connection 面板中,复制
Endpoint
、Port
与User
字段,其中Endpoint
是集群的hostname
。
步骤 2. 生成 ProxySQL 配置文件
克隆 TiDB 和 ProxySQL 的集成示例代码仓库
tidb-proxysql-integration
:- macOS
- CentOS
- Windows (Git Bash)
git clone https://github.com/pingcap-inc/tidb-proxysql-integration.gitgit clone https://github.com/pingcap-inc/tidb-proxysql-integration.gitgit clone https://github.com/pingcap-inc/tidb-proxysql-integration.git进入
tidb-cloud-connect
目录:- macOS
- CentOS
- Windows (Git Bash)
cd tidb-proxysql-integration/example/tidb-cloud-connectcd tidb-proxysql-integration/example/tidb-cloud-connectcd tidb-proxysql-integration/example/tidb-cloud-connect运行
proxysql-config.py
生成 ProxySQL 配置文件:- macOS
- CentOS
- Windows (Git Bash)
python3 proxysql-config.pypython3 proxysql-config.pypython proxysql-config.py当出现提示时,输入集群的
Endpoint
作为Serverless Tier Host
,然后输入集群的Port
与User
。下面是一个输出示例。可以看到,在当前的
tidb-cloud-connect
目录下生成了三个配置文件。[Begin] generating configuration files.. tidb-cloud-connect.cnf generated successfully. proxysql-prepare.sql generated successfully. proxysql-connect.py generated successfully. [End] all files generated successfully and placed in the current folder.
步骤 3. 配置 ProxySQL
启动 Docker。如果 Docker 已经启动,请跳过此步骤:
- macOS
- CentOS
- Windows
双击已安装的 Docker 的图标来启动它。
systemctl start docker双击已安装的 Docker 的图标来启动它。
拉取 ProxySQL 镜像,并在后台启动一个 ProxySQL 容器:
- macOS
- CentOS
- Windows (Git Bash)
docker compose up -ddocker compose up -ddocker compose up -d运行以下命令集成 ProxySQL,该命令会在 ProxySQL Admin Interface 内执行
proxysql-prepare.sql
:- macOS
- CentOS
- Windows (Git Bash)
docker compose exec proxysql sh -c "mysql -uadmin -padmin -h127.0.0.1 -P6032 < ./proxysql-prepare.sql"docker compose exec proxysql sh -c "mysql -uadmin -padmin -h127.0.0.1 -P6032 < ./proxysql-prepare.sql"docker compose exec proxysql sh -c "mysql -uadmin -padmin -h127.0.0.1 -P6032 < ./proxysql-prepare.sql"下面是一个输出示例。输出中显示集群的主机名,这意味着 ProxySQL 和 TiDB Cloud Serverless 集群之间的连接建立成功。
*************************** 1. row *************************** hostgroup_id: 0 hostname: gateway01.us-west-2.prod.aws.tidbcloud.com port: 4000 gtid_port: 0 status: ONLINE weight: 1 compression: 0 max_connections: 1000 max_replication_lag: 0 use_ssl: 1 max_latency_ms: 0 comment:
步骤 4. 通过 ProxySQL 连接到 TiDB 集群
运行
proxysql-connect.py
连接到你的 TiDB 集群。该脚本将自动启动 MySQL 客户端并使用你在步骤 2 中指定的用户名和密码进行连接。- macOS
- CentOS
- Windows (Git Bash)
python3 proxysql-connect.pypython3 proxysql-connect.pypython proxysql-connect.py连接 TiDB 集群后,可以使用以下 SQL 语句验证连接:
SELECT VERSION();如果输出了 TiDB 的版本信息,则表示你已经成功通过 ProxySQL 连接到 TiDB Cloud Serverless 集群。如需退出 MySQL 客户端,输入
quit
并按下 Enter 键。要停止和删除容器,并返回上一个目录,运行以下命令:
- macOS
- CentOS
- Windows (Git Bash)
docker compose down cd -docker compose down cd -docker compose down cd -
选项 2: 集成本地部署的 TiDB 与 ProxySQL
在这个集成中,你将使用 TiDB 和 ProxySQL 的 Docker 镜像设置环境。你也可以尝试其他方式安装 TiDB。
下面的步骤将在端口 6033
和 4000
上分别设置 ProxySQL 和 TiDB,请确保这些端口可用。
启动 Docker。如果 Docker 已经启动,请跳过此步骤:
- macOS
- CentOS
- Windows
双击已安装的 Docker 的图标来启动它。
systemctl start docker双击已安装的 Docker 的图标来启动它。
克隆 TiDB 和 ProxySQL 的集成示例代码仓库
pingcap-inc/tidb-proxysql-integration
:- macOS
- CentOS
- Windows (Git Bash)
git clone https://github.com/pingcap-inc/tidb-proxysql-integration.gitgit clone https://github.com/pingcap-inc/tidb-proxysql-integration.gitgit clone https://github.com/pingcap-inc/tidb-proxysql-integration.git拉取 ProxySQL 和 TiDB 的最新镜像:
- macOS
- CentOS
- Windows (Git Bash)
cd tidb-proxysql-integration && docker compose pullcd tidb-proxysql-integration && docker compose pullcd tidb-proxysql-integration && docker compose pull使用 TiDB 和 ProxySQL 容器启动一个集成环境:
- macOS
- CentOS
- Windows (Git Bash)
docker compose up -ddocker compose up -ddocker compose up -d你可以使用
root
用户名及空密码登录到 ProxySQL 的6033
端口。通过 ProxySQL 连接到 TiDB:
- macOS
- CentOS
- Windows (Git Bash)
mysql -u root -h 127.0.0.1 -P 6033mysql -u root -h 127.0.0.1 -P 6033mysql -u root -h 127.0.0.1 -P 6033连接 TiDB 集群后,可以使用以下 SQL 语句验证连接:
SELECT VERSION();如果输出了 TiDB 的版本信息,则表示你已经成功通过 ProxySQL 连接到 TiDB 集群。
要停止和删除容器,并返回上一个目录,运行以下命令:
- macOS
- CentOS
- Windows (Git Bash)
docker compose down cd -docker compose down cd -docker compose down cd -
生产环境
对于生产环境,建议直接使用 TiDB Cloud Dedicated 以获得完全托管的体验。
前提条件
下载并安装一个 MySQL 客户端。例如,MySQL Shell。
基于 CentOS 集成 TiDB Cloud 与 ProxySQL
你可以在不同的平台上安装 ProxySQL,下面以 CentOS 为例进行说明。
关于 ProxySQL 支持的平台和版本要求的完整列表,见 ProxySQL 文档。
步骤 1. 创建一个 TiDB Cloud Dedicated 集群
具体步骤请参考创建一个 TiDB Cloud Dedicated 集群。
步骤 2. 安装 ProxySQL
将 ProxySQL 添加到 YUM 仓库:
cat > /etc/yum.repos.d/proxysql.repo << EOF [proxysql] name=ProxySQL YUM repository baseurl=https://repo.proxysql.com/ProxySQL/proxysql-2.4.x/centos/\$releasever gpgcheck=1 gpgkey=https://repo.proxysql.com/ProxySQL/proxysql-2.4.x/repo_pub_key EOF安装 ProxySQL:
yum install -y proxysql启动 ProxySQL:
systemctl start proxysql
要了解更多关于 ProxySQL 支持的平台及其安装方法,参考 ProxySQL README 或 ProxySQL 安装文档。
步骤 3. 配置 ProxySQL
为了使用 ProxySQL 作为 TiDB 的代理,你需要配置 ProxySQL。你可以在 ProxySQL Admin Interface 中执行 SQL 语句(推荐)或使用配置文件进行配置。
选项 1: 使用 Admin Interface 配置 ProxySQL
使用标准的 ProxySQL Admin Interface 更新 ProxySQL 的配置。你可以通过任何 MySQL 命令行客户端访问(默认端口为
6032
)。mysql -u admin -padmin -h 127.0.0.1 -P6032 --prompt 'ProxySQL Admin> '执行以上命令后,系统将显示
'ProxySQL Admin'
提示。你可以在当前 MySQL 命令行客户端中向 ProxySQL 添加一个或多个 TiDB 集群。例如,下面的语句将添加一个 TiDB Cloud Dedicated 集群。你需要用集群的
Endpoint
和Port
替换<tidb cloud dedicated cluster host>
和<tidb cloud dedicated cluster port>
(默认端口为4000
)。INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES ( 0, '<tidb cloud dedicated cluster host>', <tidb cloud dedicated cluster port> ); LOAD mysql servers TO runtime; SAVE mysql servers TO DISK;为配置 ProxySQL 的登录用户,你需要确保用户在 TiDB 集群上有适当的权限。在下面的语句中,你需要把
<tidb cloud dedicated cluster username>
和<tidb cloud dedicated cluster password>
替换为集群的实际用户名和密码。INSERT INTO mysql_users( username, password, active, default_hostgroup, transaction_persistent ) VALUES ( '<tidb cloud dedicated cluster username>', '<tidb cloud dedicated cluster password>', 1, 0, 1 ); LOAD mysql users TO runtime; SAVE mysql users TO DISK;
选项 2: 使用配置文件配置 ProxySQL
这个选项只能作为配置 ProxySQL 的备用方案。更多信息,可参考使用配置文件配置 ProxySQL。
删除现有的 SQLite 数据库,即 ProxySQL 存储配置的位置。
rm /var/lib/proxysql/proxysql.db根据你的需要修改配置文件
/etc/proxysql.cnf
。例如:mysql_servers: ( { address="<tidb cloud dedicated cluster host>" port=<tidb cloud dedicated cluster port> hostgroup=0 max_connections=2000 } ) mysql_users: ( { username = "<tidb cloud dedicated cluster username>" password = "<tidb cloud dedicated cluster password>" default_hostgroup = 0 max_connections = 1000 default_schema = "test" active = 1 transaction_persistent = 1 } )在上面的例子中:
address
和port
用于指定你的 TiDB Cloud 集群的Endpoint
和Port
。username
和password
用于指定你的 TiDB Cloud 集群的用户名和密码。
重启 ProxySQL:
systemctl restart proxysql重新启动后,ProxySQL 将自动创建 SQLite 数据库。
典型场景
本节以查询规则为例,介绍集成 TiDB 与 ProxySQL 能带来的一些优势。
查询规则
数据库可能会因为高流量、错误代码或恶意攻击而过载。因此,审核 SQL 是必要的。使用 ProxySQL 的查询规则,你可以有效地应对这些问题,例如通过重路由、改写 SQL 或者拒绝查询等方式。
克隆 TiDB 和 ProxySQL 的集成示例代码仓库
pingcap-inc/tidb-proxysql-integration
。如果你已经在前面的步骤中克隆了它,请跳过这一步。- macOS
- CentOS
- Windows (Git Bash)
git clone https://github.com/pingcap-inc/tidb-proxysql-integration.gitgit clone https://github.com/pingcap-inc/tidb-proxysql-integration.gitgit clone https://github.com/pingcap-inc/tidb-proxysql-integration.git进入 ProxySQL 查询规则的示例目录:
- macOS
- CentOS
- Windows (Git Bash)
cd tidb-proxysql-integration/example/proxy-rule-admin-interfacecd tidb-proxysql-integration/example/proxy-rule-admin-interfacecd tidb-proxysql-integration/example/proxy-rule-admin-interface运行下面的命令启动两个 TiDB 容器和一个 ProxySQL 容器:
- macOS
- CentOS
- Windows (Git Bash)
docker compose up -ddocker compose up -ddocker compose up -d如果运行成功,以下容器将被启动:
- 两个 Docker 容器的 TiDB 集群,端口分别为
4001
和4002
- 一个 Docker 容器的 ProxySQL,端口为
6034
在两个 TiDB 容器中,使用
mysql
创建一个具有相同 schema 的表,然后插入不同的数据 ('tidb-server01-port-4001'
,'tidb-server02-port-4002'
) 以区分这两个容器。- macOS
- CentOS
- Windows (Git Bash)
mysql -u root -h 127.0.0.1 -P 4001 << EOF DROP TABLE IF EXISTS test.tidb_server; CREATE TABLE test.tidb_server (server_name VARCHAR(255)); INSERT INTO test.tidb_server (server_name) VALUES ('tidb-server01-port-4001'); EOF mysql -u root -h 127.0.0.1 -P 4002 << EOF DROP TABLE IF EXISTS test.tidb_server; CREATE TABLE test.tidb_server (server_name VARCHAR(255)); INSERT INTO test.tidb_server (server_name) VALUES ('tidb-server02-port-4002'); EOFmysql -u root -h 127.0.0.1 -P 4001 << EOF DROP TABLE IF EXISTS test.tidb_server; CREATE TABLE test.tidb_server (server_name VARCHAR(255)); INSERT INTO test.tidb_server (server_name) VALUES ('tidb-server01-port-4001'); EOF mysql -u root -h 127.0.0.1 -P 4002 << EOF DROP TABLE IF EXISTS test.tidb_server; CREATE TABLE test.tidb_server (server_name VARCHAR(255)); INSERT INTO test.tidb_server (server_name) VALUES ('tidb-server02-port-4002'); EOFmysql -u root -h 127.0.0.1 -P 4001 << EOF DROP TABLE IF EXISTS test.tidb_server; CREATE TABLE test.tidb_server (server_name VARCHAR(255)); INSERT INTO test.tidb_server (server_name) VALUES ('tidb-server01-port-4001'); EOF mysql -u root -h 127.0.0.1 -P 4002 << EOF DROP TABLE IF EXISTS test.tidb_server; CREATE TABLE test.tidb_server (server_name VARCHAR(255)); INSERT INTO test.tidb_server (server_name) VALUES ('tidb-server02-port-4002'); EOF运行下面的命令配置 ProxySQL,该命令会在 ProxySQL Admin Interface 中执行
proxysql-prepare.sql
,从而在 TiDB 容器和 ProxySQL 之间建立一个代理连接。- macOS
- CentOS
- Windows (Git Bash)
docker compose exec proxysql sh -c "mysql -uadmin -padmin -h127.0.0.1 -P6032 < ./proxysql-prepare.sql"docker compose exec proxysql sh -c "mysql -uadmin -padmin -h127.0.0.1 -P6032 < ./proxysql-prepare.sql"docker compose exec proxysql sh -c "mysql -uadmin -padmin -h127.0.0.1 -P6032 < ./proxysql-prepare.sql"下面是关于 ProxySQL 匹配 SQL 查询的规则的一些补充信息:
- ProxySQL 尝试按照
rule_id
的升序逐一匹配规则。 - 规则中的
^
符号用于匹配 SQL 语句的开头,$
符号用于匹配语句的结尾。
关于 ProxySQL 正则表达式和模式匹配的更多信息,参考 ProxySQL 文档
mysql-query_processor_regex
。关于完整的参数列表,参考 ProxySQL 文档
mysql_query_rules
。验证配置并检查查询规则是否有效。
使用
root
用户登录 ProxySQL MySQL Interface:- macOS
- CentOS
- Windows (Git Bash)
mysql -u root -h 127.0.0.1 -P 6034mysql -u root -h 127.0.0.1 -P 6034mysql -u root -h 127.0.0.1 -P 6034执行以下 SQL 语句:
执行一个
SELECT
语句:SELECT * FROM test.tidb_server;这个语句将匹配
rule_id
为2
的规则,因此将转发语句到hostgroup
为1
上的 TiDB 集群中。执行一个
SELECT ... FOR UPDATE
语句:SELECT * FROM test.tidb_server FOR UPDATE;这个语句将匹配
rule_id
为1
的规则,因此将转发语句到hostgroup
为0
上的 TiDB 集群中。启动一个事务:
BEGIN; INSERT INTO test.tidb_server (server_name) VALUES ('insert this and rollback later'); SELECT * FROM test.tidb_server; ROLLBACK;在这个事务中,
BEGIN
语句将不会匹配任何规则。因此,它将使用默认的hostgroup
(在这个例子中为hostgroup 0
)。因为 ProxySQL 默认启用了用户 transaction_persistent,它将在同一事务中,将所有语句都转发至相同的hostgroup
,所以INSERT
和SELECT * FROM test.tidb_server;
语句也将被转发到hostgroup
为0
的 TiDB 集群。
下面是一个输出示例。如果你得到类似的输出,表示你已经成功配置了 ProxySQL 的查询规则。
+-------------------------+ | server_name | +-------------------------+ | tidb-server02-port-4002 | +-------------------------+ +-------------------------+ | server_name | +-------------------------+ | tidb-server01-port-4001 | +-------------------------+ +--------------------------------+ | server_name | +--------------------------------+ | tidb-server01-port-4001 | | insert this and rollback later | +--------------------------------+如需退出 MySQL 客户端,输入
quit
并按下 Enter 键。
要停止和删除容器,并返回上一个目录,运行以下命令:
- macOS
- CentOS
- Windows (Git Bash)
docker compose down cd -docker compose down cd -docker compose down cd -