MySQL至TiDB複製延遲監控
因生產環境mysql中有較多複雜sql且執行效率低,因此採用tidb作為生產環境的從庫進行部分慢sql及報表的讀寫分離。其中MySQL至TIDB採用Syncer工具同步。
關於TIDB的安裝及Syncer可參照官網指引進行,搭建的主從複製架構如下:
因該方式中TiDB的資料是通過Syncer同步的,且TIDB無show slave status命令檢視複製情況,故自己開發指令碼對MySQL至TIDB的複製延遲進行監控,並且將結果進行圖形化展示以便於直觀分析,而且此方法也可以監控MySQL主從延遲,類似於percona toolkit的pt-heartbeat 。
一、 準備工作
1. 監控所需工具
監控
圖形化展示:Python plotly、matplotlib或pandas包
2. 監控延遲思路
1)建立監控資料庫(monitor)及相關表(monitor_time,monitor_result)
2)每隔固定時間(看監控精確度,如0.5s)將當期時間或時間戳的結果更新到mysql的監控表中
3)對比mysql與tidb對應的監控庫(monitor庫)中的monitor_time表的時間差,並將結果記錄在monitor_result裡
3. 視覺化展示結果
用Python 的plotly、matplotlib或pandas等展示監控結果
二、延時監控實施步驟
1. 建立資料庫及相關表,並將其加入Syncer同步中
-- 建立監控資料庫monitor; CREATE DATABASE `monitor`; USE `monitor`; -- 建立監控時間表monitor_time; CREATE TABLE `monitor_time` ( `t` bigint(20) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 初始化資料,因後面監控程式定時更新該條記錄 insert into monitor_time select 1; -- 建立監控結果表monitor_result;CREATE TABLE `monitor_result` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `t` int(11) DEFAULT NULL COMMENT '延遲時間', `add_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '監控記錄生成時間', `t_mysql` int(11) DEFAULT NULL COMMENT 'mysql主從延遲時長', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2. 建立監控賬號並授權
單獨建立一個用於監控該延遲的賬號,並新增相應的許可權。
CREATE USER [email protected]'192.168.3.42' IDENTIFIED BY 'monitor'; GRANT SELECT ,INSERT ,UPDATE ON monitor.* TO [email protected]'192.168.3.42';
3. 監控指令碼
每隔0.5s更新一次monitor_time 表,自定義時間(如例子中10s)獲取一次監控結果,並將記錄寫入資料庫中
import os,time import pymysql while True: t = time.time() t1= int(round(t * 1000)) conn = pymysql.connect(host='*.*.*.*',port=3306,user='monitor',passwd='monitor') cur = conn.cursor() sql_update = "update monitor.monitor_time set t="+str(t1) cur.execute(sql_update) conn.commit() conn.close() time.sleep(0.5)
import os,time import pymysql while True: conn_sor = pymysql.connect(host='*.*.*.*',port=3306,user='monitor',passwd='monitor') cur_sor = conn_sor.cursor() conn_138 = pymysql.connect(host='*.*.*.*',port=3306,user='monitor',passwd='monitor') cur_138 = conn_138.cursor() conn_des = pymysql.connect(host='*.*.*.*',port=4000,user='monitor',passwd='monitor') cur_des = conn_des.cursor() sql_get_time = "select t from monitor.monitor_time " cur_sor.execute(sql_get_time) v_src_tuple=cur_sor.fetchone() t_sor=v_src_tuple[0] cur_des.execute(sql_get_time) v_des_tuple=cur_des.fetchone() t_des=v_des_tuple[0] cur_138.execute(sql_get_time) v_138_tuple=cur_138.fetchone() t_138=v_138_tuple[0] t1 = t_sor/1000 - t_des/1000 t2 = t_sor/1000 - t_138/1000 sql_insert = "insert into monitor.monitor_result(t,t_mysql) select "+str(t1)+","+str(t2) cur_sor.execute(sql_insert) conn_sor.commit() conn_sor.close() conn_des.close() time.sleep(10)
將2個指令碼放在監控伺服器上執行
python monitor_tidb.py &
python get_tidb_delay.py &
三 視覺化展示
以下是其中一種實現方式,其他如折線圖方式可執行修改
# __author__ : 'GJC' # __created__ : '2018/9/17' # coding=utf-8 import pymysql import plotly.plotly from plotly.graph_objs import * import plotly.graph_objs as abc import matplotlib.pyplot as plt host = "*.*.*.*" user = "monitor" passwd = "monitor" db = "monitor" port = 3306 charset = "utf8" conn = pymysql.connect( host=host, port=port, user=user, passwd=passwd, db=db, charset=charset, ) cur = conn.cursor() re = cur.execute("SELECT add_time,t,t_mysql FROM monitor.monitor_result_t ") dfs = cur.fetchall() listx = [] listy = [] listy2 = [] for row in dfs: listx.append(row[0]) listy.append(row[1]) listy2.append(row[2]) cur.close() conn.commit() conn.close() length = listy.__len__() data_1 = abc.Scatter( x=listx, y=listy, name='syncer_delay_time_tidb', mode='markers', marker=dict( size=10, color="rgba(255,47,167,.9)", line=dict( width=2, color='rgb(2,2,2)' ) ) ) data_2 = abc.Scatter( x=listx, y=listy2, name='syncer_delay_time_mysql', mode='markers', marker=dict( size=10, color="rgba(255,47,167,.9)", line=dict( width=2, color='rgb(3,3,3)' ) ) ) data1 = Data([data_1]) plotly.offline.plot(data1) data2 = Data([data_2]) plotly.offline.plot(data2)
部分時間段效果如下: