我正在做一些实验来了解Riak。这里有一些我发现的东西:
我有一个包含2个节点的群集和一个<{1}} 2 的存储桶类型
n_val
然后我写了一些东西:
[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
在这种情况下应该表示 vnodes 的数量?
我对这个领域很陌生。非常感谢任何指针。
答案 0 :(得分:3)
你应该区分&#34; sloppy quorum&#34;和&#34;严格的法定人数&#34;。
您可能知道,哈希函数应用于每个键,以计算该键必须位于Riak群集中的位置。散列值的整个空间称为&#34; ring&#34;,并且在vnodes(虚拟节点)之间平均划分,vnode又被分配给物理节点。分配以这样的方式完成,以确保相邻的vnode属于不同的物理节点以获得可靠性,尽管它并不总是可行的。如果打开复制(即n_val> 1),则密钥不仅写入其目标vnode,还写入环上vnode之后的几个节点(大多数情况下,不同的物理节点 - 见上文)。现在,这些是该密钥的主要节点。但是,如果是一个草率的仲裁(例如,W = 2),如果主节点不可用,则密钥的副本将写入 任何 vnode,甚至可能在同一物理节点上。没关系,因为他们会被转移到&#34;右边&#34;一旦问题得到解决且主节点可用,vnode就会立即生效。如果您不想冒复用副本甚至是临时写入同一物理节点的风险,或者想要确保客户端获得最新值,您可以explicitly require全部或至少一些写入 仅 到主要vnodes(PW = 2,&#34; P&#34;代表&#34;主要&#34;)。但这是以高可用性为代价的。相同的逻辑适用于读取。
希望这有帮助。
我强烈建议您阅读&#34; A Little Riak Book&#34;。 此外,online documentation非常出色。
答案 1 :(得分:1)
不应该在读取操作中使用的仲裁数r是指在返回数据之前需要同意的副本/物理节点的数量吗?
不完全是。读取仲裁(r)是必须提供可接受响应的vnode的数量。当您向下读取一个节点时,群集的其余部分(在这种情况下是剩余节点)将根据需要启动任何缺少的vnode的回退。
当r = 2的读取请求到达时,由于preflist中的一个vnode不可用,因此启动了回退。当然,当首次启动时,该回退是空的,因此读取进程不会从回退中获得,而存储的对象也从另一个回收。
这里的技巧是存储桶属性或请求选项中的notfound_ok
设置。如果保留默认值notfound_ok=true
,则notfound被视为有效响应,因此操作符合仲裁,数据响应优先于未发现,客户端返回一个对象。这也会触发读取修复,它将填充该对象的后备,以便下一个获取请求将获得2个对象,并且没有未发现的响应。
如果notfound_ok为false,则第一个读取请求将只看到1个有效响应并失败,但仍然会发生读取修复,因此下一个r = 2请求成功,因为回退也有数据。
使用r = 1,notfound_ok = false进行读取以获得高可用性和尽可能快的响应是一种有效的策略,同时保持合理的保证,当节点发生故障时,您不会得到错误的未发现的响应。