我的问题可能是由于我对谷歌存储的全球一致性的误解,但由于我直到最近(11月中旬)才发现这个问题,现在看起来很容易重现,我想要一些澄清。问题开始发生在使用bdutil在计算引擎上运行的一段火花代码中,但我可以使用gsutil从命令行重现。
我的代码是删除目标路径,然后立即将源路径重命名为目标路径。我希望由于全局一致性,因为目标路径不再存在,src将被重命名为目标,而src将嵌套在目标中,就好像目标仍然存在且不一致。
重现的hadoop代码如下:
fs.delete(new Path(dest), true)
fs.rename(new Path(src), new Path(dest))
从命令行我可以重现:
gsutil -m rm -r gs://mybucket/dest
gsutil -m cp -r gs://mybucket/src gs://mybucket/dest
如果原因是因为列表操作最终是一致的并且FileSystem实现正在使用列表操作来确定目标是否仍然存在,那么我理解,然后是否有推荐的解决方案以确保在重命名之前目标不再存在?
谢谢, 路加
答案 0 :(得分:2)
特拉维斯的答案已经有几年了,不再是真的了。对象列表操作现在非常一致。阅读Google的post。
答案 1 :(得分:1)
写后读(包括删除)操作非常一致,例如,如果你这样做:
gsutil -m rm -r gs://mybucket/dest
# Command output shows it removed gs://mybucket/dest/file1
gsutil cp gs://mybucket/dest/file1 my_local_dir/file1
那总是会失败。
然而,要确定一个"目录"如果存在,gsutil必须执行最终一致的列表操作,以确定Google云端存储的平面名称空间中的任何对象是否具有名称为"目录"的前缀。这可能会导致您描述的问题,我希望hadoop代码的行为类似。
对于此问题,没有一个强烈一致的解决方法,因为无法以强一致的方式检查前缀是否存在。