node.js - 并发大删除操作挂在 NodeJS
问题描述
我在 Centos 7.2 服务器上运行的 NodeJS 应用程序中有一个工作区清理功能,它获取目录路径列表并删除它们。当函数接收到路径列表时,它使用Promise.all()
以下方式同时执行这些删除:
/**
* Deletes directories.
*
* @param {Array} directories Array of directories to be deleted.
*
* @returns {Object} Response object with the status code and data.
*/
const cleanup = async (directories) => {
if (!Array.isArray(directories)) {
return await responseStatementHandler(
400,
`Provide a list of directories as an array - [dir1, dir2].`,
null,
console.error
);
}
if (!directories.length > 0) {
return await responseStatementHandler(
400,
`Directory list cannot be empty.`,
null,
console.error
);
}
try {
const promisesList = await Promise.all(
directories.map((d) => deleteDirectory(d))
);
return await responseStatementHandler(
207,
await promisesList,
null,
console.log
);
} catch (err) {
return await responseStatementHandler(
500,
`Directory cleanup failed.`,
err,
console.error
);
}
};
/**
* Performs a force delete on a provided directory.
*
* @param {String} directory Path of the directory to be deleted.
*
* @returns {Object} Response object with the status code and data.
*/
const deleteDirectory = async (directory) => {
console.log(`Deleting directory: ${directory}`);
try {
if ((await fs.stat(directory)).isDirectory()) {
await fs.rm(directory, { recursive: true, force: true });
return await generateIndividualResponseObj(
directory,
200,
`Successfully deleted directory: ${directory}`,
null,
console.log
);
}
} catch (err) {
if (err.message.includes("no such file or directory")) {
return await generateIndividualResponseObj(
directory,
404,
`Could not find directory: ${directory}`,
null,
console.error
);
}
return await generateIndividualResponseObj(
directory,
500,
`Failed to delete directory: ${directory}`,
err,
console.error
);
}
};
这里的问题是目录很大;~1G 大小。所以当有多个这样的删除(>10 所以>10G)时,操作就会挂起。
我知道这是因为只要我手动删除目录,应用程序就可以正常运行而没有问题。
这是fs
模块的限制还是逻辑编写方式的限制?在这种情况下,删除操作的超时会有所帮助吗?如果是这样,我将如何使用模块实现这样的超时fs
?
解决方案
这里的问题不在于 Node。服务器有一个缓慢的硬盘驱动器,它需要很长时间才能执行大量删除。该应用程序只是在等待删除过程完成并且没有挂起。用更快的存储连接服务器解决了这个问题。
推荐阅读
- android - 将 Gradle 插件更新到 3.4.0 后引发 Resources$NotFoundException
- javascript - 显示自动完成的干净结果
- javascript - Apollo writeFragment 返回未定义但 readFragment 有效
- angular - 角度材料对话框未正确显示数据
- java - 传递给函数并用作字符串映射时,Java 对象映射不会将对象隐式转换为字符串
- uart - 发送完成回调未在 UART DMA 中被调用
- excel - 在 Excel VBA 中保存新条目不会保存新条目
- android - 当外部内容发生变化时,BottomSheet 会隐藏
- asynchronous - 如何从未来使用列表并在 listView 中使用它
- keras - 是否可以连接来自同一个 ConvNet 的 n 个输出序列并将它们输出到第二个网络而无需存储它们?