1. 程式人生 > >基於SymmetricDS的多主一從資料庫同步方案

基於SymmetricDS的多主一從資料庫同步方案

團隊最近有個資料同步的需求,大致是兩臺或以上的資料庫(MariaDB)伺服器走VPN通道與一臺資料庫進行資料同步,先不關心VPN通道通迅的問題,對於這種多主一從的資料同步需求,也曾嘗試通過MySQL本身的複製功能配置實現,但貌似不管是MySQL還是MariaDB目前都還沒有實現多主一從的複製方案(官方說MariaDB從10.0開始支援,等到花兒都謝了)。

初步確定兩種方案:

       1.通過編碼實現服務程式碼,定時主動向幾個主庫抓取資料並整合插入到從庫中.

       2.通過第三方的開源解決方案(其實也是服務程式碼,但封裝實現較好),雖然配置要繁瑣,但同步效率要高很多。

下面就記錄下測試的一款第三方同步方案SymmetricDS(以下簡稱S)的使用過程,中文資料較少,而且存在一些版本上的差異,導致一些步驟根本不能通過或報錯,自己簡化了些操作,並沒有按照官方的指導操作,鑑於英文水平有限,很多敘述都是基於自己的理解,也請有不同觀點的兄弟留言指正或交流。

之所以選擇SymmetricDS,大致三個原因:

       1.  平臺獨立。不依賴其他元件包,獨立配置完後實現功能。

       2.  業務無關。不需要關心資料庫中的業務,直接配置同步的表名等引數。

       3.  同步及時。基於觸發器的資料同步,保證資料傳輸的及時性。


官方地址:http://www.symmetricds.org

下面是開源中國的一些圖表介紹,引用下:


部署示意圖,雙箭頭代表可以雙向同步,而不是簡單的單向複製。

配置資料模型:對於各個伺服器,不管是主機還是從機,都需要配置S服務,用來監聽或執行動作等,並且是以節點代表伺服器來配置,至於觸發器更體現它的實時性,一方資料庫發生變化,首先被本機S服務監聽,同時向關聯的節點發起同步請求,關聯節點接收請求並做響應動作。


執行時資料模型:當每個節點監聽到本機的資料事件(即資料變動),會將變動的資料通過觸發器與關聯節點進行通迅。

測試方案拓撲圖如下。sun1、sun2 向 sun進行單向資料同步。
因實際硬體測試環境限制,本地新建三個資料庫分別模擬sun,sun1,sun2
每個節點都需要配置一個s服務,將S服務程式碼分別解壓到了三個目錄: D:\develop\symmetric\sun\symmetric D:\develop\symmetric\sun1\symmetric D:\develop\symmetric\sun2\symmetric
一、首先配置從機sun的S服務進入到D:\develop\symmetric\sun\symmetric目錄,將samples目錄下的corp-000.properties檔案拷貝到engines目錄下,samples目錄下是官網提供的一個範例,engines是你配置自己同步服務的目錄,corp-000.properties可以說是配置從機節點引數的一個模板,所以拷貝出來做修改,檔名可以自定義修改,修改為sunserver-000.properties。 按照如下模板修改:

engine.name 引擎名稱,可以理解成當前節點服務的名稱 db.driver 資料庫的jdbc驅動名稱 db.url 資料庫連線字串 db.user 資料庫使用者名稱 db.password 資料庫密碼 registration.url 上一級節點的註冊地址,如果是頂級節點,就設為空 sync.url 本機的註冊地址 http://localhost:8080/sync/sunserver-000 其中8080是當前節點服務啟動後需要佔用的埠,sunserver-000即第一個引數engine.name的值 group.id 節點組的ID,當前頂級節點組名為sunserver,意思是服務端 external.id 當前節點組下節點的編號,通過上面的group.id和external.id可以定位到唯一的節點 後面的引數是對S服務執行引數的配置,保持預設就好。 二、配置子節點sun1。配置好頂級節點從機sun的服務,接下來就該配置子節點資料主機sun1,sun2的了,先配置sun1.同樣的,進入到D:\develop\symmetric\sun1\symmetric目錄,將samples目錄下的store-001.properties檔案拷貝到engines目錄下,這裡的store-001.properties也可以說是配置資料主機節點引數的一個模板,配置內容與sun類似,這裡改名為sunclient-001.properties
配置基本上與sun節點類似,其中有些需要關注的是: registration.url 這裡填寫的是上級節點的註冊地址,可以看到就是sun配置引數中的sync.url 這裡的sync.url其實不用配置,因為節點到此為止。如果sun1以下還有節點分支,那需要配置這個引數,並且在下一個節點的registration.url配置這個值。需要注意的是,我當前是在單機上模擬三個節點服務的執行,所以每個節點服務的啟動埠不同,避免衝突。sun1的啟動埠是7070 group.id 這裡的組ID為sunclient,意思是客戶端。 三、配置sun2節點。進入到D:\develop\symmetric\sun2\symmetric目錄,後續步驟與上一步相同。
四、建立同步表資料。接下來,需要向同步的資料庫進行資料匯入,官網的方式是通過命令列進入到Symmetric的目錄,通過命令執行sql指令碼建立表和資料,但我嘗試了幾次,都沒有成功,有些資料說是因為官網相關XML檔案格式的問題,不管咋樣,索性自己手動建立表和資料。     所以要做的,就是在資料庫中建立你要同步的表,如果資料庫中已經有表結構了,可不做操作了。     建立後的表為
區域表,電站表。 具體表結構也一目瞭然:
所有的節點資料庫sun、sun1、sun2都需手動建立和新增資料,並且理論上資料庫的結構應該是保持一致的。 五、初始化頂級節點sun的系統表結構這裡的系統表,指的就是Symmetric自己的同步服務表,並且所有的節點資料庫中都需要有這些系統表(這也是我覺得悲催的地方,光這些系統表就二三十個,忒不美觀了)。稍微慶幸的是,我們只要在頂級節點中建立這些表,所有子節點在服務啟動後,會根據頂級節點自動建立。 通過命令列進入到D:\develop\symmetric\sun\symmetric\engines目錄 執行
..\bin\symadmin --engine sunserver-000 create-sym-tables

執行成功,完成初始化系統表。此時可以檢視下資料庫,發現多了好多表啊。
sym字首的表 都是,表數量不止於此,還不是完整截圖。:-( 六、初始化頂級節點sun的系統表資料。上一步驟是初始化表結構,下面就要初始化資料了。其實說到現在,我們都還不知道怎麼控制SymmetricDS同步的邏輯,比如需要同步哪些表,哪個節點向哪個節點發送同步資料,這些都體現在系統表資料中了。         至於如何初始化系統表資料,我參照了samples目錄中insert_sample.sql指令碼檔案,官方範例中系統表的初始化指令碼,另外還參照了百度文庫中一篇說明。 (1)配置節點組
insert into sym_node_group (node_group_id, description)
values ('sunserver', '電站資料中心');
insert into sym_node_group (node_group_id, description)
values ('sunclient', '子電站資料伺服器');

(2)配置各節點組間的資料同步模式。有push(推)和wait(等待||拉)兩種,由data_event_action制定,其中w(wait for pull)代表拉,p代表推(push)。
insert into sym_node_group_link (source_node_group_id, target_node_group_id, data_event_action)
values ('sunclient', 'sunserver', 'P');
insert into sym_node_group_link (source_node_group_id, target_node_group_id, data_event_action)
values ('sunserver', 'sunclient', 'W');

(3)配置各個節點資訊。這裡只要配置sun的節點資訊就可,其他子節點sun1、sun2在註冊節點後,會自動生成系統表並且插入資料
insert into sym_node (node_id, node_group_id, external_id, sync_enabled)
values ('000', 'sunserver', '000', 1);
insert into sym_node_security (node_id,node_password,registration_enabled,registration_time,initial_load_enabled,initial_load_time,initial_load_id,initial_load_create_by,rev_initial_load_enabled,rev_initial_load_time,rev_initial_load_id,rev_initial_load_create_by,created_at_node_id)
values ('000','123456',0,current_timestamp,0,current_timestamp,null,null,0,null,null,null,'000');
insert into sym_node_identity values ('000');

(4)配置資料通道表。有外來鍵關聯的表,一定要定義在同一通道中,才能進行關聯同步。
insert into sym_channel
(channel_id, processing_order, max_batch_size, enabled, description)
values('bus_info', 1, 100000, 1, '電站資訊同步通道');

(5)定義觸發器。在這裡定義需要同步庫中的哪些表,注意有外來鍵關聯的表,通道值要相同。sym_trigger中的excluded_column_names欄位,可以設定不想同步的表字段,這裡並沒有體現。
insert into sym_trigger
(trigger_id,source_table_name,channel_id,last_update_time,create_time)
values('symmetric_test_area','symmetric_test_area','bus_info',current_timestamp,current_timestamp);
insert into sym_trigger  
(trigger_id,source_table_name,channel_id,last_update_time,create_time)
values('symmetric_test_bus','symmetric_test_bus','bus_info',current_timestamp,current_timestamp);

(6)配置資料路由。配置資料同步時資料的走向,即從哪個節點向哪個節點同步。其中ROUTER_TYPE='column'就是指明由需同步的表中某列的值來決定資料流向,具體的條件則來表示式決定:ROUTER_EXPRESSION='org_code=:EXTERNAL_ID' 。預設ROUTER_TYPE=‘default’就好。
insert into sym_router
(router_id,source_node_group_id,target_node_group_id,router_type,create_time,last_update_time)
values('client_2_server', 'sunclient', 'sunserver', 'default',current_timestamp, current_timestamp);

(7)最後建立觸發器與路由的關聯。SymmetricDS中定義的觸發器只有被路由關聯後,SymmetricDS才會為這個表自動生成相應的觸發器。
insert into sym_trigger_router
(trigger_id,router_id,initial_load_order,last_update_time,create_time)
values('symmetric_test_area','client_2_server', 200, current_timestamp, current_timestamp);
insert into sym_trigger_router
(trigger_id,router_id,initial_load_order,last_update_time,create_time)
values('symmetric_test_bus','client_2_server', 200, current_timestamp, current_timestamp);

七、啟動SymmetricDS (1)註冊所有子節點,命令列進入D:\develop\symmetric\sun\symmetric\engines 頂級節點目錄。 分別執行註冊節點命令
..\bin\symadmin --engine sunserver-000 open-registration sunclient 001
..\bin\symadmin --engine sunserver-000 open-registration sunclient 002
再分別執行注入節點命令
..\bin\symadmin --engine sunserver-000 reload-node 001
..\bin\symadmin --engine sunserver-000 reload-node 002
(2)啟動服務。 分別啟動三個節點的服務,先執行子節點。 命令列進入 D:\develop\symmetric\sun1\symmetric\engines  執行 
..\bin\sym --port 7070
命令列進入 D:\develop\symmetric\sun2\symmetric\engines  執行 .
..\bin\sym --port 9090
命令列進入 D:\develop\symmetric\sun\symmetric\engines  執行 
..\bin\sym --port 8080
這裡要注意埠號,即配置檔案中註冊地址的埠號。
至此 三個服務都成功開啟。下面可以進行測試了。。 在sun1資料庫symmetric_test_area表中新增一條資料4--seattle
在sun2資料庫symmetric_test_area表中新增一條資料5--tokyo
最後直接檢視sun的資料庫,會發現:
大功告成! 總結: SymmetricDS功能很複雜,這裡只是暫時實現了多主一從結構的配置,深入到具體的同步細節,還需要了解很多。 優點:同步即時,基於推拉雙機制的同步,對於資料的及時性完整性有保障。關於事件的併發與執行緒管理已封裝。表結構變動對於配置好的資料欄位的同步影響不大,但對於新增的欄位如果也需要同步的話,需要重新註冊節點,並重啟服務。 缺點:每個節點都需要配置服務程式碼,且比較複雜。會在每個節點資料庫中生成41張同步系統表,業務的控制體現在表資料中。適合用於固定或長期穩定的網路通道的機房環境。如果整合進產品往外推廣,配置複雜後期維護也麻煩,適合本公司內部伺服器的應用。 補充:其實我覺得最大的優點就是,對於資料同步這個需求,symmetricDS只需要配置不關心每個資料庫的具體業務,只關心要同步哪個資料庫哪張表。如果是寫服務程式碼來定時抓取資料再插入資料的話,可能還要考慮到資料庫中的業務,比如哪個表關聯哪個表,插入資料的先後還有級聯問題等,對於symmetricDS來說只要關聯表在一個同步通道中即可。