6.5 集群内文件复制和并行复制

集群内文件复制是经常要应对的需求,比如备份容灾,文件迁移,同步数据等。

FttpAdapter提供了简单高效的文件复制方法,支持远程文件的集群内复制:

  1. FttpAdapter fromfile = new FttpAdapter("fttp://192.168.0.1/home/log/a.log");
  2. FttpAdapter tofile = fromfile.copyTo("fttp://192.168.0.2/home/log/ a.log",FileAdapter.m(1));

上面代码代表将a.log文件复制到其他机器并得到相应的文件对象。

这里的copyTo方法的第二个参数,表示复制时,每次以1M/S的速度传输:

  1. FileAdapter.m(1) 1M
  2. FileAdapter.g(1) 1G
  3. FileAdapter.k(1) 1k

数字1可以自由设置为其他数字,copyTo的默认值是每次以1M/S的速度复制,可以根据网络情况调整这个参数,达到最优化。

6.5 集群内文件复制和并行复制 - 图1注意

这里的复制方法名叫做copyTo而不是copy,因为它们之间存在区别,copyTo只是将前一文件内容复制到后一文件内容里,追加到末尾,但并不从头覆盖前一个文件的内容。通常在操作系统上覆盖文件,在用户不知情的情况下弹出警告框提示获得同意,因此copyTo能避免在未经许可下覆盖旧文件。如果你需要这样做,可以参考6.6节“读写远程文件”,设置读写位置为文件开始,从头覆盖文件内容。

FttpCopyDemo演示了集群中两台机器间的复制功能。

运行步骤如下:

1)启动ParkServerDemo:

  1. java -cp fourinone.jar; ParkServerDemo

2)在192.168.0.1机器上启动FttpServer:

  1. java -cp fourinone.jar; FttpServer 192.168.0.1

3)在192.168.0.2机器上启动FttpServer:

  1. java -cp fourinone.jar; FttpServer 192.168.0.2

4)运行FttpCopyDemo:

  1. java -cp fourinone.jar; FttpCopyDemo

完整demo源码如下:

  1. // FttpCopyDemo
  2. import com.fourinone.FttpAdapter;
  3. import com.fourinone.FttpException;
  4. import java.util.Date;
  5.  
  6. public class FttpCopyDemo
  7. {
  8. public static void main(String[] args){
  9. try{
  10. long begin = (new Date()).getTime();
  11. FttpAdapter fromfile = new FttpAdapter("fttp://192.168.0.1/home/ someone/fttp/tmp/a.log");
  12. FttpAdapter tofile = fromfile.copyTo("fttp://192.168.0.2/home/someone/ fttp/tmp/a.log");
  13. if(tofile!=null)
  14. System.out.println("copy ok.");
  15. long end = (new Date()).getTime();
  16. System.out.println("time:"+(end-begin)/1000+"s");
  17. }catch(FttpException fe){
  18. fe.printStackTrace();
  19. }
  20. }
  21. }

如果要进行并行复制,可以使用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:

  1. java -cp fourinone.jar; ParkServerDemo

2)在每台机器上启动FttpServer:

  1. java -cp fourinone.jar; FttpServer 192.168.0.1
  2. java -cp fourinone.jar; FttpServer 192.168.0.2
  3. java -cp fourinone.jar; FttpServer 192.168.0.3
  4. java -cp fourinone.jar; FttpServer 192.168.0.4
  5. java -cp fourinone.jar; FttpServer 192.168.0.5

可以通过访问http://localhost:9080/admin/fttp.jsp检查集群文件系统启动状况。

3)运行FttpMulCopyDemo:

  1. java -cp fourinone.jar; FttpMulCopyDemo

完整demo源码如下:

  1. // FttpMulCopyDemo
  2. import com.fourinone.FttpAdapter;
  3. import com.fourinone.FttpException;
  4. import com.fourinone.FileAdapter;
  5. import com.fourinone.Result;
  6. import java.util.Date;
  7.  
  8. public class FttpMulCopyDemo
  9. {
  10. public static void main(String[] args){
  11. long begin = (new Date()).getTime();
  12. try{
  13. Result<FttpAdapter>[] rs = new Result[4];
  14. String fromfttp = "fttp://192.168.0.1/home/someone/fttp/tmp/a.log";
  15. FttpAdapter fa1 = new FttpAdapter(fromfttp);
  16. FttpAdapter fa2 = new FttpAdapter(fromfttp);
  17. FttpAdapter fa3 = new FttpAdapter(fromfttp);
  18. FttpAdapter fa4 = new FttpAdapter(fromfttp);
  19.  
  20. rs[0]=fa1.tryCopyTo("fttp://192.168.0.2/home/someone/fttp/tmp/a.log", FileAdapter.m(1));
  21. rs[1]=fa2.tryCopyTo("fttp://192.168.0.3/home/someone/fttp/tmp/a.log", FileAdapter.m(1));
  22. rs[2]=fa3.tryCopyTo("fttp://192.168.0.4/home/someone/fttp/tmp/a.log", FileAdapter.m(1));
  23. rs[3]=fa4.tryCopyTo("fttp://192.168.0.5/home/someone/fttp/tmp/a.log", FileAdapter.m(1));
  24.  
  25. int n=0;
  26. while(n<4){
  27. for(int i=0;i<rs.length;i++){
  28. if(rs[i]!=null&&rs[i].getStatus()!=Result.NOTREADY){
  29.  
  30. System.out.println(i+",getStatus:"+rs[i].getStatus()+",getResult:"+rs[i]. getResult());
  31. rs[i]=null;
  32. n++;
  33. }
  34. }
  35. }
  36.  
  37. fa1.close();
  38. fa2.close();
  39. fa3.close();
  40. fa4.close();
  41. }catch(FttpException fe){
  42. fe.printStackTrace();
  43. }
  44. long end = (new Date()).getTime();
  45. System.out.println("time:"+(end-begin)/1000+"s");
  46. }
  47. }