# DolphinDB 集群间数据库同步 DolphinDB 提供离线方式和在线方式实现不同集群间 DFS 数据库的同步: * 离线方式:通过数据库备份和恢复功能实现数据同步; * 在线方式:通过建立在线连接,从一个数据库中读取数据然后写入另一个数据库中。 ## 1. 离线方式 使用离线方式同步集群间数据库的主要步骤如下: 1. 使用 [backup](https://www.dolphindb.cn/cn/help/FunctionsandCommands/FunctionReferences/b/backup.html) 函数将数据库中的数据备份到系统磁盘; 2. 通过网络传输,将备份数据同步到远端磁盘; 3. 使用 [restore](https://www.dolphindb.cn/cn/help/FunctionsandCommands/FunctionReferences/r/restore.html) 函数将备份数据恢复到另一个数据库中。 ![image](./images/datasync/1.png) ### 1.1 数据备份 通过 [backup](https://www.dolphindb.cn/cn/help/FunctionsandCommands/FunctionReferences/b/backup.html) 函数将需要同步的数据表备份到磁盘上,可使用 SQL 元代码指定需要同步的数据。示例如下: 示例1:备份数据库 db1 中表 mt 的所有数据。 ``` backupDir = "/hdd/hdd1/backDir" backup(backupDir, date(now()) - 7 and TradingDay <= date(now())>) ``` 示例3:备份数据库 db1中表 mt 的某些列 ("col1", "col2", "col3") 的数据。 ``` backupDir = "/hdd/hdd1/backDir" backup(backupDir, 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 地址,端口,以及备份机器上的目录(空目录)。 backupNodeIP = '115.239.209.234' backupNodePort = 18846 backupDir = "/home/myselfTest/backupDir" //配置恢复数据节点的 IP 地址,由备份机器到恢复机器的 ssh 登录用户名(机器间应配置好 ssh 免密登录),以及恢复节点上的目录(空目录)。 restoreServerIP = '115.239.209.234' userName = 'user1' restoreDir = "/home/myselfTest/backupDir" ``` 可执行以下函数触发备份: ``` syncDataBases(backupNodeIP=backupNodeIP,backupNodePort=backupNodePort,backupDir=backupDir,restoreServerIP=restoreServerIP, userName=userName,restoreDir=restoreDir) ``` 也可通过 [scheduleJob](https://www.dolphindb.cn/cn/help/FunctionsandCommands/FunctionReferences/s/scheduleJob.html) 指定每天22:30定时执行 ``` scheduleJob("syncDB","syncDB",syncDataBases{backupNodeIP,backupNodePort,backupDir,restoreServerIP, userName,restoreDir},22:30m,2019.01.01,2030.12.31,'D') ``` ## 2. 在线方式 ### 2.1 数据在线同步 在线方式要求两个集群同时在线并建立 socket 连接。集群2读取集群1中的数据后写入集群2中的数据库。如下图所示: ![image](./images/datasync/2.png) ### 2.2 具体示例 本例沿用1.4小节的条件设置,假设两种场景,一种是集群 B 所在物理机器的内存足够容纳当天数据,另一种是其内存不能容纳当天数据。 示例7:内存足够容纳当天数据。脚本在备份节点执行,从集群 A 中的数据库中读取当天的数据,并远程写入到恢复节点所在的集群 B 的数据库中。 ``` def writeData(dbName,tableName,t) : loadTable(dbName,tableName).append!(t) def synDataBaseOnline(restoreServerIP,restoreServerPort,writeData=writeData){ 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=restoreServerIP,restoreServerPort=restoreServerPort) ``` 示例8: 内存不能容纳当天数据时,使用上述脚本可能会导致 OOM。可使用 [sqlDS](https://www.dolphindb.cn/cn/help/FunctionsandCommands/FunctionReferences/s/sqlDS.html) 将备份数据按分区生成多个数据源,通过 [mr](https://www.dolphindb.cn/cn/help/FunctionsandCommands/FunctionReferences/m/mr.html) 函数将数据源逐个写入远程数据库。 ``` def writeData(dbName,tableName,t) : loadTable(dbName,tableName).append!(t) def writeRemoteDB(t, ip, port, dbName,tableName,writeData){ conn = xdb(ip, port) conn(login{`admin,`123456}) remoteRun(conn,writeData,dbName,tableName,t) } def synDataBaseOnline(ip, port){ ds = sqlDS(