AWS Lambda /tmp 文件夹不在执行之间共享
AWS Lambda /tmp folder is not shared between executions
我正在尝试为 AWS lambda 函数执行临时缓存一些数据,以忽略此 lambda 现在每次执行的 HTTP 请求并优化其速度。
在“观众请求”中我有以下逻辑(示例是伪代码)-
exports.handler = async (event) => {
// check /tmp folder for data
const cachedData = await getDataFromCache();
if (cachedData) {
return cachedData;
}
const data = await getDataFromApi();
// save data for 2 mins in /tmp for re-use in next executions
await saveDataInCache(data);
return data;
}
如您所见,我试图将数据保存在 /tmp
文件夹中几分钟,以便在下次执行时重新使用它并减少 API 请求的数量.
在“查看器请求”lambda 执行期间,当我在 /tmp
文件夹中缓存数据时,我立即看到数据在日志中可用 -
async function saveDataInCache(data = {}) {
// save data in tmp folder
try {
await fs.outputJson('/tmp/cache.json', {
data,
updatedAt: Date.now()
});
} catch (err) {
console.log(`page data save cache error ${err}`);
}
// check that data is immediately available
let fileData = {};
try {
fileData = await fs.readJson('/tmp/cache.json');
} catch (err) {
console.log(`page data read cache error ${err}`);
}
console.log(`check immediate value ${JSON.stringify(fileData)}`);
}
但是每次“查看器请求”尝试在保存前读取数据时,它总是 returns 错误 - ENOENT: no such file or directory, open '/tmp/cache.json'
-
async function getDataFromCache() {
let fileData = {};
try {
fileData = await fs.readJson('/tmp/cache.json');
} catch (err) {
console.log(`page data read cache error ${err}`);
}
if (isEmpty(fileData)) {
return undefined;
}
const { data = {}, updatedAt = 0 } = fileData;
const maxCacheTime = updatedAt + DATA_TTL;
const currentTime = Date.now();
const isCacheExpired = currentTime > maxCacheTime;
if (!isCacheExpired) {
return data;
}
return undefined;
}
这是否意味着 /tmp
文件夹内容在执行之间不共享?谢谢!
/tmp
目录是每个 Lambda instance/execution 上下文的私有目录,并非在所有 Lambda 实例之间共享。
这意味着如果您的请求由不同的执行上下文处理,数据将不会出现在那里。
不幸的是,您无法真正控制这些执行上下文的创建和删除方式,这是 Lambda 在后台为您处理的事情。
简短的回答就像 Maurice 所说的那样,/tmp 对于每个容器都是唯一的,所以如果你幸运的话,你会得到相同的容器,但不能保证。处理容器后,所有文件都消失了。
如果您需要 Lambda 之间真正的持久存储,请使用 EFS, S3, or Lambda layers。
也就是说有什么用例?
Cache.json 在每次执行期间更新
然后使用 EFS/s3(比 EFS 慢一点)或者 NoSQL 数据库,如果你已经在使用一个,另一个集合不会改变世界而且会非常快。
静态文件cache.json
要么将其与您的 lambda 代码捆绑在一起,要么将其放在一个层中!
我正在尝试为 AWS lambda 函数执行临时缓存一些数据,以忽略此 lambda 现在每次执行的 HTTP 请求并优化其速度。
在“观众请求”中我有以下逻辑(示例是伪代码)-
exports.handler = async (event) => {
// check /tmp folder for data
const cachedData = await getDataFromCache();
if (cachedData) {
return cachedData;
}
const data = await getDataFromApi();
// save data for 2 mins in /tmp for re-use in next executions
await saveDataInCache(data);
return data;
}
如您所见,我试图将数据保存在 /tmp
文件夹中几分钟,以便在下次执行时重新使用它并减少 API 请求的数量.
在“查看器请求”lambda 执行期间,当我在 /tmp
文件夹中缓存数据时,我立即看到数据在日志中可用 -
async function saveDataInCache(data = {}) {
// save data in tmp folder
try {
await fs.outputJson('/tmp/cache.json', {
data,
updatedAt: Date.now()
});
} catch (err) {
console.log(`page data save cache error ${err}`);
}
// check that data is immediately available
let fileData = {};
try {
fileData = await fs.readJson('/tmp/cache.json');
} catch (err) {
console.log(`page data read cache error ${err}`);
}
console.log(`check immediate value ${JSON.stringify(fileData)}`);
}
但是每次“查看器请求”尝试在保存前读取数据时,它总是 returns 错误 - ENOENT: no such file or directory, open '/tmp/cache.json'
-
async function getDataFromCache() {
let fileData = {};
try {
fileData = await fs.readJson('/tmp/cache.json');
} catch (err) {
console.log(`page data read cache error ${err}`);
}
if (isEmpty(fileData)) {
return undefined;
}
const { data = {}, updatedAt = 0 } = fileData;
const maxCacheTime = updatedAt + DATA_TTL;
const currentTime = Date.now();
const isCacheExpired = currentTime > maxCacheTime;
if (!isCacheExpired) {
return data;
}
return undefined;
}
这是否意味着 /tmp
文件夹内容在执行之间不共享?谢谢!
/tmp
目录是每个 Lambda instance/execution 上下文的私有目录,并非在所有 Lambda 实例之间共享。
这意味着如果您的请求由不同的执行上下文处理,数据将不会出现在那里。
不幸的是,您无法真正控制这些执行上下文的创建和删除方式,这是 Lambda 在后台为您处理的事情。
简短的回答就像 Maurice 所说的那样,/tmp 对于每个容器都是唯一的,所以如果你幸运的话,你会得到相同的容器,但不能保证。处理容器后,所有文件都消失了。
如果您需要 Lambda 之间真正的持久存储,请使用 EFS, S3, or Lambda layers。
也就是说有什么用例?
Cache.json 在每次执行期间更新
然后使用 EFS/s3(比 EFS 慢一点)或者 NoSQL 数据库,如果你已经在使用一个,另一个集合不会改变世界而且会非常快。
静态文件cache.json
要么将其与您的 lambda 代码捆绑在一起,要么将其放在一个层中!