DolphinDB提供離線方式和在線方式實現不一樣集羣間數據庫的同步。html
離線方式先把數據庫中數據,經過DolphinDB內置的backup函數以二進制形式導入到磁盤,而後將數據同步到數據庫所在的物理機器上,再經過restore函數將數據從磁盤恢復到到數據庫。以下所示:linux
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.1 數據在線同步
在線方式,要求兩個集羣同時在線,經過創建socket鏈接,直接從一個集羣中讀數據,並寫入到另外一個集羣上。以下圖所示:
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,不採用並行執行,以儘可能少佔用內存。若是內存充足,並行的效率更高。
性能:在線方式中,數據不用存盤,直接經過網絡傳輸到遠端並寫入數據庫;而離線方式先把數據備份到磁盤上,再經過網絡傳輸到遠端的磁盤上,再讀取磁盤數據並寫入數據庫,所以性能低於在線方式。
內存要求:離線方式是以分區爲單位備份的,所以要求內存必須容納一個分區的完整數據。通常狀況下,沒有什麼問題。但在某些特殊場景下,好比表的列特別多(幾千列),而平時經常使用的字段不多(10幾個),設計每一個分區容量的時候,可能更多的考慮經常使用字段,而不是表的所有字段。這種狀況下,內存有可能不能容納一個分區全部列的數據。而在線方式對內存容量的要求要低不少,若分區數據量超過內存,可對一個分區再進行更細粒度的劃分。
磁盤佔用:離線方式在本機以及遠端都須要存盤,佔用更多的磁盤空間,在線方式不須要額外佔用磁盤空間。
其餘方面:離線方式不須要兩個集羣同時在線,數據備份後,能夠在不一樣的時間段進行數據同步。在線方式須要兩個集羣都同時在線,都能正常提供服務。