1

我有一个由 5 个 Riak-CS 节点组成的虚拟集群。Stanchion 安装在第一个节点上。这些节点位于 Nginx 反向代理之后。

当我使用使用 boto 库的 Python 脚本上传 JPG 文件时,它可以正常工作:

cf=OrdinaryCallingFormat()
conn=S3Connection(aws_access_key_id=apikey,aws_secret_access_key=secretkey,is_secure=False,host=s3Host,port=s3Port,calling_format=cf)
b = conn.get_bucket(bucketName)
k = b.new_key(fileName)
k.set_contents_from_filename(fileName, policy='public-read')

但是,如果我这样做,它有时不会将 ACL 设置为公开,但有时会(注意:我先上传文件,然后设置 ACL):

cf=OrdinaryCallingFormat()
conn=S3Connection(aws_access_key_id=apikey,aws_secret_access_key=secretkey,is_secure=False,host=s3Host,port=s3Port,calling_format=cf)
b = conn.get_bucket(bucketName)
k = b.new_key(fileName)
k.set_contents_from_filename(fileName)
k.set_acl('public-read')

我检查了 Nginx 上的日志文件,发现在第一种情况下,我们有以下内容:

"HEAD /test/ HTTP/1.1" 200 0 "-" "Boto/2.29.1 Python/2.7.3 Windows/7"
"PUT /test/1.jpg HTTP/1.1" 200 25 "-" "Boto/2.29.1 Python/2.7.3 Windows/7"

在第二种情况下,我们得到:

"HEAD /test/ HTTP/1.1" 200 0 "-" "Boto/2.29.1 Python/2.7.3 Windows/7"
"PUT /test/1.jpg HTTP/1.1" 200 25 "-" "Boto/2.29.1 Python/2.7.3 Windows/7"
"PUT /test/1.jpg?acl HTTP/1.1" 200 0 "-" "Boto/2.29.1 Python/2.7.3 Windows/7"

这两者都是可以预料的。

我正在使用“s3cmd info s3://test/1.jpg”来找出文件中的 ACL 是什么。似乎取决于将 PUT acl 发送到哪个 Riak-CS 服务器,有时文件会更改为公共文件,有时则不会。我已经检查了来自运行脚本的机器的网络流量,并且无论失败是否成功,每次放置新 ACL 的命令都是完全相同的。通过 NGINX 的消息每次也完全相同,即使它没有将 ACL 更新为 public,它仍然返回 200。

我在上传过程中监控了每个节点上的 Riak-CS 日志文件,它似乎只发生在 5 个不同的上传场景中的两个中。以下是详细信息:

该文件在节点 4 上为 PUT,ACL 在节点 3 上为 PUT。查询文件的 ACL(S3Cmd 信息)是否针对节点 1 执行且结果为成功,ACL 具有公共访问集。这里还有一些案例->

Obj PUT Node: 4  ACL PUT Node: 3  Read Node: 1 = Success
Obj PUT Node: 3  ACL PUT Node: 2  Read Node: 5 = Success
Obj PUT Node: 2  ACL PUT Node: 1  Read Node: 4 = Fail
Obj PUT Node: 1  ACL PUT Node: 5  Read Node: 3 = Success
Obj PUT Node: 5  ACL PUT Node: 4  Read Node: 2 = Fail
Obj PUT Node: 4  ACL PUT Node: 3  Read Node: 1 = Success
Obj PUT Node: 3  ACL PUT Node: 2  Read Node: 5 = Success
Obj PUT Node: 2  ACL PUT Node: 1  Read Node: 4 = Fail
Obj PUT Node: 1  ACL PUT Node: 5  Read Node: 3 = Success
Obj PUT Node: 5  ACL PUT Node: 4  Read Node: 2 = Fail

正如您所看到的,有时 ACL “Sticks”,有时则没有。我检查了所有节点的配置,尤其是 1 和 4 并且看不到任何问题。

有谁知道为什么有时这不起作用或有任何想法我可以如何继续调查这里发生的事情?

4

1 回答 1

2

这是由 Riak CS [1] 的 bug 和服务器之间的时钟不同步造成的。详细的错误描述,请参见[1]。

当前的解决方法是同步服务器时钟。我猜,如果你能以 100 毫秒的速度同步它们,那么可能性很小(显然,这取决于客户端 PUT Object 和 PUT Acl 之间的间隔,以及客户端和 riak cs 之间的网络延迟)。如果它不起作用,请在客户端代码中的 PUT 对象之后添加一些等待:P

非常感谢您详细的成功/失败模式分析,马克。它导致了快速的错误识别:)

[1] https://github.com/basho/riak_cs/issues/879

于 2014-06-07T00:26:09.973 回答