title | summary |
---|---|
ProxySQL 集成指南 |
了解如何将本地部署的 TiDB 或 TiDB Cloud 集群与 ProxySQL 集成。 |
本文简要介绍 ProxySQL,描述如何在开发环境和生产环境中将 ProxySQL 与 TiDB 集成,并通过查询规则的场景展示集成的主要优势。
关于 TiDB 和 ProxySQL 的更多信息,请参考以下文档:
ProxySQL 是一个高性能的开源 SQL 代理。它具有灵活的架构,可以通过多种方式部署,适合各类使用场景。例如,ProxySQL 可以通过缓存频繁访问的数据来提高性能。
ProxySQL 的设计目标是快速、高效且易于使用。它完全兼容 MySQL,并支持高质量 SQL 代理的所有功能。此外,ProxySQL 还提供了许多独特功能,使其成为各种应用程序的理想选择。
- ProxySQL 可以通过降低与 TiDB 交互的延迟来提升应用程序性能。无论你构建什么,无论是使用 Lambda 等无服务器函数的可扩展应用程序(其工作负载不确定并且可能激增),还是构建执行大量数据查询的应用程序,都可以利用 ProxySQL 的强大功能(例如连接池和缓存常用查询)。
- ProxySQL 可以作为应用程序安全防护的附加层,使用查询规则防止 SQL 漏洞(例如 SQL 注入)。
- 由于 ProxySQL 和 TiDB 都是开源项目,你可以享受到零供应商锁定的好处。
将 ProxySQL 与 TiDB 集成的最直接方式是在应用层和 TiDB 之间添加 ProxySQL 作为独立中介。但是,这种方式无法保证可扩展性和容错性,而且可能因为网络跳转而增加延迟。为避免这些问题,一种替代部署架构是将 ProxySQL 作为附属容器部署,如下图所示:
注意:
上图仅供参考,你需要根据实际的部署架构进行调整。
本节介绍如何在开发环境中将 TiDB 与 ProxySQL 集成。在满足前提条件的情况下,你可以根据 TiDB 集群类型选择以下选项之一开始集成 ProxySQL:
根据选择的方案,你可能需要以下依赖:
你可以按照下面的说明进行安装:
-
下载并启动 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 安装程序并运行。
在这个集成中,你将使用 ProxySQL Docker 镜像以及 TiDB Cloud Serverless 集群。下面的步骤将在端口 16033
上设置 ProxySQL,请确保此端口可用。
-
参考创建一个 TiDB Cloud Serverless 集群文档。记住为集群设置的 root 密码。
-
获取集群的
hostname
、port
及username
供后续使用。- 在 Clusters 页面,点击你的集群名称,进入集群概览页面。
- 在集群概览页面的 Connection 面板中,复制
Endpoint
、Port
与User
字段,其中Endpoint
是集群的hostname
。
-
克隆 TiDB 和 ProxySQL 的集成示例代码仓库
tidb-proxysql-integration
: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
目录: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 配置文件: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.
-
启动 Docker。如果 Docker 已经启动,请跳过此步骤:
双击已安装的 Docker 的图标来启动它。
systemctl start docker
双击已安装的 Docker 的图标来启动它。
-
拉取 ProxySQL 镜像,并在后台启动一个 ProxySQL 容器:
docker compose up -d
docker compose up -d
docker compose up -d
-
运行以下命令集成 ProxySQL,该命令会在 ProxySQL Admin Interface 内执行
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"
docker compose exec proxysql sh -c "mysql -uadmin -padmin -h127.0.0.1 -P6032 < ./proxysql-prepare.sql"
注意:
proxysql-prepare.sql
脚本执行以下操作:- 使用集群的用户名和密码添加一个 ProxySQL 用户。
- 将该用户分配给监控账户。
- 将你的 TiDB Cloud Serverless 集群添加到主机列表中。
- 在 ProxySQL 和 TiDB Cloud Serverless 集群之间启用安全连接。
为了更好地理解此处的配置流程,强烈建议查看
proxysql-prepare.sql
文件。关于 ProxySQL 配置的更多信息,参考 ProxySQL 文档。下面是一个输出示例。输出中显示集群的主机名,这意味着 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:
-
运行
proxysql-connect.py
连接到你的 TiDB 集群。该脚本将自动启动 MySQL 客户端并使用你在步骤 2 中指定的用户名和密码进行连接。python3 proxysql-connect.py
python3 proxysql-connect.py
python proxysql-connect.py
-
连接 TiDB 集群后,可以使用以下 SQL 语句验证连接:
SELECT VERSION();
如果输出了 TiDB 的版本信息,则表示你已经成功通过 ProxySQL 连接到 TiDB Cloud Serverless 集群。如需退出 MySQL 客户端,输入
quit
并按下 Enter 键。注意:
调试提示: 如果无法连接到集群,请检查
tidb-cloud-connect.cnf
、proxysql-prepare.sql
和proxysql-connect.py
文件,确保你提供的服务器信息可用且正确。 -
要停止和删除容器,并返回上一个目录,运行以下命令:
docker compose down cd -
docker compose down cd -
docker compose down cd -
在这个集成中,你将使用 TiDB 和 ProxySQL 的 Docker 镜像设置环境。你也可以尝试其他方式安装 TiDB。
下面的步骤将在端口 6033
和 4000
上分别设置 ProxySQL 和 TiDB,请确保这些端口可用。
-
启动 Docker。如果 Docker 已经启动,请跳过此步骤:
双击已安装的 Docker 的图标来启动它。
systemctl start docker
双击已安装的 Docker 的图标来启动它。
-
克隆 TiDB 和 ProxySQL 的集成示例代码仓库
pingcap-inc/tidb-proxysql-integration
: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 的最新镜像:
cd tidb-proxysql-integration && docker compose pull
cd tidb-proxysql-integration && docker compose pull
cd tidb-proxysql-integration && docker compose pull
-
使用 TiDB 和 ProxySQL 容器启动一个集成环境:
docker compose up -d
docker compose up -d
docker compose up -d
你可以使用
root
用户名及空密码登录到 ProxySQL 的6033
端口。 -
通过 ProxySQL 连接到 TiDB:
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 集群。
-
要停止和删除容器,并返回上一个目录,运行以下命令:
docker compose down cd -
docker compose down cd -
docker compose down cd -
对于生产环境,建议直接使用 TiDB Cloud Dedicated 以获得完全托管的体验。
下载并安装一个 MySQL 客户端。例如,MySQL Shell。
你可以在不同的平台上安装 ProxySQL,下面以 CentOS 为例进行说明。
关于 ProxySQL 支持的平台和版本要求的完整列表,见 ProxySQL 文档。
具体步骤请参考创建一个 TiDB Cloud Dedicated 集群。
-
将 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 安装文档。
为了使用 ProxySQL 作为 TiDB 的代理,你需要配置 ProxySQL。你可以在 ProxySQL Admin Interface 中执行 SQL 语句(推荐)或使用配置文件进行配置。
注意:
以下章节仅列出 ProxySQL 的必要配置项。
完整的配置信息,可参考 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;
注意:
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
,直到事务被提交或回滚。
这个选项只能作为配置 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
。如果你已经在前面的步骤中克隆了它,请跳过这一步。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 查询规则的示例目录:
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 容器:
docker compose up -d
docker compose up -d
docker compose up -d
如果运行成功,以下容器将被启动:
- 两个 Docker 容器的 TiDB 集群,端口分别为
4001
和4002
- 一个 Docker 容器的 ProxySQL,端口为
6034
- 两个 Docker 容器的 TiDB 集群,端口分别为
-
在两个 TiDB 容器中,使用
mysql
创建一个具有相同 schema 的表,然后插入不同的数据 ('tidb-server01-port-4001'
,'tidb-server02-port-4002'
) 以区分这两个容器。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 之间建立一个代理连接。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
。 - 在 ProxySQL 中添加 TiDB 集群,
-
验证配置并检查查询规则是否有效。
-
使用
root
用户登录 ProxySQL MySQL Interface: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 键。
-
-
要停止和删除容器,并返回上一个目录,运行以下命令:
docker compose down cd -
docker compose down cd -
docker compose down cd -