MySQL 代理层:ProxySQL

news2024/12/26 1:01:47

文章目录

    • 说明
    • 安装部署
      • 1.1 yum 安装
      • 1.2 启停管理
      • 1.3 查询版本
      • 1.4 Admin 管理接口
    • 入门体验
    • 功能介绍
      • 3.1 多层次配置系统
    • 读写分离
      • 将实例接入到代理服务
      • 定义主机组之间的复制关系
      • 配置路由规则
      • 事务读的配置
      • 延迟阈值和请求转发
    • ProxySQL 核心表
      • mysql_users
      • mysql_servers
      • mysql_replication_hostgroups
      • mysql_query_rules
    • 高级特性
      • SQL 审计
      • SQL 黑名单
      • ProxySQL Cluster
        • 搭建 ProxySQL Cluster
    • 参考文档

说明

MySQL 常见代理有 MySQ Proxy、Atlas、MaxScale、ProxySQ L其中 MySQL Proxy 是 MySQL 原厂研发的,没有发布过 GA 版,项目已经 9 年没有维护,官方不建议生产环境使用。另外三个项目都是第三方研发的开源代理,其中 ProxySQL 项目的 Star 最多,而且一直都在维护。本篇 SOP 主要介绍 ProxySQL 运维管理。

ProxySQL 官网:https://www.proxysql.com/

安装部署

1.1 yum 安装

以 CentOS Linux release 7.8.2003 (Core) 系统版本为例:

cat <<EOF | tee /etc/yum.repos.d/proxysql.repo
[proxysql_repo]
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

使用 yum 安装,可以指定版本:

yum install proxysql OR yum install proxysql-version

1.2 启停管理

service proxysql start   # 启动 proxysql
service proxysql stop    # 停止 proxysql
service proxysql status  # 查看 proxysql 状态

1.3 查询版本

proxysql --version

1.4 Admin 管理接口

当 ProxySQL 启动后,将会监听两个端口:
**Admin 管理接口:**默认为 6032 该端口用于管理配置 ProxySQL。
**接收业务 SQL 接口:**默认为 6033 用于服务业务端口,类似于 MySQL 的 3306 端口。

请添加图片描述

Admin 管理接口兼容 MySQL 客户端协议,所以可以直接使用 MySQL 客户端连接这个管理接口。

mysql -u admin -padmin -h 127.0.0.1 -P6032 --prompt='Admin> '

一般来讲 Admin 接口不需要额外配置,最有可能需要配置的是 Admin 用户的密码。

Admin> select @@admin-admin_credentials;
+---------------------------+
| @@admin-admin_credentials |
+---------------------------+
| admin:admin               |
+---------------------------+

修改 Admin 接口密码:

set admin-admin_credentials='admin:YouPassword';

load admin variables to runtime; -- 立即生效
save admin variables to disk; -- 持久化磁盘

入门体验

以下是测试使用的环境信息,操作系统均为 CentOS 7.9 版本。

ip 地址角色程序
172.16.104.56主节点MySQL 5.7.33
172.16.104.57备节点MySQL 5.7.33
172.16.104.55代理节点ProxySQL 2.4.3

接下来,一起简单的测试一下 ProxySQL,使用下方命令登入管理端。

mysql -u admin -padmin -h 127.0.0.1 -P6032 --prompt='Admin> '

-- 设置监控后端使用的账号信息
set mysql-monitor_username = 'monitor';
set mysql-monitor_password = 'monitor';

-- 配置生效
load mysql variables to runtime;
save mysql variables to disk;

在后端创建 ProxySQL 的监控账户:

create user 'monitor'@'%' identified with mysql_native_password 
 by 'monitor';
 
grant replication client on *.* to 'monitor'@'%';

-- group replication
grant select on performance_schema.replication_group_member_stats 
 to 'monitor'@'%';

grant select on performance_schema.replication_group_members 
 to 'monitor'@'%';

配置后端节点,写入后端节点的 ip、端口、主机组。

insert into mysql_servers (hostgroup_id, hostname, port) values (1, '172.16.104.56', 3306);

LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;

配置访问用户,这里的用户分为两种含义:

  • 前端用户:客户端用来访问 ProxySQL 的用户。
  • 后端用户:ProxySQL 用来访问后端 MySQL 节点的用户。

在此,案例中我们配置的前后端用户一致。在 MySQL 中创建后端使用的账号:

-- 创建后端用户
create user 'op_user'@'%' identified by 'abc123';
grant all privileges on *.* to 'op_user'@'%';

将账号信息录入到 ProxySQL 中:

-- 写入用户信息
insert into mysql_users(username, password, default_hostgroup, comment) values ('op_user', 'abc123', 1, '后端用户');

-- 加载 & 持久化
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;

连接代理节点,访问数据库:

mysql -u op_user -pabc123 -h 172.16.104.55 -P6033 -e'select @@hostname;'
+---------------+
| @@hostname    |
+---------------+
| 172-16-104-56 |
+---------------+

功能介绍

ProxySQL 默认的配置文件位于/etc/proxysql.cnf,第一次启动 ProxySQL 会初始化配置数据库,往后的所有配置都可以在 ProxySQL 数据库中修复,直接修改配置文件则不会生效,除非重新初始化。

3.1 多层次配置系统

ProxySQL 为了实现动态修改大部分配置项,不需要重启,设计了多级配置系统,将配置从运行时环境移到内存,并在有需求时持久化到磁盘上。
请添加图片描述

  • 最底层的是 DISK 库和 CONFIG FILE,负责持久化保存配置。这里的 CONFIG FILE 就是传统的配置文件,ProxySQL 启动时,主要是从 DISK 库中读取配置加载到内存并最终加载到 runtime 生效,只有极少的几个特定配置内容是从 CONFIG FILE 中加载的,除非是第一次初始化 ProxySQL 运行环境或者 DISK 库为空。
  • 中间层的是 MEMORY,表示的是内存数据库,管理接口中的 main 库。通过管理接口可以修改所有配置,都保存在内存数据库中,此时并没有生效也没有持久化,需要 load 到上层 RUNTIME 才能生效,save 到下层 DISK 才能持久化保存。
  • 最上层的是 RUNTIME,它是 ProxySQL 相关线程运行时读取的数据结构。该数据结构中的配置都是已生效的配置。修改了 main 库中的配置后,必须 load 到 runtime 数据结构中才能使其生效。
    在这里插入图片描述

在上面的多层配置系统图中,标注了** [1]、[2]、[3]、[4]、[5] ** 的序号。每个序号都有两个操作方向 from/to b 以下是各序号对应的操作:

  • [1] LOAD FROM MEMORY / LOAD TO RUNTIME
  • [2] SAVE FROM RUNTIME / SAVE TO MEMORY
  • [3] LOAD FROM DISK / LOAD TO MEMORY
  • [4] SAVE FROM MEMORY / SAVE TO DISK
  • [5] LOAD FROM CONFIG

另外,上面的 是什么?这表示要 加载/保存 的是哪类配置。 详细如下:

+------------------------------------+
| tables                             |
+------------------------------------+
| global_variables                   |  # (1)
| mysql_collations                   |  # (N)
| mysql_group_replication_hostgroups |  # (2)
| mysql_query_rules                  |  # (3)
| mysql_query_rules_fast_routing     |  # (4)
| mysql_replication_hostgroups       |  # (5)
| mysql_servers                      |  # (6)
| mysql_users                        |  # (7)
| proxysql_servers                   |  # (8)
| scheduler                          |  # (9)
+------------------------------------+
  • (1)中包含两类变量,以 amdin 为前缀的表示 admin variables,以 mysql 为前缀的表示 mysql variables。
  • (2,5,6)对应的都是 mysql servers。
  • (3,4)对应的是 mysql query rules。
  • (7)对应的 mysql users。
  • (9)对应的 scheduler。
  • (N)只是一张表,保存的是 ProxySQL 支持的字符集和排序规则,不需要修改。
  • (8)是 ProxySQL 的集群配置表,对应 proxysql_servers。

在 ProxySQL 客户端使用 DML/SET 语句修改配置,是直接在内存中修改的,所以需要使用命令持久化和激活,这也是官方推荐的管理方式。下面提供常见的管理语句:

  1. 激活/持久化 MySQL 用户配置:
# Active current in-memory MySQL User configuration
LOAD MYSQL USERS TO RUNTIME;

# Save the current in-memory MySQL User configuration to disk
SAVE MYSQL USERS TO DISK;
  1. 激活/持久化 MySQL 服务器配置和主机组配置:
# Active current in-memory MySQL Server and Replication Hostgroup configuration
LOAD MYSQL SERVERS TO RUNTIME;

# Save the current in-memory MySQL Server and Replication Hostgroup configuration to disk
SAVE MYSQL SERVERS TO DISK;
  1. 激活/持久化 MySQL 查询规则:
# Active current in-memory MySQL Query Rule configuration
LOAD MYSQL QUERY RULES TO RUNTIME;

# Save the current in-memory MySQL Query Rule configuration to disk
SAVE MYSQL QUERY RULES TO DISK;
  1. 激活/持久化 MySQL 管理变量:
# Active current in-memory MySQL Variable configuration
LOAD MYSQL VARIABLES TO RUNTIME;

# Save the current in-memory MySQL Variable configuration to disk
SAVE MYSQL VARIABLES TO DISK;
  1. 激活/持久化 ProxySQL 管理变量:
# Active current in-memory ProxySQL Admin Variable configuration
LOAD ADMIN VARIABLES TO RUNTIME;

# Save the current in-memory ProxySQL Admin Variable configuration to disk
SAVE ADMIN VARIABLES TO DISK;

读写分离

在入门体验中,已完成监控账号、业务账号的创建和配置,并将主节点完成接入。本小节,将介绍一个高频的使用场景,就是读写分离。

将实例接入到代理服务

下图,是当前的 mysql_servers 表的配置,只添加了主库。

Admin> select * from mysql_servers;
+--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| hostgroup_id | hostname      | port | gtid_port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment |
+--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| 1            | 172.16.104.56 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
+--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+

现在将备库也接入进来:

insert into mysql_servers (hostgroup_id, hostname, port) values (2, '172.16.104.57', 3306);

LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;

定义主机组之间的复制关系

主机之间的复制关系是通过 hostgroup_id 来绑定的,关系定义使用的是 mysql_replication_hostgroups 表。

insert into mysql_replication_hostgroups(writer_hostgroup, reader_hostgroup, check_type, comment) values(1, 2, 'read_only', 'op 集群');

LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;

ProxySQL 会基于后端节点 check_type 的值,来动态调整它所属的主机组,所以必须保证从库的 read_only 参数为 on 的状态。

配置路由规则

路由的规则是在 mysql_query_rules 中配置:

insert into mysql_query_rules(rule_id, active, match_pattern, destination_hostgroup, apply) values (1, 1, '^SELECT.*FOR UPDATE$', 1, 1);
insert into mysql_query_rules(rule_id, active, match_pattern, destination_hostgroup, apply) values (2, 1, '^SELECT', 2, 1);
  • rule_id:是规则 ID。
  • active:表示是否启动规则。
  • match_pattern:表示匹配规则,支持正则匹配。
  • apply:设置为 1,如果当前的规则匹配,则不再进行后续其他规则的匹配。
  • destination_hostgroup:SQL转发目的 hostgroup。

上方配置的路由规则效果如下:

  • 所有的 SELECT FOR UPDATE 操作将发往主库执行。
  • 其他所有的 SELECT 操作将发往备库执行。
  • 除此之外的所有操作将默认发往主库处理。

配置完成后,验证一下:

mysql -u op_user -pabc123 -h 172.16.104.55 -P6033

-- 测试执行 SQL 语句
select * from test_semi;
select * from test_semi where a = 10 for update;

连接管理节点,查看日志:

mysql -u admin -padmin -h 127.0.0.1 -P6032 --prompt='Admin> '

-- 查询 SQL 执行情况
select hostgroup, digest_text from stats.stats_mysql_query_digest order by first_seen desc;
+-----------+------------------------------------------------+
| hostgroup | digest_text                                    |
+-----------+------------------------------------------------+
| 1         | select * from test_semi where a = ? for update |
| 2         | select * from test_semi                        |
+-----------+------------------------------------------------+

事务读的配置

接下来我们验证另外一个操作,显式开启事务后执行 SELECT 操作。

begin;
select * from test_semi;
update test_semi set c = 123 where a = 10;
select * from test_semi;
commit;

执行结果可以通过 stats.stats_mysql_query_digest 表进行观测。这里直接说结论,显式开启事务后,会直接路由到主库执行,该行为由 mysql_users 表中的 transaction_persistent 参数有关。创建用户时,如果不指定 transaction_persistent 参数,其默认值为 1,表示事务开启后,所有的操作都会在事务开启的主机组中执行,此时会忽略所有的路由规则。
我们将 transaction_persistent 设置为 0 测试一下。

update mysql_users set transaction_persistent = 0 where username = 'op_user';

-- 配置生效
LOAD MYSQL USERS TO RUNTIME;

开启事务后,执行查询可以看到是路由到了备库,不过 transaction_persistent = 1 更符合我们对事务的认知习惯。

Admin> select hostgroup, digest_text from stats.stats_mysql_query_digest order by first_seen desc;
+-----------+----------------------------------------+
| hostgroup | digest_text                            |
+-----------+----------------------------------------+
| 1         | commit                                 |
| 1         | update test_semi set c = ? where a = ? |
| 2         | select * from test_semi                |
| 1         | begin                                  |
+-----------+----------------------------------------+

延迟阈值和请求转发

上方是一个比较简单的读写分离配置,实际上我们还会遇到如下问题:

  • 如果备库宕机了,所有转发的查询都会失败。
  • 如果备库的延迟过高,查询会读取到旧数据。

接下来我们通过配置 延迟阈值路由权重 来解决。

  • 备库宕机了,所有的请求都会转发到主库。
  • 为备库设置延迟阈值,如果延迟大于该值,请求会自动转发到主库。
-- 写入一个规则
insert into mysql_servers (hostgroup_id, hostname, port) values (2, '172.16.104.56', 3306);

-- 修改备库配置
update mysql_servers set weight = 100, max_replication_lag = 30 where hostname = '172.16.104.57';

第一条 SQL 将主库加入到了 reader_hostgroup 中,这样当备库出现故障的时候,查询会自动路由到主库中。
第二条 SQL 调大了备库的权重,这样只有极少部分 SQL 会路由到主库,同时将 max_replication_lag 调整到了 30,表示延迟如果大于 30 的时候,查询会路由到主库。

ProxySQL 核心表

本节会介绍 ProxySQL 中常用的表,熟悉这些表中字段的含义。

mysql_users

该表用来配置用户信息。

CREATE TABLE mysql_users (
    username VARCHAR NOT NULL,
    password VARCHAR,
    active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1,
    use_ssl INT CHECK (use_ssl IN (0,1)) NOT NULL DEFAULT 0,
    default_hostgroup INT NOT NULL DEFAULT 0,
    default_schema VARCHAR,
    schema_locked INT CHECK (schema_locked IN (0,1)) NOT NULL DEFAULT 0,
    transaction_persistent INT CHECK (transaction_persistent IN (0,1)) NOT NULL DEFAULT 1,
    fast_forward INT CHECK (fast_forward IN (0,1)) NOT NULL DEFAULT 0,
    backend INT CHECK (backend IN (0,1)) NOT NULL DEFAULT 1,
    frontend INT CHECK (frontend IN (0,1)) NOT NULL DEFAULT 1,
    max_connections INT CHECK (max_connections >=0) NOT NULL DEFAULT 10000,
    attributes VARCHAR CHECK (JSON_VALID(attributes) OR attributes = '') NOT NULL DEFAULT '',
    comment VARCHAR NOT NULL DEFAULT '',
    PRIMARY KEY (username, backend),
    UNIQUE (username, frontend)) 
  • username & password:用户名和密码。
  • active:是否激活账号。
  • use_ssl:设置为 1,则强制用户使用 SSL 证书进行身份验证。
  • default_hostgroup:默认的主机组。如果没有匹配的路由规则或路由规则没配置,请求会转发到默认主机组。
  • default_schema:默认的 schema。如果不设置,则由 mysql-default_schema 决定。
  • schema_locked:目前未实现。
  • transaction_persistent:设置为 1,则代表一个事务内的所有请求都会转发到第一个主机组内执行。
  • fast_forward:设置为 1,则表示由该用户发起的 SQL 会跳过重写、缓存 等查询处理层,执行转发到后端。
  • backend & frontend:当前没有实现前后端分离,默认为 1 即可。
  • max_connections:账号的最大连接数,默认为 1。
  • attributes:目前未实现。
  • comment:注释。

mysql_servers

用于配置后端的 MySQL 节点。

CREATE TABLE mysql_servers (
    hostgroup_id INT CHECK (hostgroup_id>=0) NOT NULL DEFAULT 0,
    hostname VARCHAR NOT NULL,
    port INT CHECK (port >= 0 AND port <= 65535) NOT NULL DEFAULT 3306,
    gtid_port INT CHECK ((gtid_port <> port OR gtid_port=0) AND gtid_port >= 0 AND gtid_port <= 65535) NOT NULL DEFAULT 0,
    status VARCHAR CHECK (UPPER(status) IN ('ONLINE','SHUNNED','OFFLINE_SOFT', 'OFFLINE_HARD')) NOT NULL DEFAULT 'ONLINE',
    weight INT CHECK (weight >= 0 AND weight <=10000000) NOT NULL DEFAULT 1,
    compression INT CHECK (compression IN(0,1)) NOT NULL DEFAULT 0,
    max_connections INT CHECK (max_connections >=0) NOT NULL DEFAULT 1000,
    max_replication_lag INT CHECK (max_replication_lag >= 0 AND max_replication_lag <= 126144000) NOT NULL DEFAULT 0,
    use_ssl INT CHECK (use_ssl IN(0,1)) NOT NULL DEFAULT 0,
    max_latency_ms INT UNSIGNED CHECK (max_latency_ms>=0) NOT NULL DEFAULT 0,
    comment VARCHAR NOT NULL DEFAULT '',
    PRIMARY KEY (hostgroup_id, hostname, port) )
  • hostgroup_id:主机组 ID。
  • hostname:后端节点的主机名或 IP。
  • port:后端节点的端口。
  • gtid_port:不详。
  • status:节点的状态,有 ONLINE、SHUNNED、OFFLINE_SOFT、OFFLINE_HARD 四个取值。
    • ONLINE:节点状态正常,可对外服务。
    • SHUNNED:节点暂时离线,无法对外服务。
    • OFFLINE_SOFT:节点离线,在离线前会等待该节点的事务执行完。
    • OFFLINE_HARD:节点离线,如果当前节点有事务正在执行会 Kill 掉。
  • weight:读写分离的权重,权重越高被分发的请求就越多。
  • compression:是否开启压缩。
  • max_connections:限制 ProxySQL 到后端节点的最大连接数。
  • max_replication_lag:主备的延迟阈值。一旦超过该值,该节点的状态会被设置为 SHUNNED,直到延迟恢复。
  • use_ssl:是否开启 SSL 连接,针对的是 ProxySQL 与后端之间的连接。
  • max_latency_ms:ProxySQL 会定期对后端节点进行 ping 操作,如果 ping 的响应时间超过该参数,则会将该节点从连接池中剔除。
  • comment:注释。

mysql_replication_hostgroups

用于配置复制关系的表。

CREATE TABLE mysql_replication_hostgroups (
    writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY,
    reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND reader_hostgroup>=0),
    check_type VARCHAR CHECK (LOWER(check_type) IN ('read_only','innodb_read_only','super_read_only','read_only|innodb_read_only','read_only&innodb_read_only')) NOT NULL DEFAULT 'read_only',
    comment VARCHAR NOT NULL DEFAULT '', UNIQUE (reader_hostgroup))
  • writer_hostgroup:定义可写的主机组。
  • reader_hostgroup:定义只读的主机组。
  • check_type:检测类型,提供了多种选择,基本都是通过 read_only 的值来区分的。
  • comment:注释。

将主库和备库的 hostgroup 配置到 mysql_replication_hostgroups 表中后,ProxySQL 会检测主备库的 read_only 状态。
当检测到 read_only 从 OFF 变成 ON 时,会将 writer_hostgroup 中的主机添加的 reader_hostgrup 中。
反之,当 read_only 从 ON 变成 OFF 时,会将其调整到 writer_hostgroup 组中。
由此可见,在 ProxySQL 中,一定要将备库的 read_only 设置为 on,否则可能会出现双写。
当一个后端 MySQL 实例的 read_only 状态从 ON 变成 OFF 时,会将该实例加入到 writer_hostgroup 中,同时该实例依然位于 read_hostgroup 中。如果需要将该实例从 read_hostgroup 中移除,需要将参数 mysql-monitor_writer_is_also_reader 设置为 false。

set mysql-monitor_writer_is_also_reader='false';
load mysql variables to runtime;

mysql_query_rules

用于配置路由关系的表。

CREATE TABLE mysql_query_rules (
    rule_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 0,
    username VARCHAR,
    schemaname VARCHAR,
    flagIN INT CHECK (flagIN >= 0) NOT NULL DEFAULT 0,
    client_addr VARCHAR,
    proxy_addr VARCHAR,
    proxy_port INT CHECK (proxy_port >= 0 AND proxy_port <= 65535),
    digest VARCHAR,
    match_digest VARCHAR,
    match_pattern VARCHAR,
    negate_match_pattern INT CHECK (negate_match_pattern IN (0,1)) NOT NULL DEFAULT 0,
    re_modifiers VARCHAR DEFAULT 'CASELESS',
    flagOUT INT CHECK (flagOUT >= 0),
    replace_pattern VARCHAR CHECK(CASE WHEN replace_pattern IS NULL THEN 1 WHEN replace_pattern IS NOT NULL AND match_pattern IS NOT NULL THEN 1 ELSE 0 END),
    destination_hostgroup INT DEFAULT NULL,
    cache_ttl INT CHECK(cache_ttl > 0),
    cache_empty_result INT CHECK (cache_empty_result IN (0,1)) DEFAULT NULL,
    cache_timeout INT CHECK(cache_timeout >= 0),
    reconnect INT CHECK (reconnect IN (0,1)) DEFAULT NULL,
    timeout INT UNSIGNED CHECK (timeout >= 0),
    retries INT CHECK (retries>=0 AND retries <=1000),
    delay INT UNSIGNED CHECK (delay >=0),
    next_query_flagIN INT UNSIGNED,
    mirror_flagOUT INT UNSIGNED,
    mirror_hostgroup INT UNSIGNED,
    error_msg VARCHAR,
    OK_msg VARCHAR,
    sticky_conn INT CHECK (sticky_conn IN (0,1)),
    multiplex INT CHECK (multiplex IN (0,1,2)),
    gtid_from_hostgroup INT UNSIGNED,
    log INT CHECK (log IN (0,1)),
    apply INT CHECK(apply IN (0,1)) NOT NULL DEFAULT 0,
    attributes VARCHAR CHECK (JSON_VALID(attributes) OR attributes = '') NOT NULL DEFAULT '',
    comment VARCHAR)
  • rule_id:指定规则的 ID。该值越小,越先匹配。
  • active:是否启用规则。
  • username:基于用户名进行匹配。
  • schemaname:基于 schema 名进行匹配。
  • flagIN & flagOUT:定义规则的入口和出口,用于实现链式匹配规则。
  • client_addr:基于客户端地址进行匹配。通过 client_addr 实现简单的白名单功能。
  • proxy_addr & proxy_port:如果 ProxySQL 部署的服务器中有多个 IP 地址,可匹配来自指定 IP 的流量。
  • digest:基于 Query ID 进行匹配。
  • match_digest & match_pattern:基于正则表达式进行匹配,match_digest 是匹配模版化后的 SQL,match_pattern 是匹配原 SQL。
  • negate_match_pattern:设置为 1,表示没匹配上 match_digest & match_pattern 的规则才为真。
  • re_modifiers:设置正则引起的修饰符。
  • replace_pattern:替换后的文本,用于查询重写。
  • destination_hostgroup:规则目标的主机组。
  • cache_ttl:设置结果集的缓存时长,单位是毫秒。
  • cache_empty_result:是否缓存空的结果集。
  • cache_timeout:暂未实现。
  • reconnect:暂无实现。
  • timeout:定义查询的超时时长,单位是毫秒。如果查询在指定时间没有完成,则会被 ProxySQL kill 掉,如果不指定该字段,则由全局参数控制该行为 mysql-default_query_timeout 默认为 10 小时。
  • retries:查询失败重试的次数。
  • delay:定义查询延迟执行的时长,单位是毫秒。
  • mirror_flagOUT & mirror_hostgroup:用于景象功能。
  • error_msg:匹配规则的操作将返回 error_msg,用于实现黑名单的功能。
  • log:是否将匹配规则的查询记录到审计日志中。不指定的话,则由全局参数 mysql-eventlog_defalut_log 决定,默认为 0。
  • apply:若设置为 1 的话,则操作匹配到该规则时,会直接被转发给后端节点处理,不会再进行其他规则的匹配。

高级特性

本小节,介绍一下 ProxySQL 实用的高级特性。

SQL 审计

ProxySQL 可将流经它的 SQL 语句全部记录下来,用于审计分析和问题定位。是一个非常实用的功能,不过数据库流量如果比较大的话,会占用很大的存储空间。

Admin> show variables like 'mysql-eventslog%';
+-----------------------------+-----------+
| Variable_name               | Value     |
+-----------------------------+-----------+
| mysql-eventslog_filename    |           |
| mysql-eventslog_filesize    | 104857600 |
| mysql-eventslog_default_log | 0         |
| mysql-eventslog_format      | 1         |
+-----------------------------+-----------+

各参数含义如下:

  • mysql-eventslog_filename:日志前缀名。默认为空,代表 SQL 审计没有开启。
  • mysql-eventslog_filesize:日志的最大大小。超过此限制,会对日志进行切割,默认为 100MB。
  • mysql-eventslog_default_log:是否开启操作审计,默认为 0 不记录。
  • mysql-eventslog_format:日志的格式。1 表示二进制格式 2 表示 JSON 格式。如果要查看二进制格式的内容,必须使用专用的解析工具 eventslog_reader_sample。

下面我们进行一个测试:

set mysql-eventslog_filename = 'query';
set mysql-eventslog_format = 2;
set mysql-eventslog_default_log = 1;

LOAD MYSQL VARIABLES TO RUNTIME;
{"client":"172.16.104.56:38474","digest":"0xDC257DF652F9B5E6","duration_us":1764,"endtime":"2024-06-26 14:43:39.203870","endtime_timestamp_us":1719384219203870,"event":"COM_QUERY","hostgroup_id":2,"query":"select * from fractest1","rows_affected":0,"rows_sent":1,"schemaname":"test","server":"172.16.104.57:3306","starttime":"2024-06-26 14:43:39.202106","starttime_timestamp_us":1719384219202106,"thread_id":2,"username":"op_user"}

SQL 黑名单

当有一类 SQL 突然并发较高,打满数据库资源时,往往会导致数据库整体变慢。此时处理的方法,往往是让研发定位接口,然后停掉相关业务,及时止血,但也需要一定的时间,此时业务可能已经受损。
如果使用 ProxySQL 可以通过 SQL 黑名单的方式解决。接下来我们介绍通过 SQL 指纹来屏蔽 SQL 语句。
状态库 stats_mysql_query_digest 表中,记录了一些 TOP SQL 的信息,可从该表中获取 SQL 指纹。

select * from stats.stats_mysql_query_digest;

-- digest 字段是 SQL 指纹
-- 0xDC257DF652F9B5E6 | select * from fractest1

获取指纹后,需要写入路由规则,需要注意的是,路由规则是按 rule_id 顺序匹配的,所以屏蔽规则需要放在 rule_id 小的规则中,之前演示 rule_id = 1 和 2,所以限制改大。

Admin> update mysql_query_rules set rule_id = 11 where rule_id = 1;
Query OK, 1 row affected (0.00 sec)

Admin> update mysql_query_rules set rule_id = 12 where rule_id = 2;
Query OK, 1 row affected (0.00 sec)

插入屏蔽规则:·

insert into mysql_query_rules (rule_id, destination_hostgroup, digest, error_msg, active, apply, comment) values (1, 1, '0xDC257DF652F9B5E6', 'request denied by rule', 1, 1, 'request denied by rule');

load mysql query rules to runtime;
save mysql query rules to disk;

验证屏蔽效果:

op_user@mysql 15:15:  [test]>select * from fractest1;
ERROR 1148 (42000): request denied by rule

ProxySQL Cluster

ProxySQL 作为一个中间价,本身是无状态的,如果代理节点出现故障,那就会导致业务无法访问。所以线上一般会部署多个节点,使用 VIP 或者 LVS 来进行故障切换。既然涉及到多个节点,ProxySQL 的配置调整需要实时同步,这样将流量切换到任意一个代理都是正确可用的。这就是接下来 ProxySQL Cluster 的作用。

搭建 ProxySQL Cluster

开启 proxysql 的集群功能,需要:

  • 配置 cluster 账号,用于查询对比集群内各 proxysql 节点的配置信息
  • 配置 proxysql_servers,将集群内的 proxysql 节点信息添加到 proxysql_servers 表

以上操作需要到组成集群的每一个 proxysql 节点上执行。
通过参数 admin-cluster_username 和 admin-cluster_password 设置 cluster 账号。不能使用 admin 账号作为cluster 账号,因为 admin 账号只能在本地(127.0.0.1)登陆。
同时还需要将 cluster 账号添加到参数 admin-admin_credentials 中。

set admin-admin_credentials = 'admin:admin;clusteradmin:passadmin';

set admin-cluster_username='clusteradmin';
set admin-cluster_password='passadmin';

load admin variables to runtime;
save admin variables to disk;

将组成 proxysql 集群的多个节点的信息添加到 proxysql_servers 表。

mysql> show create table proxysql_servers\G
*************************** 1. row ***************************
       table: proxysql_servers
Create Table: CREATE TABLE proxysql_servers (
    hostname VARCHAR NOT NULL,
    port INT NOT NULL DEFAULT 6032,
    weight INT CHECK (weight >= 0) NOT NULL DEFAULT 0,
    comment VARCHAR NOT NULL DEFAULT '',
    PRIMARY KEY (hostname, port) )
1 row in set (0.00 sec)

insert into proxysql_servers values('172.16.104.55', 6032, 1, 'proxysql node 1');
insert into proxysql_servers values('172.16.104.56', 6032, 1, 'proxysql node 2');


LOAD PROXYSQL SERVERS TO RUNTIME;
save PROXYSQL SERVERS TO disk;

参考文档

【1】ProxySQL Multi layer configuration system

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

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

相关文章

达梦数据库修改日期时间格式和语言

1、问题 重装了达梦数据库后&#xff0c;通过达梦管理工具查询&#xff0c;表字段timestamp类型变成了中文 对于2023-11-01 01:55:33格式时间插入报错&#xff0c;非法的时间日期类型数据 2、查询配置 通过DM8系统管理员手册查到相关配置 通过命令进行查询显示&#xff0c;语…

《工业微生物》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答 问&#xff1a;《工业微生物》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的第一批认定学术期刊。 问&#xff1a;《工业微生物》级别&#xff1f; 答&#xff1a;国家级。主管单位&#xff1a;中国轻工业联合会 主办单位&#xff…

多个tomcat同时使用 不设置CATALINA_HOME环境变量

通常一台服务器只使用一个tomcat&#xff0c;设置一个CATALINA_HOME的环境变量。但有些时候需要一台服务器启动多个tomcat&#xff0c;那就不能设置CATALINA_HOME了&#xff01;因为会串~ 我们可以在对应tomcat的startup.bat启动脚本中&#xff0c;加入对应的CATALINA_HOME。 …

南京林业大学点云相关团队论文

【1】Chen Dong, Wan Lincheng, Hu Fan, Li Jing, Chen Yanming, Shen Yueqian*, Peethambaran Jiju, 2024. Semantic-aware room-level indoor modeling from point clouds, International Journal of Applied Earth Observation and Geoinformation, 2024, 127, 103685. 语义…

Python入门 2024/7/2

目录 格式化的精度控制 字符串格式化 对表达式进行格式化 小练习&#xff08;股票计算小程序&#xff09; 数据输入 布尔类型和比较运算符 if语句 小练习&#xff08;成人判断&#xff09; if-else语句 if-elif-else语句 练习&#xff1a;猜猜心里数字 嵌套语句 猜…

TransMIL:基于Transformer的多实例学习

MIL是弱监督分类问题的有力工具。然而&#xff0c;目前的MIL方法通常基于iid假设&#xff0c;忽略了不同实例之间的相关性。为了解决这个问题&#xff0c;作者提出了一个新的框架&#xff0c;称为相关性MIL&#xff0c;并提供了收敛性的证明。基于此框架&#xff0c;还设计了一…

imagesc函数 纵坐标翻转 colormap “set” “jet“

纵坐标默认上小下大 翻转&#xff1a; 在Matlab中&#xff0c;使用imagesc函数绘制的图像的纵坐标默认是从上到下递增的&#xff0c;即下面的值较大&#xff0c;上面的值较小。如果想要翻转纵坐标&#xff0c;使之从上到下递增&#xff0c;可以通过设置坐标轴的YDir属性为’n…

【Python机器学习】模型评估与改进——带交叉验证的网格搜索

虽然将数据划分为训练集、验证集、测试集的方法是可行的&#xff0c;也相对常用&#xff0c;但这种方法对数据的划分相当敏感&#xff0c;为了得到对泛化性能的更好估计&#xff0c;我们可以使用交叉验证来评估每种参数组合的性能&#xff0c;而不是仅将数据单次划分为训练集与…

Git入门 本地仓库 远端仓库 多分支

Git入门 Git入门本地git初始化git仓库初始化 创建远端仓库githubgitee 指定远端仓库推送至远端多分支将feature分支合并至dev分支 其他开发者 Git入门 本地git初始化 git仓库初始化 mkdir myrepo # 创建仓库文件夹 cd myrepo/ # 进入目录 git init # 初始化git仓库 (创建.g…

BMA456 运动传感器

型号简介 BMA456是博世&#xff08;bosch-sensortec&#xff09;的一款超小型、三轴、低重力高性能加速度传感器&#xff0c;配备数字接口。该传感器适用于低功耗且要求严格的消费电子应用。它可以检测手腕倾斜、按压/双击&#xff0c;并支持即插即用计步功能&#xff0c;尤其适…

让新质生产力照进现实,智慧数据基础设施需要软硬兼施

数智化时代&#xff0c;什么才是企业与组织最大的差异化竞争力&#xff1f; 答案无疑是&#xff1a;数据。在生成式AI技术日新月异之际&#xff0c;发展新质生产力已成为产业共识&#xff0c;越来越多的企业意识到&#xff1a;数据乃一切运作的基础&#xff0c;是企业拥抱AI浪…

【信息系统项目管理师】18年~23年案例概念型知识

文章目录 18上18下19上19下20上20下21上21下22年上22年下23年上 18上 请简述 ISO 9000 质量管理的原则 领导作用、 过程方法、 管理的系统方法、 与供方互利的关系、 基于事实的决策方法、 持续改进、 全员参与、 以顾客为关注焦点 概念 国家标准(GB/T 1 9000 2008)对质量的定…

Thinking--Promise解决动态挂载静态资源重复问题

Thinking系列&#xff0c;旨在利用10分钟的时间传达一种可落地的编程思想。 #mermaid-svg-MQ0o4hbZOvkQJra0 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-MQ0o4hbZOvkQJra0 .error-icon{fill:#552222;}#mermaid-s…

嵌入式Linux系统编程 — 6.3 kill、raise、alarm、pause函数向进程发送信号

目录 1 kill函数 1.1 kill函数介绍 1.2 示例程序 2 raise函数 2.1 raise函数介绍 2.2 示例程序 3 alarm函数 3.1 alarm函数介绍 3.2 示例程序 4 pause函数 4.1 pause函数介绍 4.2 示例程序 与 kill 命令相类似&#xff0c; Linux 系统提供了 kill()系统调用&#…

仿全民飞机大战射击网页游戏源码

仿全民飞机大战设计网页游戏源码&#xff0c;画质精美的飞机大战手机端游戏源码 微信扫一扫免费下载源码

搞管理千万别犯这3大禁忌,否则活该你当不了领导,切忌!

搞管理千万别犯这3大禁忌&#xff0c;否则活该你当不了领导&#xff0c;切忌&#xff01; 禁忌一&#xff1a;不懂放权 美国总统罗斯福曾说过&#xff1a;“一个最好的管理者&#xff0c;很擅长知人善任。当下属在从事其职务时&#xff0c;管理者要懂得约束自己&#xff0c;不…

MyBatis入门案例

实施前的准备工作&#xff1a; 1.准备数据库表2.创建一个新的springboot工程&#xff0c;选择引入对应的起步依赖&#xff08;mybatis、mysql驱动、lombok&#xff09;3.在application.properties文件中引入数据库连接信息4.创建对应的实体类Emp&#xff08;实体类属性采用驼峰…

一文揭秘:CRM如何助力家居建材企业可持续发展?

01、家居建材行业业务高速发展&#xff0c;对数字化转型提出越来越高诉求 家居建材行业是国民经济的重要基础产业&#xff0c;是改善人居条件、治理生态环境和发展循环经济的重要支撑。家居建材是土木工程和建筑工程中使用材料的统称&#xff0c;包括天花板、瓷砖、门、窗、锁…

VGPU的使用

&#xff08;作者&#xff1a;陈玓玏&#xff09; 开源项目&#xff0c;欢迎star哦&#xff0c;https://github.com/data-infra/cube-studio 训练AI模型以及部署模型推理服务时&#xff0c;GPU往往是必不可少的&#xff0c;但当我们机器上没有足够的GPU卡可使用时&#xf…

如何选择品牌推广公司?哪家好?收费标准及评价!

不管是什么品牌&#xff0c;推广对公司的成败起了很关键的作用。然而&#xff0c;面对市面上琳琅满目的品牌推广公司&#xff0c;如何选择一家既熟悉又靠谱的公司&#xff0c;成为许多企业主面临的难题。 作为一家手工酸奶品牌的创始人&#xff0c;目前全国也复制了100多家门店…