0

我正在做一些实验来了解 Riak。这是我发现的一些有趣的东西:

n_val我有一个包含 2 个节点的集群和一个包含2个节点的存储桶类型

[root@co-riak002 ~]# riak-admin ring-status
================================== Claimant ===================================
Claimant:  'riak@10.172.48.68'
Status:     up
Ring Ready: true

============================== Ownership Handoff ==============================
No pending changes.

============================== Unreachable Nodes ==============================
All nodes are up and reachable

[root@co-riak002 ~]# riak-admin bucket-type create testBucket '{"props":{"n_val":2}}'
testBucket created
[root@co-riak002 ~]# riak-admin bucket-type activate testBucket                        
testBucket has been activated

然后我在里面写了一些东西:

[root@co-riak002 ~]# curl -XPUT -d '{"bar":"foo"}' -H "Content-Type: application/json" http://localhost:8098/types/testBucket/buckets/stuff/keys/hello?w=2&returnbody=true
[1] 10890
[root@co-riak002 ~]# 
[1]+  Done                    curl -XPUT -d '{"bar":"foo"}' -H "Content-Type: application/json" http://localhost:8098/types/testBucket/buckets/stuff/keys/hello?w=2

r=2现在我可以用和很好地阅读它pr=2

[root@co-riak002 ~]# curl http://localhost:8098/types/testBucket/buckets/stuff/keys/hello?r=2
{"bar":"foo"}
[root@co-riak002 ~]# curl http://localhost:8098/types/testBucket/buckets/stuff/keys/hello?pr=2
{"bar":"foo"}

在我杀死了一个节点后,r=2仍然可以正常读取,但不能pr=2

[root@co-riak002 ~]# riak-admin ring-status
================================== Claimant ===================================
Claimant:  'riak@10.172.48.68'
Status:     up
Ring Ready: true

============================== Ownership Handoff ==============================
No pending changes.

============================== Unreachable Nodes ==============================
The following nodes are unreachable: ['riak@10.172.48.66']

r=2

[root@co-riak002 ~]# curl http://localhost:8098/types/testBucket/buckets/stuff/keys/hello?r=2
{"bar":"foo"}

pr=2

[root@co-riak002 ~]# curl http://localhost:8098/types/testBucket/buckets/stuff/keys/hello?pr=2
PR-value unsatisfied: 1/2

我很困惑 -r读取操作中使用的仲裁数不应该意味着在返回数据之前需要同意的副本/物理节点的数量吗?为什么它在这种情况下不起作用?pr当它应该意味着vnodes的数量时,为什么在这种情况下工作?

我对这个空间很陌生。非常感谢任何指针。

4

2 回答 2

3

你应该区分“草率的法定人数”和“严格的法定人数”。

您可能知道,哈希函数应用于每个键以计算该键在 Riak 集群中的位置。散列值的整个空间称为“环”,并在 vnode(虚拟节点)之间平均分配,而这些虚拟节点又被分配给物理节点。分配是以这样一种方式完成的,以确保相邻的 vnode 属于不同的物理节点以提高可靠性,尽管这并不总是可能的。如果打开了复制(即 n_val > 1),一个密钥不仅会写入其目标 vnode,还会写入环上 vnode 之后的几个节点(大多数情况下是不同的物理节点 - 见上文)。现在,这些是该密钥的主节点。但是,在一个草率的仲裁(例如,W = 2)的情况下,如果主节点不可用,vnode,甚至可能在同一个物理节点上。没关系,因为一旦问题得到解决并且主节点可用,它们就会被移交给“正确的”vnode。如果您不想冒险将副本写入同一个物理节点,即使是临时的,或者想确保客户端接收到最新的值,您可以明确要求进行所有或至少一些写入到主要 vnode(PW = 2,“P”代表“主要”)。但是,这是以牺牲高可用性为代价的。相同的逻辑适用于读取。

希望这可以帮助。

我强烈推荐你阅读“ A Little Riak Book ”。此外,在线文档非常好。

于 2015-10-02T17:53:49.770 回答
1

读取操作中使用的仲裁数 r 不应该是在返回数据之前需要同意的副本/物理节点的数量吗?

不完全是。read quorum(r) 是必须提供可接受响应的 vnode 数量。当您在一个节点关闭的情况下阅读时,集群的其余部分(在本例中为剩余节点)将根据需要为任何丢失的 vnode 启动回退。

当您的 r=2 读取请求到达时,由于 preflist 中的一个 vnode 不可用,因此启动了回退。自然,第一次启动时该回退是空的,因此读取过程从回退接收 notfound 并从另一个接收存储对象。

这里的技巧是notfound_ok存储桶属性或请求选项中的设置。如果保留默认notfound_ok=true的 notfound 被认为是一个有效的响应,所以操作满足仲裁,带有数据的响应胜过 notfound,客户端取回一个对象。这也会触发读取修复,它将使用该对象填充回退,因此下一个获取请求将获得 2 个对象并且没有未找到的响应。

如果 notfound_ok 为 false,第一个读取请求将只看到 1 个有效响应并失败,但读取修复仍然发生,因此下一个 r=2 请求成功,因为回退也有数据。

使用 r=1, notfound_ok=false 进行读取以获得高可用性和尽可能快的响应是一种有效的策略,同时保持合理的保证,即当节点发生故障时您不会得到错误的未找到响应。

于 2015-10-30T09:09:13.207 回答