當今世界,隨著企業業務全面向數字化、線上化、智慧化演進,應用場景日趨複雜和多樣化。企業面臨著指數級遞增的海量儲存需求,業務系統的壓力越來越大。
金倉JDBC讀寫分離叢集原理
讀寫分離透過備機讀負載均衡,降低主機上讀負載,以此提高整個系統的吞吐量。
金倉JDBC讀寫分離主旨是透過JDBC驅動實現SQL讀寫分離,讓DQL語句在多個節點間負載均衡,同時對應用透明,無需修改現有程式。
金倉JDBC透過在內部直接識別語句型別,記錄事務狀態等處理。把讀語句負載均衡給叢集中的多個節點執行,降低單節點的負載,提升資料庫叢集整體的吞吐量。
讀寫分離叢集提升效能
主備節點各有分工 緩解爭用現象
在事務處理過程中,以下四種操作分別對應不同節點執行:
1.如果只有讀操作,透過JDBC驅動將事務中的語句分發到備節點中執行;
2.如果事務中只有寫操作,透過驅動分發器將事務分發到主節點中執行;
3.如果事務中開始是讀,後續有寫操作,則將開始的讀操作分發到備節點中執行,直到寫操作後,該事務中的所有SQL將在主節點中執行;
4.對於TCL事務控制和SET會話引數設定語句傳送給所有節點。
5.對於DCL語句只發送給主節點。
負載均衡 提升效能
針對不同的硬體效能,JDBC透過引數控制讀語句發給主機的比例來分配負載。所有的備機節點用於讀操作,當我們讀取操作較多時,驅動分發器將透過分發演算法,將讀操作均衡分佈在所有正確的備機節點中執行,降低主節點負載,透過備節點負載均衡,提高查詢效能。
針對讀比例較大的應用系統,同步部署金倉的讀寫分離叢集,能大大的提升資料庫的響應能力。也就是說,如果某個應用系統中的讀操作佔了70%,透過部署3節點的讀寫分離叢集,能將資料庫的整體效能(按照事務吞吐量計算)提高2倍左右;隨著讀操作的比例越高,效能提升倍數約趨向於節點數。
效能測試結果對比:
Jmeter 執行100萬次select查詢操作
一主兩備 連線配置方式 |
Throughput(持續3分鐘) |
併發連線數(執行緒數) |
單機,不使用讀寫分離 |
9749.11 |
50 |
使用中間代理kingbasecluster讀寫分離 |
6478.32 |
50 |
使用 JDBC讀寫分離 |
25731.95 |
50 |
JDBC讀寫分離對比單機效能提升1.5倍。JDBC讀寫分離對比kingbasecluster效能提升3倍。
Throughput曲線圖:
由此圖可以看出JDBC 讀寫分離效能提升明顯
備註:為方便對比測試,全部執行簡單查詢語句。
讀寫分離叢集保障服務連續
當資料庫叢集中出現某個節點宕機或者網路中斷等問題時,金倉的資料庫叢集可以自動恢復。同時金倉JDBC會自動重建連線和自動判斷主備狀態,在非寫事務狀態下,JDBC還可以自動重發失敗語句,直至成功,從而最大程度保障上層應用服務連續。
引數配置及最佳實踐
引數配置
ConfigurePath = String
指定配置檔案的路徑,只能在連線串中配置,值為null時,不讀取配置檔案,預設取值為:null。當連線引數較多時,可透過配置檔案配置連線引數。當檔案中配置的連線引數與URL中的引數重複時,會覆蓋掉URL中的引數值。
USEDISPATCH = Boolean
指定是否使用讀寫分離功能,預設取值為:false。此配置項關閉JDBC就變成單機JDBC,無讀寫分離功能。
TransactionDispatchStrategy = String
指定事務中的分發策略,1表示事務都不分發,2表示事務中的寫語句之前的讀語句可以分發,預設取值為:“2”。此功能開啟需要同時開啟讀寫分離功能。
HOSTLOADRATE = String
指定主機的讀語句負載率,預設取值為:“0”。此功能開啟需要同時開啟讀寫分離功能。根據當前發給主機的語句數目與總語句數目的比例與HOSTLOADRATE設定的比例進行比較,當前者大於後者時,發給備機,否則發給主機,當總語句數目達到Integer.MAX_VALUE時,用當前分發的實際比例的分子分母更新當前發給主機的語句數目與總語句數目。
SLAVE_ADD = String
指定備機地址,可指定多個,用“,”隔開。此功能開啟需要同時開啟讀寫分離功能。
SLAVE_PORT = String
指定備機埠,與備機地址對應,可指定多個,用“,”隔開。此功能開啟需要同時開啟讀寫分離功能且設定備機地址。
RETRYTIMES = String
指定失敗重發的最高次數,預設取值為:“10”。此功能開啟需要同時開啟讀寫分離功能。
RETRYINTERVAL = String
指定每次失敗重發之間的時間間隔,單位是秒,預設取值為:“5”。此功能開啟需要同時開啟讀寫分離功能且重試次數大於0。
forwardStandby = Boolean
WhiteList = String
WhiteList指定只讀函式列表,可指定多個,各個函式之間用分號分隔,如:WhiteList=MAX;COUNT;AVG 這樣,預設取值為:null。目前只支援函式名字的比較,不支援函式名過載的區分。此功能開啟需要同時開啟讀寫分離功能。
BlackList = String
預設情況下認為函式都是隻讀的,BlackList指定寫函式列表,可指定多個,各個函式之間用分號分隔,如:BlackList=updateXXX;writeXXX 這樣,預設取值為:null。目前只支援函式名字的比較,不支援函式名過載的區分。不與WhiteList同時配置,與WhiteList同時配置時,只有BlackList生效。此功能開啟需要同時開啟讀寫分離功能。
MasterFunctionList = String
指定只發主機,但不改變事務狀態的函式語句列表,可指定多個,各個函式之間用分號分隔,如:MasterFunctionList=updateXXX;writeXXX 這樣,預設取值為:null。目前只支援函式名字的比較,不支援函式名過載的區分。此功能開啟需要同時開啟讀寫分離功能。
TempTable = String
指定臨時表,如果是查詢臨時表的查詢語句,則只發主機且不改變事務狀態。可指定多個,各個表名之間用分號分隔,如:aaa;bbb這樣,預設取值為:null。此功能開啟需要同時開啟讀寫分離功能。
BlackSqlList = String
指定只發主機,但不改變事務狀態的sql語句列表,可指定多個,各個語句之間用分號分隔,如:BlackSqlList=SET TRANSACTION READ WRITE;BEGIN READ WRITE 這樣,預設取值為:null。此功能開啟需要同時開啟讀寫分離功能。
socketTimeout = String
指定底層socket receive的超時時間,單位是秒,值可以為任意正整數,“0”表示沒有超時,一 直等,直到返回,預設取值為:“0”。
最佳實踐以上引數大多使用預設值即可,也可根據需求進行修改。最簡單的使用配置只需開啟讀寫分離,然後配置主備機IP、Port即可。
請注意:讀寫分離的主備機的IP地址需要配置真實IP地址,不要配置VIP。因為VIP在切機後會造成新升主的IP和VIP其實指向了同一節點,造成重複連線,同時造成之前故障的舊主機重新恢復上線後,無法被識別。另外VIP並不可靠,可能出現丟失或VIP重複問題。
只使用url進行配置一主兩備叢集jdbc:kingbase8://192.168.8.128:54321/TEST?USEDISPATCH=true&SLAVE_ADD=192.168.8.129,192.168.8.130&SLAVE_PORT=54321,54321
使用URL+配置檔案進行配置一主兩備叢集jdbc:kingbase8:TEST?ConfigurePath=/home/test/jdbc.conf
jdbc.conf配置檔案例子:
USEDISPATCH=true
HOST=192.168.8.128
PORT=54321
SLAVE_ADD=192.168.8.129,192.168.8.130
SLAVE_PORT=54321,54321
常見問答
叢集狀態正常,sockettimeout設定大於0時,為什麼執行時間超長的事務會失敗並導致jdbc重建連線?
sockettimeout是控制底層socket超時返回的最長時間,預設是0,即沒有超時無限等待。如果指定大於0的值,意思就是最多等待sockettimeout的時間,socket的receive操作就會返回。
這主要是用來防止當server掉線時,client端socket的receive操作會一直等待。但是這會帶來副作用,就是如果一條語句真的執行很長時間超過了sockettimeout的值時,會被認為是超時而中斷receive返回超時錯誤。如果是在讀寫分離狀態下,超時會造成重建連線重發語句。此時需要根據使用者的語句最長執行時間來設定sockettimeout或者設定為0一直等待。如果應用自己有防這種JDBC操作一直不返回的機制,JDBC呼叫不返回,應用會有自己的超時控制,那就不需要JDBC設定sockettimeout,讓應用自己控制超時時間就好。如果應用沒有這種防止機制,一個JDBC操作不返回就會造成應用完全卡死,那就需要設定JDBC的sockettimeout值,讓JDBC來控制超時時間。
主備切換後,備機rewind,或者備機故障後,備機恢復時為什麼備機的連線數是持續上升,而不是一次性全部建好?
主備切換後,連線不是馬上就全部建立起來的,而是應用確實呼叫到JDBC時,JDBC才會去判斷叢集是否切換了,重建連線,重發語句執行。所以連線數的恢復速度和應用操作JDBC負荷有關,通常是慢慢建立起來的,備機的連線會稍滯後於主機連線恢復速度,因為切機重發時,都是隻要能找到新的主機就可以重發成功了,不會等到所有備機重啟完成。只有等到下一次傳送語句觸發備機時,JDBC才會去檢測備機是否已經起來了,如果未建起才會去重建備機連線。
主機切機後,應用第一次登陸WEB慢,JDBC等待時間分析
區域網內測試拔網線切機後的過程:
1、叢集的新主機起來可連線後;
2、應用使用者登入WEB;
3、使用連線池中已經有的JDBC連線(主機的連線都已經失效,備機的rewind之前都還在);
4、傳送SQL;
5 、(I /O Error 20秒)收到錯誤返回;
6、重建JDBC連線(sleep 5秒);
7、(線上0.1秒返回)+(不線上的需要10秒返回)。重建連線完成開始執行登陸SQL返回,總計35秒左右。
其中 (不線上的需要10秒返回) 這個可以透過connectTimeout 引數控制connect超時時間,預設是10秒。其中 (sleep 5秒) 這個可以透過RETRYINTERVAL引數控制重建連線的間隔時間,預設是5秒。其中 (I /O Error 20秒) 這個可以透過socketTimeout引數控制receive的超時時間,預設是0無限等待。備機的連線不是馬上斷掉,而是在一段時間內都還可以使用,等到rewind時連線才會全部斷掉。