这个需求是由于公司里对某个空间误设置了生命周期,随着时间流逝很多文件请求不到了,关了生命周期后,之前赋予过生命周期的那些文件还是会把流程走下去,所以在稳定后需要做一次数据的搬迁。
修改的方式有几种:
第一种是七牛提供了可视化操作工具,可以让没有开发经验的人也能做修改,但按我同事的说法是很卡很卡难以操作(因为我们这个空间文件数挺多的,大概百万的文件数),我没有去尝试
第二种是七牛提供的qshell指令,具体文档 https://developer.qiniu.com/kodo/1302/qshell ,我没有使用这个的原因是,浅试了一下可以实现需求,但是list导出的文件列表格式和解冻、修改存储类型时导入文件需要的格式有差别,实际跑的时候那么大量的数据要手改的话不现实(但是qshell的list好的地方是可以filter文件存储状态和时间,可以快速导出你具体想找的文件列表)
把试用的命令贴出来以供参考:
// 导出列表
sudo ./qshell listbucket2 --start 2022-10-10 --end 2022-10-12 --storages 2 --show-fields Key,StorageType as-prod -o list.txt
// 批量解冻7天
./qshell batchrestorear as-prod 7 -i list.txt
// 批量修改存储类型
./qshell batchchtype as-prod -i list.txt
第三种是我现在使用的方式,node sdk
文档:https://developer.qiniu.com/kodo/1289/nodejs
本地起一个koa的服务,安装七牛提供的nodesdk库,按照文档配置auth,listPrefix的参数没有看到日期、当前存储类型之类的filter,我目前就只能把整个空间遍历一遍,找到归档的文件先解冻,由于解冻需要时间,所以先跑一遍做解冻,再跑一遍做存储类型修改,整体比较耗时间。
下面是具体的代码,解冻和修改两个步骤写一起了,用的时候自己切换下注释,我图省力直接放在根路由下操作了,记得把代码改好了再打开服务。
const router = require('koa-router')()
const qiniu = require('qiniu')
const {logger} = require('../logs');
// 配置你的auth相关信息
const mac = new qiniu.auth.digest.Mac(xxx, xxx);
const config = new qiniu.conf.Config();
config.zone = qiniu.zone.Zone_z0;
const bucketManager = new qiniu.rs.BucketManager(mac, config);
router.get('/', async (ctx, next) => {
limitList(null, true);
await ctx.render('index', {
title: 'Hello Koa 2!'
})
})
// 你的空间名
const bucket = 'xxxbucket';
let count = 0;
let restoreCount = 0;
function limitList(marker, isFirst) {
if (!isFirst) {
if (!marker) {
logger.error('无marker,结束!!!!!!共执行个数:' + restoreCount);
return
}
}
const options = { limit: 1000 };
if (marker) {
options['marker'] = marker;
}
bucketManager.listPrefix(bucket, options, (err, res) => {
if (!err) {
const marker = res.marker;
const data = res.items;
for (let i = 0; i < data.length; i++) {
const fileItem = data[i];
// 0标准 1低频 2归档
if (fileItem.type === 2) {
// 用于修改文件存储类型
// bucketManager.changeType(bucket, fileItem.key, 0, (e) => {
// if (e) {
// logger.error('类型修改失败:' + fileItem.key + JSON.stringify(e));
// } else {
// restoreCount++;
// logger.info('类型修改成功:' + fileItem.key);
// }
// })
// 用于解冻
const entry = bucket + ":" + fileItem.key;
bucketManager.restoreAr(entry, 7, (e) => {
if (e) {
logger.error('执行解冻失败:' + entry + JSON.stringify(e));
} else {
restoreCount++;
logger.info('执行解冻:' + entry);
}
})
}
}
count += 1000;
logger.info('---------已经遍历条目数量:' + count + '执行成功数量:' + restoreCount + '---------');
limitList(marker, false)
} else {
console.log('error:' + err)
}
})
}
module.exports = router