【问题标题】:Amazon S3 - ColdFusion's fileExists breaks when file was deleted by s3cmdAmazon S3 - 当文件被 s3cmd 删除时,ColdFusion 的 fileExists 中断
【发布时间】:2014-12-01 10:54:18
【问题描述】:

我在 ColdFusion 9 上运行一个站点,该站点将缓存信息存储在 Amazon S3 上。

ColdFusion 应用程序构建文件并将它们放入 Amazon S3。每隔N 小时,缓存就会被一个执行s3cmd del 的bash 脚本刷新,因为它比ColdFusion 的fileDeletedirectoryDelete 效率更高。

但是,在文件被 s3cmd 删除后,ColdFusion 仍会将其标记为现有文件,即使它无法读取其内容。

对于 ColdFusion 应用,我在 Application.cfc 上提供了 S3 凭据,它们与 s3cmd 使用的身份验证密钥相同,因此我认为这不是用户权限问题。

让我们来看看这个过程:

// Create an S3 directory with 3 files
fileWrite( myBucket & 'rabbits/bugs-bunny.txt', 'Hi there, I am Bugs Bunny' );
fileWrite( myBucket & 'rabbits/peter-rabbit.txt', 'Hi there, I am Peter Rabbit' );
fileWrite( myBucket & 'rabbits/roger-rabbit.txt', 'Hi there, I am Roger Rabbit' );

 

writeDump( var = directoryList(myBucket & 'rabbits/', 'true', 'name' ), label = 'Contents of the rabbits/ folder on S3' );

 

// Delete one of the files with ColdFusion's fileDelete
fileDelete( myBucket & 'rabbits/roger-rabbit.txt' );

 

writeDump( var = directoryList(myBucket & 'rabbits/', 'true', 'name' ), label = 'Contents of the rabbits/ folder on S3' );

 

// Now, let's delete a file using the command line:
[~]$ s3cmd del s3://myBucket/rabbits/peter-rabbit.txt
File s3://myBucket/rabbits/peter-rabbit.txt deleted

 

writeDump( var = directoryList(myBucket & 'rabbits/', 'true', 'name' ), label = 'Contents of the rabbits/ folder on S3' );

 

// So far, so good!
// BUT!... ColdFusion still thinks that peter-rabbit.txt exists, even
// though it cannot display its contents

writeOutput( 'Does bugs-bunny.txt exist?: ' & fileExists(myBucket & 'rabbits/bugs-bunny.txt') );
writeOutput( 'Then show me the content of bugs-bunny.txt: ' & fileRead(myBucket & 'rabbits/bugs-bunny.txt') );

writeOutput( 'Does peter-rabbit.txt exist?: ' & fileExists(myBucket & 'rabbits/peter-rabbit.txt') );
writeOutput( 'Then show me the content of peter-rabbit.txt: ' & fileRead(myBucket & 'rabbits/peter-rabbit.txt') );
// Error on fileRead(peter-rabbit.txt) !!!

【问题讨论】:

  • 可能是因为S3返回xml结果。 ColdFusion 甚至返回所有返回非 404 结果的 url。我认为这就是你认为它是真实的原因。
  • @PriteshPatel 我不这么认为,因为当我使用 fileDelete('roger') 删除文件时,fileExists('roger') 会按预期返回 false。这有点像 CF “缓存”目录中的文件列表,当它们被 s3cmd 等外部​​服务删除时不会刷新它
  • 我觉得我读得太快了:(
  • Xevi - 我认为您的问题是延迟。如果您等待的时间足够长 - 说几分钟。这个问题是否持续存在? CF 目录列表最终会反映已删除的文件吗? S3 的幕后发生了很多事情。
  • @MarkAKruger - 是的,我认为在测试过程中的某个时刻,我看到 CF 最终反映了已删除的文件。但是我需要我的应用程序的最新信息...您认为我不应该混合技术并仅使用冷融合或仅使用 s3cmd 进行所有写入/删除/读取操作吗?

标签: amazon-web-services coldfusion amazon-s3 coldfusion-9 s3cmd


【解决方案1】:

我同意@MarkAKruger 的评论,即这里的问题是延迟。

鉴于 ColdFusion 无法始终如一地判断文件是否存在,但它确实始终如一地读取其最新内容(并且在它们不可用时始终无法读取它们),我想出了这个解决方案:

string function cacheFileRead(
    required string cacheFileName
){
    var strContent = '';

    try{
        strContent = FileRead( ARGUMENTS.cachefileName );
    }catch(Any e){
        strContent = '';
    }

    return strContent;
}

【讨论】:

  • 是的!尝试捕获将始终有效 - 请记住有意依赖抛出的错误 - 尤其是文件读取错误 - 在资源方面非常昂贵。密切关注您的可扩展性;)
【解决方案2】:

此答案假定延迟是您的问题,正如我在上面的 cmets 中所断言的那样。

我想我会跟踪 s3cmd 的运行时间。如果您通过 CFEXECUTE 运行它,则将时间戳存储在应用程序范围或文件或数据库表中。然后,在检查文件时,如果该命令已在最后 N 分钟内运行(您必须尝试找出什么是有意义的),您将自动重新缓存。当 N 分钟过去后,您可以相信您的检查系统是可靠的。

如果您从 cfexecute 运行 s3cmd,请尝试创建一个脚本来更新应用程序范围内的时间戳,然后将 curl 命令添加到您的 s3cmd 脚本中,该命令会命中您的 cf 脚本 - 保留 2进程同步。

您的另一个选择是不断使用 fileExists() (不是一个好主意 - 非常昂贵)或跟踪缓存的内容或未缓存的内容,以其他可以实时更新的方式 - 例如数据库表。然后,您需要从 s3cmd 脚本中清除该表(可能使用 mysql 命令行)。

我可能会想些别的给你。这就是我现在所拥有的。 :)

【讨论】:

  • 谢谢马克,但我无法找到一致且可靠的 N 分钟数...我将我的解决方案发布在单独的答案中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-05
  • 2012-03-28
  • 2018-11-09
相关资源
最近更新 更多