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 Serverless 集群。下面的步骤将在端口 16033
上设置 ProxySQL,请确保此端口可用。
步骤 1. 创建一个 TiDB Serverless 集群
参考创建一个 TiDB 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 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 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 以获得完全托管的体验。
前提条件
下载并安装一个 MySQL 客户端。例如,MySQL Shell。
基于 CentOS 集成 TiDB Cloud 与 ProxySQL
你可以在不同的平台上安装 ProxySQL,下面以 CentOS 为例进行说明。
关于 ProxySQL 支持的平台和版本要求的完整列表,见 ProxySQL 文档。
步骤 1. 创建一个 TiDB Dedicated 集群
具体步骤请参考创建一个 TiDB 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 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 -