Proxysql讀寫分離配置


GitHub地址:https://github.com/sysown/proxysql

官網地址:https://www.proxysql.com/

Percona主推的讀寫分離中間件,下載地址:

https://www.percona.com/downloads/proxysql/

一、安裝

1:下載
wget https://www.percona.com/downloads/proxysql/proxysql-1.4.5/binary/redhat/6/x86_64/proxysql-1.4.5-1.1.el6.x86_64.rpm
2:安裝
rpm -ivh proxysql-1.4.5-1.1.el6.x86_64.rpm
3:啟動
service proxysql start/stop/status

二、配置

登錄Proxysql管理和監控界面(也是使用Mysql協議,端口是6032,不加-h在某些環境下會自動使用本地sock連到3306的mysql端口,所以建議要加上-h參數)

mysql -uadmin -padmin -P6032 -h127.0.0.1

6032為管理和監控端口,6033為對外提供數據庫服務的端口,admin/amin為默認的管理監控的賬號密碼(只能本地登錄),可以在proxysql.conf文件的admin_variables找到。

main
    是默認的數據庫名,表里存放backend的mysql server、mysql user、路由規則等信息。表名以runtime_開頭的表示proxysql當前運行的配置內容,是不能通過dml語句修改的,可以通過修改對應的不以runtime_ 開頭的里的表(in-memory表),然后load xxx to runtime使其生效,記得最后使用save相關的命令將其存入disk庫。
    需要注意的是main庫中的表全是內存表,你可以通過修改那些不以runtime_ 開頭的里的表來進行配置的熱更新,但是需要load to runtime才能生效,通過runtime_表查看生效后的值,此外如果這些更新未被save到disk庫,那么proxysql重啟后這些更新會全部丟失。
disk
    是持久化到硬盤的配置,sqlite數據文件。你可以看到這里的表名和main庫中的不以runtime_ 開頭的里的表名一樣,是的,這些就是main庫里那些內存表的持久化映射表,proxysql啟動時是從這里讀取配置的。
stats
    proxysql運行抓取的統計信息,包括到后端各命令的執行次數、流量、processlist、查詢種類匯總/執行時間,等等。
monitor 
    存儲 monitor 模塊收集的信息,主要記錄針對后端db的connect log,ping和slave delay
main庫中的表信息:

可以通過查看global_variables表來獲取proxysql的各種參數,在其中你可以找到其默認自帶的2個管理用戶admin、stats,其默認db schema分別為main、stats,這兩個用戶一個可以用於進行proxysql一個可以用於觀察stats,這倆賬戶唯一的區別就是admin權限大,stats權限小點,兩者都只能本地登錄。

此外還需要再定義一個監控賬號,因為默認的admin和stats管理賬號都是屬於proxysql的不能用於后端mysql連接,我們需要一個賬號用於ping后端的mysql以及檢測mysql主從延遲。

這個監控賬號雖然是在后端數據庫真實存在的(既可以通過6033端口連接),但其實他是個管理賬號,所以他很特殊,因為它既可以通過6032端口連到proxysql的管理界面,也可以通過6033端口連到后端的mysql業務庫。平時我們既不會用他連6032(因為有stats管理賬戶)也不會用他連mysql業務庫(權限受限)。但是如果你不想從本地登錄還想查看proxysql的統計信息,那么可以使用此賬戶遠程連接到6032的管理端口,此賬戶的管理權限等同於stats賬戶。

# 首先后端mysql主庫添加賬戶:
mysql> GRANT SUPER,REPLICATION CLIENT ON *.* TO 'proxysql' IDENTIFIED BY 'proxysql';
# 然后設置proxysql對應的管理賬戶:
mysql -uadmin -padmin -h127.0.0.1 -P6032
set mysql-monitor_username='proxysql';
set mysql-monitor_password='proxysql';

關於proxysql配置,最重要的是mysql_servers,mysql_users,mysql_query_rules,其他表很少修改:

這3個最重要的表的內容也可以在/etc/proxysql.conf中修改,但只是第一次初始化時使用,以后的修改和初始化信息都是通過disk庫實現的(存儲在sqllite庫中),目前建議不要對/etc/proxysql.conf和proxysql-admin.conf做任何修改。

  • mysql_servers:
定義所有可用的mysql server,hostgroup_id可以自定義數字,只需將讀和寫的組設為不一樣的hostgroup_id即可。
本例中是在MHA環境下配置的,59、60、61為MHA的3個節點,其中59目前為master,200為MHA的VIP(公共IP)。
在配置完mysql_users后,ProxySQL為每個mysql_servers表中定義的hostname創建一個默認的連接放入連接池中,可以通過查看stats_mysql_connection_pool表獲知。
insert into mysql_servers(hostgroup_id,hostname,port,weight,max_connections,max_replication_lag,comment) 
values(100,'10.0.1.59',3306,1,1000,10,'test my proxysql');
insert into mysql_servers(hostgroup_id,hostname,port,weight,max_connections,max_replication_lag,comment) 
values(100,'10.0.1.60',3306,1,1000,10,'test my proxysql');
insert into mysql_servers(hostgroup_id,hostname,port,weight,max_connections,max_replication_lag,comment) 
values(100,'10.0.1.61',3306,1,1000,10,'test my proxysql');
insert into mysql_servers(hostgroup_id,hostname,port,weight,max_connections,max_replication_lag,comment) 
values(1000,'10.0.1.200',3306,1,1000,10,'test my proxysql');
 這里把MHA的3個節點的IP--59,60,61的hostgroup_id設為100,將MHA的VIP--200的hostgroup_id設置為1000,實現讀寫分離和讀的負載均衡。
  • mysql_users:
定義連接proxysql的數據庫賬戶和密碼。這里的賬戶是不同於你在global_variables看到的admin和stats賬戶的,那是屬於連接6032的管理賬戶。而這里是用於連接6033端口的應用賬戶。
這些user的frontend和backend字段默認都為1,標識了賬戶既是屬於proxysql server的賬戶,也是可以用於連接后端mysql server的賬戶。雖然proxysql文檔說未來版本會把前端賬戶和后端賬戶分隔以便后端賬戶可以完全對proxysql的client們隔離,但目前前后端賬戶還是重合的。
思考一個問題:為何proxysql需要frotend和backend賬戶?
解釋可以再上述鏈接看到,proxysql server其實只是一個轉發mysql請求的代理,如果proxysql直接將請求轉發到后端mysql進行身份驗證,那么當后端mysql節點失敗或者負載過高時連接就可能失敗,而一般讀節點可以有多個,一個拒絕了可以繼續到另一個節點試試啊,所以為了實現簡單的故障轉移和負載均衡,proxysql選擇自己也建立一套身份認證體系,這樣客戶端可以無阻塞的直接與proxysql創建連接,之后proxysql可以在后端節點之間進行負載均衡。
proxysql 6033端口使用與后端mysql相同的認證體系,在mysql_users中新增的賬戶需要在后端mysql中也存在,且密碼要一致。
mysql_users里的賬戶與后端mysql賬戶的區別在於不需要指定權限,只要賬密與后端mysql一樣即可。
insert into mysql_users(username,password,active,default_hostgroup,transaction_persistent)
values('leo','leo',1,1000,1);
# 需要注意的是插入時設置的password是明文密碼,可以使用如下方式加密一下:
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS FROM RUNTIME;
SAVE MYSQL USERS TO DISK;
# 其原理如下:
	參數admin-hash_passwords為true時,密碼在load入runtime時會被自動hash,所以load mysql users to runtime可以實現密碼hash
    save mysql users from runtime等價於save mysql users to mem,意思是main庫的mysql_users表里記載的密碼也更新下
    最后save mysql users to disk是將hash密碼寫入硬盤
default_hostgroup可以設為上邊定義的1000,這樣所有連接到MHA所在服務器的6033端口的客戶端會話都會默認轉發到hostgroup 1000上,但是如果設置了任何mysql_query_rules,那么只要有select操作就會按mysql_query_rules的規則轉發,所以如果你設置了mysql_query_rules,那么select @@hostname;查到的可能不會是hostgroup為1000的節點,因為這也屬於select語句。
本例中hostgroup為1000的是MHA的VIP,proxysql自動連接到MHA的VIP上,即始終默認連接到master庫,執行任何語句都會根據mysql_query_rules的規則轉發。
最后load加載並在sqlite中保存上述各種修改:
load mysql servers to runtime;
load mysql users to runtime;
load mysql variables to runtime;
save mysql servers to disk;
save mysql users to disk;
save mysql variables to disk;
  • mysql_query_rules:
定義讀寫分離規則,可以看到是通過正則實現的,下列定義表示除了select for update,其他的select一律轉發到hostgroup_id為100的虛擬節點上,也就說讀操作負載均衡的分配到59、60、61三個庫上。其他操作使用默認的hostgroup_id為1000的庫,也就是MHA的master庫。
使用proxysql時我們可以先不設置query rules,這樣客戶端依然是對主庫的單點讀寫,之后我們可以慢慢為一些慢查詢設置正則規則導向讀庫們。
關於mysql_query_rules各個字段的解釋參考:https://github.com/sysown/proxysql/wiki/Main-(runtime)#mysql_query_rules
INSERT INTO mysql_query_rules(active,match_pattern,destination_hostgroup,apply) 
VALUES(1,'^SELECT.*FOR UPDATE$',1000,1);
INSERT INTO mysql_query_rules(active,match_pattern,destination_hostgroup,apply) 
VALUES(1,'^SELECT',100,1);
# mysql_query_rules表的主鍵是自增的rule_id,匹配規則的應用順序是按rule_id升序來的,所以可以把精細的匹配規則前置,模糊的匹配規則后置。
# load to runtime生效並在sqlite中保存上述修改。
load mysql query rules to runtime;
save mysql query rules to disk;
 
關於正則匹配規則:
proxysql支持兩種正則匹配規則,由參數mysql-query_processor_regex控制,1.4.0版本之前只有RE2可用(即C++正則匹配規則)。
當前默認的匹配規則為PCRE即perl compatible Regular Expressions.
因此設計正則匹配規則是使用正常的正則表達式即可。
至於匹配規則的一些限制,如大小寫敏感,匹配模式是全局替換還是只替換等首個匹配等等,可以通過mysql_query_rules.re_modifiers字段進行設置,默認的匹配規則是大小寫不敏感的。
如何查看proxysql的統計信息?
在進行一系列增刪改查后,可以通過如下視圖查看統計信息,需要使用監控賬號連接proxysql的6032端口.
本例中連接方式為mysql -ustats -pstats -P6032 -h127.0.0.1 (127.0.0.1為proxsql所在服務器,我這里直接在本地查的)
select * from stats_mysql_query_digest_reset;
# 以上視圖與stats_mysql_query_digest的結構與內容一樣,區別在於查詢以上視圖后統計信息會被清空。
本文使用的proxysql 1.4.5遇到一個BUG,stats.stats_mysql_query_digest無法記錄query信息,相關的參數配置已查證無誤,暫未找到其他原因,建議之后使用更新的版本。
Ps:后經過驗證發現,在proxysql server上通過本地mysql命令行執行的SQL不會記錄入stats_mysql_query_digest表。
最后,Proxysql日志的默認位置為/var/lib/proxysql/proxysql.log.
三、總結
本例使用Proxysql實現了MHA的讀寫分離,把VIP設置為了可讀寫的hostgroup,真實的3台MHA服務器IP設置為了可讀的hostgroup,但是在MHA同步延遲較大時可能出現讀取不到最新數據的情況,需要注意,可以通過設置mysql_servers的max_replication_lag來盡可能避免單個節點的slave delay。
一個需要注意的點:
    很不建議配置mysql_replication_hostgroups表,因為配置此表之后,proxysql會自動檢測mysql_servers里mysql節點的read_only的值,只要read_only=0,此節點就會被加入writer_hostgroup中,否則加入reader_hostgroup,造成的結果就是假如集群重啟之后read_only統一為0,那么這些節點就會全部加入讀組中(mysql_servers里會出現處於不同組但是屬性完全一樣的記錄),造成寫入混亂,除非你能在任意時刻保證read_only參數的正確性


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM