天天看點

ProxySQL實作Doris FE高可用

ProxySQL是靈活強大的MySQL代理層, 是一個能實實在在用在生産環境的MySQL中間件,可以實作讀寫分離,支援 Query 路由功能,支援動态指定某個 SQL 進行 cache,支援動态加載配置、故障切換和一些 SQL的過濾功能。

ProxySQL的優缺點,這裡我就不說了,我隻介紹怎麼安裝使用

ProxySQL安裝(yum方式)

[[email protected] ~]# 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
 
執行安裝
[[email protected] ~]# yum clean all
[[email protected] ~]# yum makecache
[[email protected] ~]# yum -y install proxysql
  
[[email protected] ~]# proxysql --version
ProxySQL version 1.4.13-15-g69d4207, codename Truls
設定開機自啟動
[[email protected] ~]# systemctl enable proxysql
[[email protected] ~]# systemctl start proxysql      
[[email protected] ~]# systemctl status proxysql
啟動後會監聽兩個端口,
預設為6032和6033。6032端口是ProxySQL的管理端口,6033是ProxySQL對外提供服務的端口 (即連接配接到轉發後端的真正資料庫的轉發端口)。
[[email protected] ~]# 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相關路由規則等,則就會被抹掉)

[[email protected] ~]# 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管理端口
[[email protected] ~]# 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表示讀組,我們這裡不需要讀寫分許,無所謂随便設定哪一個都可以,後面我會講出現的問題及解決辦法。
  
[[email protected] ~]# 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主資料庫節點行執行:
[[email protected] ~]# mysql -P9030 -uroot -p 
mysql> create user monitor@'192.168.9.%' identified by '[email protected]!';
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代理層節點上配置監控
[[email protected] ~]# 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='[email protected]!';
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主資料庫節點上執行:[[email protected] ~]# mysql -P9030 -uroot -p
.........
root使用者已經存在,我們直接建立doris使用者
mysql> create user doris@'%' identified by '[email protected]!';
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','[email protected]!',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: [email protected]!
                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連接配接的,連接配接的是轉發到後端真正的資料庫!

[[email protected] ~]#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)
​
然後我們在重新試一下,顯示成功
[[email protected] ~]# mysql -udoris [email protected]! -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''

繼續閱讀