乾貨丨DolphinDB集羣間數據庫同步教程

DolphinDB提供離線方式和在線方式實現不一樣集羣間數據庫的同步。html

  • 離線方式:經過數據庫備份和恢復功能實現數據同步。
  • 在線方式:經過創建在線鏈接,把數據從一個庫讀取再寫入到另外一個庫中。數據庫指的是DFS分佈式的數據庫,而非內存表或流數據表等。

1. 離線方式

離線方式先把數據庫中數據,經過DolphinDB內置的backup函數以二進制形式導入到磁盤,而後將數據同步到數據庫所在的物理機器上,再經過restore函數將數據從磁盤恢復到到數據庫。以下所示:linux

9b9e5d3586220d21da618d0d4ac4ea73.png

1.1 數據備份git

經過backup函數將須要同步的數據表備份到磁盤上,備份以分區爲單位。須要同步的數據能夠用sql語句指定,以下:github

示例1,備份數據庫db1中表mt的全部數據。sql

backupDir = /hdd/hdd1/backDir		
backup(backupDir,<select * from loadTable("dfs://db1","mt")>)

示例2,備份數據庫db1中表mt的最近7天的數據,假設時間分區字段是TradingDay(DATE)。shell

backupDir = /hdd/hdd1/backDir		
backup(backupDir,<select * from loadTable("dfs://db1","mt") where TradingDay > date(now()) - 7 and  TradingDay <= date(now())>)

示例3,備份數據庫db1中表mt的某些列(col1,col2,col3)的數據:數據庫

backupDir = /hdd/hdd1/backDir		
backup(backupDir,<select col1,col2,col3 from loadTable("dfs://db1","mt")>)

更靈活的sql元語句表示參考DolphinDB元編程教程編程

1.2 節點間數據文件同步服務器

若是須要同步的兩個數據庫不在同一臺物理機器上,則須要同步二進制文件。DolphinDB支持shell命令,可利用操做系統提供的文件同步手段來同步目錄,例如rsync或者scp命令。其中rsync是linux上的經常使用命令,只同步發生變化的文件,很是高效。網絡

cmd = "rsync -av  " + backupDir + "/*  " + userName + "@" + restoreIP + ":" + restoreDir 
shell(cmd)

以上腳本,將一臺機器上backupDir目錄下的全部發生變化的文件同步到另外一臺機器的restoreDir目錄下。其中,userName和restoreIP是經過ssh登陸的用戶名以及遠程機器的IP地址。

注意:以上命令須要配置ssh免密登陸。固然,也能夠經過其餘服務器同步工具實現。

1.3 數據恢復

數據同步之後,可經過DolphinDB內置的restore函數,從restoreDir中恢復出所須要的數據。

示例1,恢復全部備份數據庫db1表mt的全部數據到數據庫db2的表mt中。

restore(restoreDir,"dfs://db1","mt","%",true,loadTable("dfs://db2","mt"))

除了恢復全部數據,還能夠根據條件恢復指定分區。詳細參考教程數據備份與恢復

1.4 具體實例

兩個DolphinDB集羣部署在不一樣的機器上。須要天天22:30,同步A集羣上的數據庫(db1,包括表mt)的全部數據到B集羣上。數據庫db1的分區類型爲VALUE,按天分區,分區字段爲Timestamp(類型爲TIMESTAMP)。

//腳本應在B集羣上,也就是須要恢復數據的集羣上執行。
def syncDataBases(backupNodeIP,backupNodePort,backupDir,restoreServerIP, userName,restoreDir){
	conn = xdb(backupNodeIP,backupNodePort)
	conn(login{`admin,`123456})
	conn(backup{backupDir,<select * from loadTable("dfs://db1","mt") where Timestamp > timestamp(date(now())) and Timestamp < now()>})
	cmd = "rsync -av  " + backupDir + "/*  " + userName + "@" + restoreServerIP + ":" + restoreDir 
	conn(shell{cmd})
	restore(restoreDir,"dfs://db1","mt","%",true,loadTable("dfs://db1","mt"))
}

login(`admin,`123456)
//配置備份節點的IP address,端口,以及備份機器上的物理目錄,該目錄應是空目錄。
backupNodeIP = '115.239.209.234' 
backupNodePort = 18846
backupDir = "/home/pfsui/myselfTest/backupDir"
//配置恢復數據節點的IP address,由備份機器到恢復機器的ssh登陸用戶名(機器間應配置好ssh免密登陸),以及恢復節點上的物理空目錄。
restoreServerIP = '115.239.209.234'
userName = 'user1'
restoreDir = "/home/pfsui/myselfTest/backupDir"

//手動觸發備份
syncDataBases(backupNodeIP,backupNodePort,backupDir,restoreServerIP, userName,restoreDir)
//經過scheduleJob方式,天天22:30定時執行
scheduleJob("syncDB","syncDB",syncDataBases{backupNodeIP,backupNodePort,backupDir,restoreServerIP, userName,restoreDir},22:30m,2019.01.01,2030.12.31,'D')

先經過backup函數備份數據數據到系統磁盤,而後使用shell命令rsync來同步不一樣物理機器上的目錄,最後使用restore函數恢復數據到數據庫。可以使用scheduleJob函數來啓動定時任務。

2 在線方式

2.1 數據在線同步

在線方式,要求兩個集羣同時在線,經過創建socket鏈接,直接從一個集羣中讀數據,並寫入到另外一個集羣上。以下圖所示:

a7c9c6fc5d3dc8190d385abcef31f922.png

2.1 具體示例

場景跟上面場景一致,咱們考慮兩種場景,一是內存足夠容納一天的數據,二是內存不足以容納一天的數據。

場景1,內存足夠容納一天數據,具體代碼以下:

def writeData(dbName,tableName,t) : loadTable(dbName,tableName).append!(t)
def synDataBaseOnline(restoreServerIP,restoreServerPort){
	t = select * from loadTable("dfs://db1","mt") where Timestamp > timestamp(date(now())) and Timestamp < now()
	conn = xdb(restoreServerIP,restoreServerPort)
	conn(login{`admin,`123456})
	conn(writeData{"dfs://db1","mt",t})
}
login(`admin,`123456)
restoreServerIP = '115.239.209.234'
restoreServerPort = 18848
synDataBaseOnline(restoreServerIP,restoreServerPort)

腳本在備份節點執行,從數據庫中取出當前的數據,並遠程寫入到恢復節點的數據庫中。

場景2,當天數據量太大,內存不足以容納:

def writeData(dbName,tableName,t) : loadTable(dbName,tableName).append!(t)
def writeRemoteDB(t, ip, port, dbName,tableName){
	conn = xdb(ip, port)
	conn(login{`admin,`123456})
	remoteRun(conn,writeData,dbName,tableName,t)
}
def synDataBaseOnline(ip, port){
	ts = <select * from loadTable("dfs://db1","mt") where Timestamp > timestamp(date(now())) and Timestamp < now()>
	ds = repartitionDS(ts,`sym,RANGE,10)
	mr(ds, writeRemoteDB{,ip,port,"dfs://db1","mt"},,, false)
}
login(`admin,`123456)
restoreServerIP = '115.239.209.234'
restoreServerPort = 18848

//手動觸發
synDataBaseOnline(restoreServerIP,restoreServerPort)

//定時觸發
scheduleJob("syncDB","syncDB",synDataBaseOnline{restoreServerIP,restoreServerPort},22:30m,2019.01.01,2030.12.31,'D')

若是當天的數據量太大,能夠經過repartitionDS函數將數據再分區。本例把當天數據按照sym字段再進行切分爲10份,最後經過mr函數將這10份數據逐一寫到遠程,mr函數的parallel參數設爲false,不採用並行執行,以儘可能少佔用內存。若是內存充足,並行的效率更高。

3 兩種方式對比

性能:在線方式中,數據不用存盤,直接經過網絡傳輸到遠端並寫入數據庫;而離線方式先把數據備份到磁盤上,再經過網絡傳輸到遠端的磁盤上,再讀取磁盤數據並寫入數據庫,所以性能低於在線方式。

內存要求:離線方式是以分區爲單位備份的,所以要求內存必須容納一個分區的完整數據。通常狀況下,沒有什麼問題。但在某些特殊場景下,好比表的列特別多(幾千列),而平時經常使用的字段不多(10幾個),設計每一個分區容量的時候,可能更多的考慮經常使用字段,而不是表的所有字段。這種狀況下,內存有可能不能容納一個分區全部列的數據。而在線方式對內存容量的要求要低不少,若分區數據量超過內存,可對一個分區再進行更細粒度的劃分。

磁盤佔用:離線方式在本機以及遠端都須要存盤,佔用更多的磁盤空間,在線方式不須要額外佔用磁盤空間。

其餘方面:離線方式不須要兩個集羣同時在線,數據備份後,能夠在不一樣的時間段進行數據同步。在線方式須要兩個集羣都同時在線,都能正常提供服務。

相關文章
相關標籤/搜索