mysql_proxy工作原理和配置引數
Mysql伺服器和客戶端建立連線過程如下
認證透過,客戶端發起查詢請求,伺服器可能返回3種結果;
圖片來源http://blog.sina.com.cn/s/blog_98cb2d960100zs0e.html
Mysql-proxy作為一個代理,工作於mysql客戶端和伺服器之間(對兩者皆透明);
http://dev.mysql.com/doc/mysql-proxy/en/mysql-proxy-scripting-injection.html
首先MySQL Proxy以伺服器的身份接受客戶端請求,根據配置對這些請求進行分析處理,然後以客戶端的身份轉發給相應的後端資料庫伺服器,再接受伺服器的資訊,返回給客戶端,所以MySQL Proxy需
要同時實現客戶端和伺服器的協議。
由於要對客戶端傳送過來的SQL語句進行分析,還需要包含一個SQL解析器。可以說MySQL Proxy相當於一個輕量級的MySQL了,實際上,MySQL Proxy的admin server是可以接受SQL來查詢狀態資訊的。
MySQL Proxy透過lua指令碼來控制連線轉發,主要的函式都是配合MySQL Protocol各個過程的:
* connect_server() // 接收到Client的連線請求時呼叫
* read_handshake() // 讀取server發起的handshake資訊時呼叫
* read_auth() // 讀取Client的認證資訊時呼叫
* read_auth_result() // 讀取認證結果時呼叫
* read_query() // 讀取Client的query請求時呼叫
* read_query_result() //讀取query結果時呼叫
具體功能:
1.資料連線的故障轉移
2.資料連線的負載均衡
3.攔截查詢(取通訊包,實現關鍵字替換)
4.重寫查詢(例如,強制密碼度等規則)
5.新增額外的查詢(附)
6.刪除,修改或者新增返回到客戶端的 SQL結果集
配置檔案
mysql-proxy.cnf(許可權設為660)
[mysql-proxy]
admin-username=root
admin-password=123456
admin-lua-script=/usr/local/lib/admin.lua
proxy-read-only-backend-addresses=192.168.2.115
proxy-backend-addresses=192.168.2.117
proxy-lua-script=/usr/local/lib/rw-splitting.lua
log-file=/var/log/mysql-proxy.log
log-level=debug
daemon=true
keepalive=true
proxy-lua-script,指定一個Lua指令碼來控制mysql-proxy的執行和設定,這個指令碼在每次新建連線和指令碼發生修改的的時候將重新呼叫
keepalive,額外建立一個程式專門監控mysql_proxy程式,當mysql_proxy crash予以重新啟動;
啟動
/usr/local/mysql-proxy/bin/mysql-proxy -P 192.168.2.112:3306 --defaults-file=/etc/mysql-proxy.cnf
讀寫分離
當proxy-lua-script指定為rw-splitting.lua時,mysql_proxy會對客戶端傳入的sql執行讀寫分離;
同一個事務,DML傳輸給backend,select則被傳到read-only-backend;
Lua指令碼預設最小4個最大8個以上的客戶端連線才會實現讀寫分離(這是因為mysql-proxy會檢測客戶端連線, 當連線沒有超過min_idle_connections預設值時,不會進行讀寫分離,即查詢操作會發生到Master上),現改為最小1個最大2個,我們用vim修改/usr/local/lib/rw-splitting.lua指令碼,改動內容如下所示:
if not proxy.global.config.rwsplit then
proxy.global.config.rwsplit = {
min_idle_connections = 1,
max_idle_connections = 2,
is_debug = false
}
end
read_query()函式內有這麼一個判斷
if stmt.token_name == "TK_SQL_SELECT" then
這個語句的作用就是判斷sql語句是不是以SELECT開始的,如果是查詢的話,接下來會有這麼個語句
local backend_ndx = lb.idle_ro()
lb.idle_ro() 是透過 local lb = require("proxy.balance") 引入的balance.lua檔案
這個函式的作用就是選擇使用哪個讀伺服器,並返回伺服器的index:max_conns_ndx
如何選擇伺服器呢? 它透過迴圈遍歷所有伺服器,然後選出一個客戶端連線(s.connected_clients)最少的伺服器,這樣在一定程度上實現負載均衡
function idle_ro()
local max_conns = -1
local max_conns_ndx = 0
for i = 1, #proxy.global.backends do
local s = proxy.global.backends[i]
local conns = s.pool.users[proxy.connection.client.username]
-- pick a slave which has some idling connections
if s.type == proxy.BACKEND_TYPE_RO and s.state ~= proxy.BACKEND_STATE_DOWN and conns.cur_idle_connections > 0 then
if max_conns == -1 or s.connected_clients < max_conns then
max_conns = s.connected_clients
max_conns_ndx = i
end
end
end
return max_conns_ndx
end
http://blog.csdn.net/clh604/article/details/8906022
failover
利用mysql_proxy實現failover
缺點:mysql_proxy單點故障;
原理:預設連線A,如果A宕掉則連線B,A啟動後再連線到A;
編寫failover指令碼
vi $mysql-proxy_path/share/doc/mysql-proxy/mysql_failover.lua
function connect_server()
for i = 1, #proxy.backends do
local s = proxy.backends[i]
print ("s.state:" + s.state)
if s.state ~= proxy.BACKEND_STATE_DOWN then
proxy.connection.backend_ndx = i
print ("connecting to " .. i)
return
end
end
end
function read_query(packet)
for i = 1, #proxy.backends do
local s = proxy.backends[i]
print ("s.state:" + s.state)
if s.state ~= proxy.BACKEND_STATE_DOWN then
proxy.connection.backend_ndx = i
print ("connecting to " .. i)
return
end
end
end
啟動mysql-proxy
$mysql-proxy_path/bin/mysql-proxy --proxy-address=:4040 --proxy-lua-script=$mysql-proxy_path/share/doc/mysql-proxy/mysql_failover.lua --proxy-backend-addresses=$A:3306 --proxy-backend-addresses=$B:3306 --log-level=error --log-file=$mysql-proxy_path/mysql-proxy.log --keepalive --proxy-fix-bug-25371
此時客戶端直接連線mysql-proxy即可;
http://www.cnblogs.com/lenolix/archive/2013/04/06/3003226.html
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15480802/viewspace-1432659/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Nginx的工作原理和配置詳解Nginx
- 【MySQL】SemisynchronousReplication配置和引數說明MySql
- 常用的jvm配置引數 :永久區引數配置JVM
- 【MySQL】Semisynchronous Replication 配置和引數說明MySql
- HACMP配置引數和常用命令ACM
- Redis 主從配置和引數詳解Redis
- 引數session_cached_cursors的工作原理及優缺點分析Session
- jvm引數配置JVM
- oracle引數配置Oracle
- JavaWeb引數配置JavaWeb
- kettle 引數——變數引數和常量引數變數
- Ceph配置引數分析
- Oracle rman 配置引數Oracle
- ORACLE 配置event引數Oracle
- mosquitto 引數配置UI
- 配置網路引數
- Nginx的gzip壓縮的原理和設定引數Nginx
- nginx 常見引數以及重定向引數配置Nginx
- ORACLE RAC GUARD配置引數——RAC GUARD概念和管理Oracle
- 【調優篇基本原理】優化器相關引數配置優化
- 引數和變數變數
- hadoop YARN配置引數剖析—MapReduce相關引數HadoopYarn
- Hystrix 配置引數全解析
- Laravel 配置郵箱引數Laravel
- APM Java agent 引數配置Java
- Elasticsearch 引數配置說明Elasticsearch
- SAP配置系統引數
- kafka 引數配置說明Kafka
- DataGuard引數配置詳解
- struts配置引數詳解
- AIX 系統引數配置AI
- MySQL引數配置優化MySql優化
- tomcat jvm 引數配置TomcatJVM
- docker 配置引數參考Docker
- JavaScript形式引數和實際引數JavaScript
- tcprstat和tcpstat工作原理TCP
- SAP Spartacus 預設路由配置的工作原理路由
- Bash變數和引數變數