在我们的场景中,我们将本地CouchDB连接到生成数据的node.js服务器。数据包括用户及其对此数据库中某些表的访问权限。
应将此本地CouchDB实例复制到云中的远程CouchDB,包括每个数据库的表 _users和_security 中指定的用户和安全规则。
将所有数据复制到远程CouchDB可以正常工作,但问题是:
只有服务器和数据库管理员才能创建用户。因此,复制任务需要管理员凭据。如果没有其他解决方案,我认为我可以忍受。
_security文档是无版本的,因此无法复制。
即使本地CouchDB实例在用户创建时处于脱机状态,是否有一种保持两个数据库同步的好方法。 (用户和安全)。
更新
我想到的一种方法是在服务器上创建一个设计文档,每次创建新用户时都会调用该文档。然后,此函数为新创建的用户创建新数据库,并将用户名添加到_security规则。
我希望避免服务器上的其他应用程序收听 _changes Feed并对新的更新采取行动。
答案 0 :(得分:0)
我想到的一种方法是在服务器上创建一个设计文档,每次创建新用户时都会调用该文档。然后,此函数为新创建的用户创建新数据库,并将用户名添加到_security规则。
有一个名为couch per user的插件可以让你做到这一点。安装它,对于_users数据库中的每个新user
,它将自动为该用户创建一个数据库。
你是对的_security文件没有版本。但是常规文件是。因此,如果将_security对象存储为常规couchdb文档,则可以解决复制它们的问题。现在我们需要确保的是,当复制包含_security对象的文档时,它会自动添加到目标数据库的_security中。
如果您认为验证功能为"更新前"事件处理程序然后他们可以用于此任务。我们需要做的是
现在默认的javascript验证功能无法进行http调用,因此您需要更改query server。我知道至少erlang和python查询服务器允许你进行http调用。但首先尝试用你最喜欢的语言。
示例: -
{
_id:adsfasf,
_rev:3-bd25f9790db7a8034d9415da7a4d625,
"type":"security",
_security:
{
"admins": {
"names": [
"superuser"
],
"roles": [
"admins"
]
},
"members": {
"names": [
"user1",
"user2"
],
"roles": [
"developers"
]
}
}
}
}
验证功能
function(newDoc,oldDoc,userCtx,secObj){
if(newDoc.type ==="security"){
//make an http call to db/_security and post the _security field there
}
}
您不需要以这种方式收听更改Feed。只需使用普通的couchdb文档和验证函数的组合(在不同的查询服务器中),您就可以执行所需的操作。
效果问题
拥有验证功能肯定会减慢插入时间,因为它会在插入之前对每个couchdb文档执行检查。
Erlang验证功能将是不同查询服务器中速度最快,资源效率最高的功能。在erlang中编写它不是太困难,因为它只是一个if块和一个http请求。这个例子未经测试,但它应该让你开始。
fun({N_Doc},_Old_Doc,_User,_Sec)->
case proplists:get_value(<<"type">>,N_Doc) of
<<"_serurity">>->
httpc:request(
post,
{"http://localhost:5984/yourdb/_security",
[],
"application/json",
ejson:encode(proplists:get_value(<<"_security">>))},
[],[]),
1;
<<"some_bad_value">>->
{[{<<"forbidden">>, "Nope this won't do"}]};
_->
1
end
end.
上面的函数只是等待类型&#34; security&#34;的文档。并将其发布到数据库的_security端点。 1
回复意味着每件事都没问题。该文档已经过验证,现在可以存储。禁止响应不允许存储文档。希望这可以帮助。
答案 1 :(得分:0)
我刚刚发布了一个名为replicate-couchdb-cluster的新工具,它提供了一种容错方式来复制整个数据库集群。它还允许并发,因此可以大大加快复制群集所需的时间。
您还可以使用docker image轻松设置连续复制。
我希望这有帮助!