6.5 集群内文件复制和并行复制
集群内文件复制是经常要应对的需求,比如备份容灾,文件迁移,同步数据等。
FttpAdapter提供了简单高效的文件复制方法,支持远程文件的集群内复制:
- FttpAdapter fromfile = new FttpAdapter("fttp://192.168.0.1/home/log/a.log");
- FttpAdapter tofile = fromfile.copyTo("fttp://192.168.0.2/home/log/ a.log",FileAdapter.m(1));
上面代码代表将a.log文件复制到其他机器并得到相应的文件对象。
这里的copyTo方法的第二个参数,表示复制时,每次以1M/S的速度传输:
- FileAdapter.m(1) 1M
- FileAdapter.g(1) 1G
- FileAdapter.k(1) 1k
数字1可以自由设置为其他数字,copyTo的默认值是每次以1M/S的速度复制,可以根据网络情况调整这个参数,达到最优化。
注意
这里的复制方法名叫做copyTo而不是copy,因为它们之间存在区别,copyTo只是将前一文件内容复制到后一文件内容里,追加到末尾,但并不从头覆盖前一个文件的内容。通常在操作系统上覆盖文件,在用户不知情的情况下弹出警告框提示获得同意,因此copyTo能避免在未经许可下覆盖旧文件。如果你需要这样做,可以参考6.6节“读写远程文件”,设置读写位置为文件开始,从头覆盖文件内容。
FttpCopyDemo演示了集群中两台机器间的复制功能。
运行步骤如下:
1)启动ParkServerDemo:
- java -cp fourinone.jar; ParkServerDemo
2)在192.168.0.1机器上启动FttpServer:
- java -cp fourinone.jar; FttpServer 192.168.0.1
3)在192.168.0.2机器上启动FttpServer:
- java -cp fourinone.jar; FttpServer 192.168.0.2
4)运行FttpCopyDemo:
- java -cp fourinone.jar; FttpCopyDemo
完整demo源码如下:
- // FttpCopyDemo
- import com.fourinone.FttpAdapter;
- import com.fourinone.FttpException;
- import java.util.Date;
- public class FttpCopyDemo
- {
- public static void main(String[] args){
- try{
- long begin = (new Date()).getTime();
- FttpAdapter fromfile = new FttpAdapter("fttp://192.168.0.1/home/ someone/fttp/tmp/a.log");
- FttpAdapter tofile = fromfile.copyTo("fttp://192.168.0.2/home/someone/ fttp/tmp/a.log");
- if(tofile!=null)
- System.out.println("copy ok.");
- long end = (new Date()).getTime();
- System.out.println("time:"+(end-begin)/1000+"s");
- }catch(FttpException fe){
- fe.printStackTrace();
- }
- }
- }
如果要进行并行复制,可以使用tryCopyTo,它的使用和copyTo一样,只不过是立即返回一个Result<FttpAdapter>对象,需要检查Result的getStatus是否复制完成,状态显示就绪代表复制已完成,这时可以获取到复制后的文件对象。
FttpMulCopyDemo演示了将一台计算机上的a.log文件并行复制到4台计算机上,并通过结果状态检查复制是否完成。
下面是内网环境下向4台机器复制1GB文件的测试结果(均为4核4GB内存配置):
❏ 内网(并行复制):完成工作的耗时为39秒,速度大约是105M/s。
❏ 内网(串行复制):完成工作的耗时为60秒,速度大约是68M/s。
❏ 由此可以观察到内网并行复制的速度比串行要快很多。
❏ 局域网的传输数据的极限是100M/s,传统的串行复制无法超越这个速度,但是并行的传送总量和花费时间算下来会优于串行传送。
❏ 外网环境受网络带宽局限,速度大约是3.6M/s。
运行步骤如下:
1)启动ParkServerDemo:
- java -cp fourinone.jar; ParkServerDemo
2)在每台机器上启动FttpServer:
- java -cp fourinone.jar; FttpServer 192.168.0.1
- java -cp fourinone.jar; FttpServer 192.168.0.2
- java -cp fourinone.jar; FttpServer 192.168.0.3
- java -cp fourinone.jar; FttpServer 192.168.0.4
- java -cp fourinone.jar; FttpServer 192.168.0.5
可以通过访问http://localhost:9080/admin/fttp.jsp检查集群文件系统启动状况。
3)运行FttpMulCopyDemo:
- java -cp fourinone.jar; FttpMulCopyDemo
完整demo源码如下:
- // FttpMulCopyDemo
- import com.fourinone.FttpAdapter;
- import com.fourinone.FttpException;
- import com.fourinone.FileAdapter;
- import com.fourinone.Result;
- import java.util.Date;
- public class FttpMulCopyDemo
- {
- public static void main(String[] args){
- long begin = (new Date()).getTime();
- try{
- Result<FttpAdapter>[] rs = new Result[4];
- String fromfttp = "fttp://192.168.0.1/home/someone/fttp/tmp/a.log";
- FttpAdapter fa1 = new FttpAdapter(fromfttp);
- FttpAdapter fa2 = new FttpAdapter(fromfttp);
- FttpAdapter fa3 = new FttpAdapter(fromfttp);
- FttpAdapter fa4 = new FttpAdapter(fromfttp);
- rs[0]=fa1.tryCopyTo("fttp://192.168.0.2/home/someone/fttp/tmp/a.log", FileAdapter.m(1));
- rs[1]=fa2.tryCopyTo("fttp://192.168.0.3/home/someone/fttp/tmp/a.log", FileAdapter.m(1));
- rs[2]=fa3.tryCopyTo("fttp://192.168.0.4/home/someone/fttp/tmp/a.log", FileAdapter.m(1));
- rs[3]=fa4.tryCopyTo("fttp://192.168.0.5/home/someone/fttp/tmp/a.log", FileAdapter.m(1));
- int n=0;
- while(n<4){
- for(int i=0;i<rs.length;i++){
- if(rs[i]!=null&&rs[i].getStatus()!=Result.NOTREADY){
- System.out.println(i+",getStatus:"+rs[i].getStatus()+",getResult:"+rs[i]. getResult());
- rs[i]=null;
- n++;
- }
- }
- }
- fa1.close();
- fa2.close();
- fa3.close();
- fa4.close();
- }catch(FttpException fe){
- fe.printStackTrace();
- }
- long end = (new Date()).getTime();
- System.out.println("time:"+(end-begin)/1000+"s");
- }
- }