乐趣区

关于负载均衡:ProxySQL实现Apache-doris-FE负载均衡

概述

ProxySQL 是灵便弱小的 MySQL 代理层, 是一个能实实在在用在生产环境的 MySQL 中间件,能够实现读写拆散,反对 Query 路由性能,反对动静指定某个 SQL 进行 cache,反对动静加载配置、故障切换和一些 SQL 的过滤性能。

ProxySQL 的优缺点,这里我就不说了,我只介绍怎么装置应用

ProxySQL 装置(yum 形式)

[root@mysql-proxy ~]# vim /etc/yum.repos.d/proxysql.repo
[proxysql_repo]
name= ProxySQL YUM repository
baseurl=http://repo.proxysql.com/ProxySQL/proxysql-1.4.x/centos/\$releasever
gpgcheck=1
gpgkey=http://repo.proxysql.com/ProxySQL/repo_pub_key
 
执行装置
[root@mysql-proxy ~]# yum clean all
[root@mysql-proxy ~]# yum makecache
[root@mysql-proxy ~]# yum -y install proxysql
  
[root@mysql-proxy ~]# proxysql --version
ProxySQL version 1.4.13-15-g69d4207, codename Truls
设置开机自启动
[root@mysql-proxy ~]# systemctl enable proxysql
[root@mysql-proxy ~]# systemctl start proxysql      
[root@mysql-proxy ~]# systemctl status proxysql
启动后会监听两个端口,默认为 6032 和 6033。6032 端口是 ProxySQL 的治理端口,6033 是 ProxySQL 对外提供服务的端口 (即连贯到转发后端的真正数据库的转发端口)。[root@mysql-proxy ~]# netstat -tunlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name  
tcp        0      0 0.0.0.0:6032            0.0.0.0:*               LISTEN      23940/proxysql    
tcp        0      0 0.0.0.0:6033            0.0.0.0:*               LISTEN

ProxySQL 配置

ProxySQL 有配置文件 /etc/proxysql.cnf 和配置数据库文件 /var/lib/proxysql/proxysql.db。这里须要特地留神:如果存在如果存在 ”proxysql.db” 文件(在 /var/lib/proxysql 目录下),则 ProxySQL 服务只有在第一次启动时才会去读取 proxysql.cnf 文件并解析;前面启动会就不会读取 proxysql.cnf 文件了!如果想要让 proxysql.cnf 文件里的配置在重启 proxysql 服务后失效(即想要让 proxysql 重启时读取并解析 proxysql.cnf 配置文件),则须要先删除 /var/lib/proxysql/proxysql.db 数据库文件,而后再重启 proxysql 服务。这样就相当于初始化启动 proxysql 服务了,会再次生产一个污浊的 proxysql.db 数据库文件(如果之前配置了 proxysql 相干路由规定等,则就会被抹掉)

[root@mysql-proxy ~]# egrep -v "^#|^$" /etc/proxysql.cnf
datadir="/var/lib/proxysql"                                   #数据目录
admin_variables=
{
        admin_credentials="admin:admin"  #连贯治理端的用户名与明码
        mysql_ifaces="0.0.0.0:6032"    #治理端口,用来连贯 proxysql 的治理数据库
}
mysql_variables=
{
        threads=4                                             #指定转发端口开启的线程数量
        max_connections=2048
        default_query_delay=0
        default_query_timeout=36000000
        have_compress=true
        poll_timeout=2000
        interfaces="0.0.0.0:6033"       #指定转发端口,用于连贯后端 mysql 数据库的,相当于代理作用
        default_schema="information_schema"
        stacksize=1048576
        server_version="5.5.30"                               #指定后端 mysql 的版本
        connect_timeout_server=3000
        monitor_username="monitor"
        monitor_password="monitor"
        monitor_history=600000
        monitor_connect_interval=60000
        monitor_ping_interval=10000
        monitor_read_only_interval=1500
        monitor_read_only_timeout=500
        ping_interval_server_msec=120000
        ping_timeout_server=500
        commands_stats=true
        sessions_sort=true
        connect_retries_on_failure=10
}
mysql_servers =
(
)
mysql_users:
(
)
mysql_query_rules:
(
)
scheduler=
(
)
mysql_replication_hostgroups=
()

连贯 ProxySQL 治理端口

[root@mysql-proxy ~]# mysql -uadmin -padmin -P6032 -hdoris01
查看 main 库(默认登陆后即在此库)的 global_variables 表信息
MySQL [(none)]> show databases;
+-----+---------------+-------------------------------------+
| seq | name          | file                                |
+-----+---------------+-------------------------------------+
| 0   | main          |                                     |
| 2   | disk          | /var/lib/proxysql/proxysql.db       |
| 3   | stats         |                                     |
| 4   | monitor       |                                     |
| 5   | stats_history | /var/lib/proxysql/proxysql_stats.db |
+-----+---------------+-------------------------------------+
5 rows in set (0.000 sec)
MySQL [(none)]> use main;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
 
Database changed
MySQL [main]> show tables;
+--------------------------------------------+
| tables                                     |
+--------------------------------------------+
| global_variables                           |
| mysql_collations                           |
| mysql_group_replication_hostgroups         |
| mysql_query_rules                          |
| mysql_query_rules_fast_routing             |
| mysql_replication_hostgroups               |
| mysql_servers                              |
| mysql_users                                |
| proxysql_servers                           |
| runtime_checksums_values                   |
| runtime_global_variables                   |
| runtime_mysql_group_replication_hostgroups |
| runtime_mysql_query_rules                  |
| runtime_mysql_query_rules_fast_routing     |
| runtime_mysql_replication_hostgroups       |
| runtime_mysql_servers                      |
| runtime_mysql_users                        |
| runtime_proxysql_servers                   |
| runtime_scheduler                          |
| scheduler                                  |
+--------------------------------------------+
20 rows in set (0.000 sec)

这些表的含意及作用大家能够在网上搜寻

ProxySQL 配置后端 Doris FE

应用 insert 语句增加主机到 mysql_servers 表中,其中:hostgroup_id 为 10 示意写组,为 20 示意读组,咱们这里不须要读写分许,无所谓轻易设置哪一个都能够,前面我会讲呈现的问题及解决办法。

  
[root@mysql-proxy ~]# mysql -uadmin -padmin -P6032 -h127.0.0.1
............
MySQL [(none)]> insert into mysql_servers(hostgroup_id,hostname,port) values(10,'192.168.9.211',9030);
Query OK, 1 row affected (0.000 sec)
  
MySQL [(none)]> insert into mysql_servers(hostgroup_id,hostname,port) values(10,'192.168.9.212',9030);
Query OK, 1 row affected (0.000 sec)
  
MySQL [(none)]> insert into mysql_servers(hostgroup_id,hostname,port) values(10,'192.168.9.213',9030);
Query OK, 1 row affected (0.000 sec)
 
如果在插入过程中,呈现报错:ERROR 1045 (#2800): UNIQUE constraint failed: mysql_servers.hostgroup_id, mysql_servers.hostname, mysql_servers.port
 
阐明可能之前就曾经定义了其余配置,能够清空这张表 或者 删除对应 host 的配置
MySQL [(none)]> select * from mysql_servers;
MySQL [(none)]> delete from mysql_servers;
Query OK, 6 rows affected (0.000 sec)
​
查看这 3 个节点是否插入胜利,以及它们的状态。MySQL [(none)]> select * from mysql_servers\G;
*************************** 1. row ***************************
       hostgroup_id: 10
           hostname: 192.168.9.211
               port: 9030
             status: ONLINE
             weight: 1
        compression: 0
    max_connections: 1000
max_replication_lag: 0
            use_ssl: 0
     max_latency_ms: 0
            comment:
*************************** 2. row ***************************
       hostgroup_id: 10
           hostname: 192.168.9.212
               port: 9030
             status: ONLINE
             weight: 1
        compression: 0
    max_connections: 1000
max_replication_lag: 0
            use_ssl: 0
     max_latency_ms: 0
            comment:
*************************** 3. row ***************************
       hostgroup_id: 10
           hostname: 192.168.9.213
               port: 9030
             status: ONLINE
             weight: 1
        compression: 0
    max_connections: 1000
max_replication_lag: 0
            use_ssl: 0
     max_latency_ms: 0
            comment:
6 rows in set (0.000 sec)
  
ERROR: No query specified
  
如上批改后,加载到 RUNTIME,并保留到 disk
MySQL [(none)]> load mysql servers to runtime;
Query OK, 0 rows affected (0.006 sec)
  
MySQL [(none)]> save mysql servers to disk;
Query OK, 0 rows affected (0.348 sec)

监控后端 doris 节点

添 doris fe 节点之后,还须要监控这些后端节点。对于后端多个 FE 高可用负载平衡环境来说,这是必须的,因为 ProxySQL 须要通过每个节点的 read_only 值来主动调整

它们是属于读组还是写组。

首先在后端 master 主数据节点上创立一个用于监控的用户名

在 doris fe master 主数据库节点行执行:

[root@doris01 ~]# mysql -P9030 -uroot -p 
mysql> create user monitor@'192.168.9.%' identified by 'P@ssword1!';
Query OK, 0 rows affected (0.03 sec)
mysql> grant ADMIN_PRIV on *.* to monitor@'192.168.9.%';
Query OK, 0 rows affected (0.02 sec)
 
而后回到 mysql-proxy 代理层节点上配置监控
[root@mysql-proxy ~]# mysql -uadmin -padmin -P6032 -h127.0.0.1
MySQL [(none)]> set mysql-monitor_username='monitor';
Query OK, 1 row affected (0.000 sec)
 
MySQL [(none)]> set mysql-monitor_password='P@ssword1!';
Query OK, 1 row affected (0.000 sec)
 
批改后,加载到 RUNTIME,并保留到 disk
MySQL [(none)]> load mysql variables to runtime;
Query OK, 0 rows affected (0.001 sec)
 
MySQL [(none)]> save mysql variables to disk;
Query OK, 94 rows affected (0.079 sec)

验证监控后果:ProxySQL 监控模块的指标都保留在 monitor 库的 log 表中。
以下是连贯是否失常的监控 (对 connect 指标的监控):
留神:可能会有很多 connect_error,这是因为没有配置监控信息时的谬误,配置后如果 connect_error 的后果为 NULL 则示意失常。

MySQL [(none)]> select * from mysql_server_connect_log;
+---------------+------+------------------+-------------------------+---------------+
| hostname      | port | time_start_us    | connect_success_time_us | connect_error |
+---------------+------+------------------+-------------------------+---------------+
| 192.168.9.211 | 9030 | 1548665195883957 | 762                     | NULL          |
| 192.168.9.212 | 9030 | 1548665195894099 | 399                     | NULL          |
| 192.168.9.213 | 9030 | 1548665195904266 | 483                     | NULL          |
| 192.168.9.211 | 9030 | 1548665255883715 | 824                     | NULL          |
| 192.168.9.212 | 9030 | 1548665255893942 | 656                     | NULL          |
| 192.168.9.211 | 9030 | 1548665495884125 | 615                     | NULL          |
| 192.168.9.212 | 9030  | 1548665495894254 | 441                     | NULL          |
| 192.168.9.213 | 9030 | 1548665495904479 | 638                     | NULL          |
| 192.168.9.211 | 9030 | 1548665512917846 | 487                     | NULL          |
| 192.168.9.212 | 9030 | 1548665512928071 | 994                     | NULL          |
| 192.168.9.213 | 9030 | 1548665512938268 | 613                     | NULL          |
+---------------+------+------------------+-------------------------+---------------+
20 rows in set (0.000 sec)
以下是对心跳信息的监控(对 ping 指标的监控)
MySQL [(none)]> select * from mysql_server_ping_log;
+---------------+------+------------------+----------------------+------------+
| hostname      | port | time_start_us    | ping_success_time_us | ping_error |
+---------------+------+------------------+----------------------+------------+
| 192.168.9.211 | 9030 | 1548665195883407 | 98                   | NULL       |
| 192.168.9.212 | 9030 | 1548665195885128 | 119                  | NULL       |
...........
| 192.168.9.213 | 9030 | 1548665415889362 | 106                  | NULL       |
| 192.168.9.213 | 9030 | 1548665562898295 | 97                   | NULL       |
+---------------+------+------------------+----------------------+------------+
110 rows in set (0.001 sec)
 
read_only 日志此时也为空(失常来说,新环境配置时,这个只读日志是为空的)
MySQL [(none)]> select * from mysql_server_read_only_log;
Empty set (0.000 sec)
​
3 个节点都在 hostgroup_id=10 的组中。当初,将方才 mysql_replication_hostgroups 表的批改加载到 RUNTIME 失效。MySQL [(none)]> load mysql servers to runtime;
Query OK, 0 rows affected (0.003 sec)
 
MySQL [(none)]> save mysql servers to disk;
Query OK, 0 rows affected (0.361 sec)
​
当初看后果
MySQL [(none)]> select hostgroup_id,hostname,port,status,weight from mysql_servers;
+--------------+---------------+------+--------+--------+
| hostgroup_id | hostname      | port | status | weight |
+--------------+---------------+------+--------+--------+
| 10           | 192.168.9.211 | 9030 | ONLINE | 1      |
| 20           | 192.168.9.212 | 9030 | ONLINE | 1      |
| 20           | 192.168.9.213 | 9030 | ONLINE | 1      |
+--------------+---------------+------+--------+--------+
3 rows in set (0.000 sec)

配置 mysql_users

下面的所有配置都是对于后端 MySQL 节点的,当初能够配置对于 SQL 语句的,包含:发送 SQL 语句的用户、SQL 语句的路由规定、SQL 查问的缓存、SQL 语句的重写等等。本大节是 SQL 申请所应用的用户配置,例如 root 用户。这要求咱们须要先在后端 Doris FE 节点增加好相干用户。这里以 root 和 doris 两个用户名为例.

首先,在 Doris FE master 主数据库节点上执行:

[root@doris01 ~]# mysql -P9030 -uroot -p
.........
root 用户曾经存在,咱们间接创立 doris 用户
mysql> create user doris@'%' identified by 'P@ssword1!';
Query OK, 0 rows affected, 1 warning (0.04 sec)
 
mysql> grant ADMIN_PRIV on *.* to doris@'%';
Query OK, 0 rows affected, 1 warning (0.03 sec)
 
 
而后回到 mysql-proxy 代理层节点,配置 mysql_users 表,将方才的两个用户增加到该表中。admin> insert into mysql_users(username,password,default_hostgroup) values('root','',10);
Query OK, 1 row affected (0.001 sec)
  
admin> insert into mysql_users(username,password,default_hostgroup) values('doris','P@ssword1!',10);
Query OK, 1 row affected (0.000 sec)
  
admin> load mysql users to runtime;
Query OK, 0 rows affected (0.001 sec)
  
admin> save mysql users to disk;
Query OK, 0 rows affected (0.108 sec)

mysql_users 表有不少字段,最次要的三个字段为 username、password 和 default_hostgroup:

  • username:前端连贯 ProxySQL,以及 ProxySQL 将 SQL 语句路由给 MySQL 所应用的用户名。
  • password:用户名对应的明码。能够是明文明码,也能够是 hash 明码。如果想应用 hash 明码,能够先在某个 MySQL 节点上执行
    select password(PASSWORD),而后将加密后果复制到该字段。
  • default_hostgroup:该用户名默认的路由指标。例如,指定 root 用户的该字段值为 10 时,则应用 root 用户发送的 SQL 语句默认
    状况下将路由到 hostgroup_id=10 组中的某个节点。
 
admin> select * from mysql_users\G
*************************** 1. row ***************************
              username: root
              password: 
                active: 1
               use_ssl: 0
     default_hostgroup: 10
        default_schema: NULL
         schema_locked: 0
transaction_persistent: 1
          fast_forward: 0
               backend: 1
              frontend: 1
       max_connections: 10000
*************************** 2. row ***************************
              username: doris
              password: P@ssword1!
                active: 1
               use_ssl: 0
     default_hostgroup: 10
        default_schema: NULL
         schema_locked: 0
transaction_persistent: 1
          fast_forward: 0
               backend: 1
              frontend: 1
       max_connections: 10000
2 rows in set (0.000 sec)

尽管这里没有具体介绍 mysql_users 表,但下面标注了 ” 留神本行 ” 的两个字段必须要引起留神。只有 active= 1 的用户才是无效的用户。
至于 transaction_persistent 字段,当它的值为 1 时,示意事务长久化:当某连贯应用该用户开启了一个事务后,那么在事务提交 / 回滚之前,
所有的语句都路由到同一个组中,防止语句扩散到不同组。在以前的版本中,默认值为 0,不晓得从哪个版本开始,它的默认值为 1。
咱们冀望的值为 1,所以在持续上面的步骤之前,先查看下这个值,如果为 0,则执行上面的语句批改为 1。


MySQL [(none)]> update mysql_users set transaction_persistent=1 where username='root';
Query OK, 1 row affected (0.000 sec)
 
MySQL [(none)]> update mysql_users set transaction_persistent=1 where username='sqlsender';
Query OK, 1 row affected (0.000 sec)
 
MySQL [(none)]> load mysql users to runtime;
Query OK, 0 rows affected (0.001 sec)
 
MySQL [(none)]> save mysql users to disk;
Query OK, 0 rows affected (0.123 sec)

这样就能够通过 sql 客户端,应用 doris 的用户名明码去连贯了 ProxySQL 了

通过 ProxySQL 连贯 Doris 测试

上面,别离应用 root 用户和 doris 用户测试下它们是否能路由到默认的 hostgroup_id=10(它是一个写组)读数据。上面是通过转发端口 6033 连贯的,连贯的是转发到后端真正的数据库!


[root@mysql-master ~]#mysql -uroot -p -P6033 -hdoris01 -e "show databases;"
Enter password: 
ERROR 9001 (HY000) at line 1: Max connect timeout reached while reaching hostgroup 10 after 10000ms
这个时候发现出错,并没有转发到后端真正的 doris fe 上
通过日志看到有 set autocommit= 0 这样开启事务
查看配置发现:mysql-forward_autocommit=false
mysql-autocommit_false_is_transaction=false
咱们这里不须要读写拆散,只须要将这两个参数通过上面语句间接搞成 true 就能够了
mysql> UPDATE global_variables SET variable_value='true' WHERE variable_name='mysql-forward_autocommit';
Query OK, 1 row affected (0.00 sec)

mysql> UPDATE global_variables SET variable_value='true' WHERE variable_name='mysql-autocommit_false_is_transaction';
Query OK, 1 row affected (0.01 sec)

mysql>  LOAD MYSQL VARIABLES TO RUNTIME;
Query OK, 0 rows affected (0.00 sec)

mysql> SAVE MYSQL VARIABLES TO DISK;
Query OK, 98 rows affected (0.12 sec)

而后咱们在从新试一下,显示胜利

[root@doris01 ~]# mysql -udoris -pP@ssword1! -P6033 -h192.168.9.211  -e "show databases;"
Warning: Using a password on the command line interface can be insecure.
+--------------------+
| Database           |
+--------------------+
| doris_audit_db     |
| information_schema |
| retail             |
+--------------------+

OK,到此就完结了,你就能够用 Mysql 客户端,JDBC 等任何连贯 mysql 的形式连贯 ProxySQL 去操作你的 doris 了

备注:在应用 jdbc 连接池的时候,mysql 的驱动请应用 8.0.15,我试过好几个版本都会出错,这个版本没有问题,出错信息如下

java.sql.SQLException: Unknown system variable ‘performance_schema”

退出移动版