tcpcopy實作新加的從庫資料預熱,這個功能還是比較實用的(booking的2018年DTCC大會上的分享中也提過他們做了這個功能)。尤其是高負載的從庫,如果直接加入一台冷的從節點到叢集,可能造成大量慢查詢出現。
編譯tcpcopy和intercept的過程直接參考github官方即可,需要注意的是要安裝 libpcap-devel 不然無法編譯完成
git clone https://github.com/session-replay-tools/tcpcopy.git
cd tcpcopy
git clone https://github.com/session-replay-tools/mysql-replay-module.git # 安裝這個插件,不然封包轉發到後端需要賬号密碼驗證的MySQL時候時候無法work
./configure --set-protocol-module=mysql-replay-module
make && make install
預設是安裝到 /usr/local/tcpcopy/
vim /usr/local/tcpcopy/conf/plugin.conf 裡面寫上稍後要壓測用的資料庫賬号密碼
user dts@dts;
user archiver@archiver;
git clone https://github.com/session-replay-tools/intercept.git
cd intercept
./configure --with-resp-payload
make && make install
預設是安裝到 /usr/local/intercept/
注意: tcpcopy在雲上環境可能因為雲廠商的限制,導緻其不work。是以我們這裡更主要是針對實體機環境下的實驗。
1、192.168.2.4 online server 生産環境 mysql從庫,部署 tcpcopy程式,負責捕獲線上請求
2、192.168.2.162 assistant server 輔助機器, 部署有 intercept,負責向tcpcopy發送響應資訊
3、192.168.2.164 target server 目标機器,待新加入的從庫
4、192.168.1.40 發起壓測的機器,部署有mysql用戶端或者sysbench之類工具即可
大緻結構如下:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsATOfd3bkFGazxCMx8VesATMfhHLlN3XnxCMwEzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SN4cjNzIzM3YzN0IzM5UTMvw1NyYDMwIDMy8CXzV2Zh1WavwVbvNmLvR3YxUjL0M3Lc9CX6MHc0RHaiojIsJye.png)
tcpcopy拷貝一次流量通路的步驟如下:
① 一個客戶請求到達線上機器;
② 拷貝IP層(或者資料鍊路層)的包到tcpcopy程序;
③ tcpcopy修改包的目的及源位址,發給目标測試機;
④ 拷貝的包到達目标測試機;
⑤ 目标測試機的應用處理通路,并傳回結果給輔助機;
⑥ 傳回結果在輔助機的資料鍊路層被截獲,drop響應的body,copy傳回的ip header;
⑦ 輔助機将響應header發送給線上機器的tcpcopy程序。
注意: 在做tcpcopy實驗的時候,需要確定這幾台主機是關閉 ip_forward的。操作方法:echo 0 > /proc/sys/net/ipv4/ip_forward
下面開始實時複制流量實驗部分(流量錄制的用的比較少,這裡就不寫了)
1. 目标機器 192.168.2.164 上配置路由 ,将響應包路由到輔助機 192.168.2.162
route add -net 192.168.0.0 netmask 255.255.0.0 gw 192.168.2.162 dev ens32
其中 192.168.2.162 為輔助機, 192.168.0.0 為發壓用戶端所在的網段
2. 輔助機 192.168.2.162 捕獲目标機器發來的響應包 (和抓包指令類似)
格式:
./intercept -F <filter> -i <device,>
例子:
cd /usr/local/tcpcopy/sbin/
./intercept -i ens32 -F 'tcp and src port 3306' # 前台啟動,需要放到背景的話,加上 -d 選項即可
含義:捕獲網卡 ens32 ,端口 3306 基于tcp的包
3. 線上機器 192.168.2.4 上捕獲包,并修改用戶端位址,并把包發送給目标機器,等待輔助機發送響應包
格式:
./tcpcopy -x localServerPort-targetServerIP:targetServerPort -s <intercept server,> [-c <ip range,>]
例子:
cd /usr/local/tcpcopy/sbin/
./tcpcopy -x 3306-192.168.2.164:3306 -s 192.168.2.162 -c 192.168.0.0 #全流量複制,如果背景運作需要加 -d選項即可
其它:
./tcpcopy -x 80-3.3.3.3:8080 -s 2.2.2.2 -c 1.1.1.0 -r 20 -d #複制20%的流量
./tcpcopy -x 80-3.3.3.3:8080 -s 2.2.2.2 -c 1.1.1.0 -n 2 -d #複制2倍流量
4、壓測結果,我這裡就不貼了。感興趣的,可以開mysql的general_log,看執行個體的網卡流量、errlog,都可以看到有用的資訊。
5、預熱完成後,記得删除之前加的路由:
route del -net 192.168.0.0 netmask 255.255.0.0
下圖,是生産上可以參考用的方案:
參考:
https://www.jianshu.com/p/e34086c47493
https://blog.csdn.net/github_39037504/article/details/93030068
https://github.com/session-replay-tools/tcpcopy