相册存储文件要往分布式系统服务器上迁移,技术上涉及到以下方面:
1)从windows服务器上迁移到linux服务器
2)目录结构不同
3)存储需要的图片从大图,小图变更为大图,中图,小图。
4)涉及到数据量大小达2.5T
5)数据库迁移
技术实施方案:
1)创建目录,根据目录结构规则创建出目录, 迁移过程中不再去判断目录是否存在,不再去创建目录。这个步骤关键,能大量减少迁移时间。
2)先迁移存储文件,后迁移数据库,并在旧应用上做出增量日志记录
3)迁移程序需要能指定某台被迁移服务器进行迁移,目前有20台存储服务器,有些已经关闭上传口,这部分优先迁移
4)迁移过程中能根据photoid进行分段迁移,程序出错或者意外终止时,能从日志中已经执行到最后的photoid开始执行
5)使用多线程,需要监控服务器,通过测试数服务器的io分析,需找出开启多少条线程同时迁移是最佳方案,我目前的标准是服务器CPU使用率达到70%左右。
6)使用程序迁移数据库,数据表结构已经产生变化。
关键代码:
public static void runList(String serNum, String size, String pId) {
// 根据参数获取数据列表
int threadNum = 5;
List<PhotoVO> photoList = PhotoDAO.getPhotoInfo(serNum, size, pId);
if (null != photoList && photoList.size() > 0) {
int allCount = photoList.size();
int StartRow = 0;
int EndRow = 0;
int PageSize = (allCount / threadNum)+1;
for (int i = 0; i < threadNum; i++) {
StartRow = PageSize * i;
EndRow = PageSize * (i + 1);
EndRow = EndRow > photoList.size() ? photoList.size() : EndRow;
final List<PhotoVO> sublatestInfo = photoList.subList(StartRow, EndRow);
final int _i = i;
new Thread(new Runnable() {
public void run() {// 循环列表
// 开始迁移时间
Date dtRun = new Date();
int _j = 1;
int migrated = 0;
for (PhotoVO photoVO : sublatestInfo) {
if(runImport(photoVO)>0)
migrated++;
_j++;
}
// 结束时间
Date dtEnd = new Date();
// 计算时间差
long s = (dtEnd.getTime() - dtRun.getTime()) / 1000;
// 打印线程执行结果
System.out.println("------------------------- Thread_"+_i+", total time: " + s + "(s) --------------------------------------");
System.out.println("------------------------- Thread_"+_i+", total count: " + sublatestInfo.size() + ", migrated count: " + migrated + " --------------------------------------");
}
}).start();
}
}
}