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.git
git clone https://github.com/pingcap-inc/tidb-proxysql-integration.git
git 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-connect
cd tidb-proxysql-integration/example/tidb-cloud-connect
cd tidb-proxysql-integration/example/tidb-cloud-connect
运行
proxysql-config.py
生成 ProxySQL 配置文件:- macOS
- CentOS
- Windows (Git Bash)
python3 proxysql-config.py
python3 proxysql-config.py
python 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 -d
docker compose up -d
docker 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-prepare.sql
脚本执行以下操作:- 使用集群的用户名和密码添加一个 ProxySQL 用户。
- 将该用户分配给监控账户。
- 将你的 TiDB Serverless 集群添加到主机列表中。
- 在 ProxySQL 和 TiDB Serverless 集群之间启用安全连接。
为了更好地理解此处的配置流程,强烈建议查看
proxysql-prepare.sql
文件。关于 ProxySQL 配置的更多信息,参考 ProxySQL 文档。下面是一个输出示例。输出中显示集群的主机名,这意味着 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.py
python3 proxysql-connect.py
python proxysql-connect.py
连接 TiDB 集群后,可以使用以下 SQL 语句验证连接:
SELECT VERSION();
如果输出了 TiDB 的版本信息,则表示你已经成功通过 ProxySQL 连接到 TiDB Serverless 集群。如需退出 MySQL 客户端,输入
quit
并按下 Enter 键。注意
调试提示: 如果无法连接到集群,请检查
tidb-cloud-connect.cnf
、proxysql-prepare.sql
和proxysql-connect.py
文件,确保你提供的服务器信息可用且正确。要停止和删除容器,并返回上一个目录,运行以下命令:
- 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.git
git clone https://github.com/pingcap-inc/tidb-proxysql-integration.git
git clone https://github.com/pingcap-inc/tidb-proxysql-integration.git
拉取 ProxySQL 和 TiDB 的最新镜像:
- macOS
- CentOS
- Windows (Git Bash)
cd tidb-proxysql-integration && docker compose pull
cd tidb-proxysql-integration && docker compose pull
cd tidb-proxysql-integration && docker compose pull
使用 TiDB 和 ProxySQL 容器启动一个集成环境:
- macOS
- CentOS
- Windows (Git Bash)
docker compose up -d
docker compose up -d
docker compose up -d
你可以使用
root
用户名及空密码登录到 ProxySQL 的6033
端口。通过 ProxySQL 连接到 TiDB:
- macOS
- CentOS
- Windows (Git Bash)
mysql -u root -h 127.0.0.1 -P 6033
mysql -u root -h 127.0.0.1 -P 6033
mysql -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 语句(推荐)或使用配置文件进行配置。
注意
以下章节仅列出 ProxySQL 的必要配置项。
完整的配置信息,可参考 ProxySQL 文档。
选项 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;
注意
hostgroup_id
:指定一个 hostgroup 的 ID。ProxySQL 使用 hostgroup 管理集群。如果需要将 SQL 流量均匀地分配给这些集群,你可以将需要负载均衡的几个 TiDB 集群配置到同一个 hostgroup 中。另一方面,为了区分不同的集群,例如为了实现读写分离,你可以将它们配置为不同的 hostgroup ID。hostname
:TiDB 集群的Endpoint
。port
:TiDB 集群的Port
。
为配置 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;
注意
username
:TiDB 用户名。password
:TiDB 密码。active
:指定用户是否处于激活状态。1
表示该用户是激活的,可以用于登录,0
表示该用户是非激活的。default_hostgroup
:用户使用的默认hostgroup
,除非特定的查询规则覆盖了hostgroup
,否则 SQL 将会默认路由到default_hostgroup
。transaction_persistent
:值为1
表示使用持久性事务。即当用户在一个连接中启动一个事务时,所有的查询语句都被路由到同一个hostgroup
,直到事务被提交或回滚。
选项 2: 使用配置文件配置 ProxySQL
这个选项只能作为配置 ProxySQL 的备用方案。更多信息,可参考使用配置文件配置 ProxySQL。
删除现有的 SQLite 数据库,即 ProxySQL 存储配置的位置。
rm /var/lib/proxysql/proxysql.db
警告
删除 SQLite 数据库后,通过 ProxySQL Admin Interface 所做的任何配置更改都会丢失。
根据你的需要修改配置文件
/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 数据库。
警告
在生产环境中,不要使用默认的管理员用户运行 ProxySQL。在启动 proxysql
服务之前,你可以通过修改 admin_credentials 变量更改 /etc/proxysql.cnf
文件中的默认值。
典型场景
本节以查询规则为例,介绍集成 TiDB 与 ProxySQL 能带来的一些优势。
查询规则
数据库可能会因为高流量、错误代码或恶意攻击而过载。因此,审核 SQL 是必要的。使用 ProxySQL 的查询规则,你可以有效地应对这些问题,例如通过重路由、改写 SQL 或者拒绝查询等方式。
注意
以下步骤使用 TiDB 和 ProxySQL 的容器镜像配置查询规则。如果你还没有拉取这些镜像,请参考集成本地部署的 TiDB 与 ProxySQL 部分的详细步骤。
克隆 TiDB 和 ProxySQL 的集成示例代码仓库 pingcap-inc/tidb-proxysql-integration。如果你已经在前面的步骤中克隆了它,请跳过这一步。
- macOS
- CentOS
- Windows (Git Bash)
git clone https://github.com/pingcap-inc/tidb-proxysql-integration.git
git clone https://github.com/pingcap-inc/tidb-proxysql-integration.git
git clone https://github.com/pingcap-inc/tidb-proxysql-integration.git
进入 ProxySQL 查询规则的示例目录:
- macOS
- CentOS
- Windows (Git Bash)
cd tidb-proxysql-integration/example/proxy-rule-admin-interface
cd tidb-proxysql-integration/example/proxy-rule-admin-interface
cd tidb-proxysql-integration/example/proxy-rule-admin-interface
运行下面的命令启动两个 TiDB 容器和一个 ProxySQL 容器:
- macOS
- CentOS
- Windows (Git Bash)
docker compose up -d
docker compose up -d
docker 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');
EOF
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');
EOF
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');
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-prepare.sql
脚本完成以下操作:- 在 ProxySQL 中添加 TiDB 集群,
hostgroup_id
分别为0
和1
。 - 添加一个用户
root
,密码为空,并设置default_hostgroup
为0
。 - 添加规则
^SELECT.*FOR UPDATE$
,rule_id
为1
,destination_hostgroup
为0
。这代表如果一个 SQL 语句与此规则相匹配,该请求将被转发到hostgroup
为0
的 TiDB 集群。 - 添加规则
^SELECT
,rule_id
为2
,destination_hostgroup
为1
。这代表如果一个 SQL 语句与此规则相匹配,该请求将被转发到hostgroup
为1
的 TiDB 集群。
为了更好地理解此处的配置流程,强烈建议查看
proxysql-prepare.sql
文件。关于 ProxySQL 配置的更多信息,参考 ProxySQL 文档。下面是关于 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 6034
mysql -u root -h 127.0.0.1 -P 6034
mysql -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 -