-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add couchdb clustering #2810
Add couchdb clustering #2810
Conversation
abc9a1b
to
cc0d2d3
Compare
Any more thing to do for this pr? |
@style95 as you shared on slack, the use of |
@rabbah Let me explain the issues here. In this pr, And I got comment from couchdb community that,
In short, we don't need those configurations any more. I will update the code accordingly. One question is, would it be required to add volume mapping for configuration directory as well? |
cc0d2d3
to
30ff97b
Compare
@rabbah |
1666f2e
to
08f9594
Compare
It seems Travis error is not related to this pr. |
set_fact: | ||
nodeName: "couchdb{{ groups['db'].index(inventory_hostname) }}" | ||
coordinator: "{{ groups['db'][0] }}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should use the ansible_host
of groups['db'][0] here. Otherwise we are not able to deploy two dbs on one machine (which is very useful for testing)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As you know, to setup cluster, we need only one coordinator node.
This is to get the first host among many hosts.
Is it possible to do the same thing with ansible_host
?
For examaple, if there are two nodes running on same ansible_host
, we need only one node.
state: started | ||
recreate: true | ||
restart_policy: "{{ docker.restart.policy }}" | ||
volumes: "{{volume_dir | default([])}}" | ||
ports: | ||
- "{{ db_port }}:5984" | ||
- "4369:4369" | ||
- "9100:9100" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make these ports (outside of the container) configurable and increment them for each container? Again, to be able to deploy two dbs on the same host.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to discuss this further.
Please refer to this: https://docs.couchdb.org/en/latest/cluster/setup.html#firewall
Those two ports are used when Erlang VM finds other nodes.
APAIK, 4369 is reserved to find other nodes, and 9100 is reserved to use for communication among nodes.
Normally, erlang VM uses random ports between 9100~9200, but it is forced to use 9100 only in apache/couchdb
.
Regarding 9100, I think we can change it, but we need to update apache/couchdb
image.
That should be different on every nodes, I am not sure it works in that situation.
You can refer to this: https://github.com/apache/couchdb-docker/blob/master/2.1.1/vm.args#L14
And with regard to 4369, since it is reserved at Erlang VM layer, I am not sure we can change it.
@cbickel Do you have any idea?
@cbickel any comments on this? |
url: "{{ db_protocol }}:https://{{ ansible_host }}:{{ db_port }}/_cluster_setup" | ||
method: POST | ||
body: > | ||
{"action": "enable_cluster", "bind_address":"0.0.0.0", "username": "{{ db_username }}", "password":"{{ db_password }}", "port": {{ db_port }}, "node_count": "{{ num_instances }}", "remote_node": "{{ ansible_host }}", "remote_current_user": "{{ db_username }}", "remote_current_password": "{{ db_password }}"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about using
{{ groups['db'] | length }}
Instead of defining num_instances
on the top?
This is a great Pull request. And I have an additional question. Is the intention of this PR only, to share data across multiple instances? Wouldn't it be great, if the requests against the database would be distributed across the instances? Or do you have in mind to do this later? |
Agree. It would be great if we can deploy more than one instances on a single machine for testability. Regarding the data sharing across multiple instances, do we need any further configurations to distribute data? AFAIK, from CouchDB 2.0, the number of nodes who are in charge of specific shards will be decided based on Based on the value of If you are mentioning about load-balancing(using single endpoint address) among multi nodes for HA, currently i have no idea. We may locate load-balancer in front of them or, other components to use list of endpoints. |
Ok, I didn't know yet, that if you send a request to instance 1, that it could be handled by instance2. I think for HA we need one of your proposed ideas. I just wanted to ask, if you want to address that problem already in this PR, or maybe later. |
Yes I think it would be better to address load-balancing problem in separate pr. Regarding But for example, if we configure the port as I am looking for the configuration to segregate its binding port( |
It seems, all Erlang nodes must use same epmd port. It means, we cannot run a couchdb cluster on a single machine. As of now I am trying the following scenario.
Since both nodes will be running on a single machine, they will be in the same subnet. So though port is not opened in host layer, they may be able to connect to other node using Since it assumes nodes are running on same subnet, it won't work on distributed environments. Is it worth to take this approach? |
Let me share the discussion with @cbickel. So it could be an option that running a test case in case there are more than 1 couchdb deployed(in distributed environment). I will look into |
One idea for one of the tests could be:
Do you have some more ideas? |
@style95 What would be consistency support in clustered setup. Would it be possible to read-your-own-writes? Reading here indicates that for reads and writes it would use quorum which should allow one to read its own write
However its not clear what is the semantics for queries or view access. Per here it looks like queries would not be using quorum
So in clustered setup it can happen that an action added in one step is not visible in query made in subsequent request? |
Correct: views are subject to eventual consistency and may exclude a just added/modified action (for example) until all nodes have replicated and indexed. |
Thanks @rabbah for confirming the eventual consistent nature for queries. Next question - Does Couchdb supports specifying the sharding key? Or it always shards on the basis of _id key only. In absence of sharding key all queries would need to query all shards which may have some impact on performance |
@chetanmeh If we do view query, we should access all relevant shards to create a combined result. If I misunderstood, kindly correct me. |
2feda7f
to
934bf3a
Compare
I am exploring support for running OW on Mongo and Cosomosdb which support specifying custom partition key. Looking at views used by Couchdb I see following types of queries
From my understanding of flow the "whisks" are mostly read. In a sharded setup this may benefit by using "root namespace" as sharding (partition key). In such a case the query would only need to be evaluated on single shard and avoid hitting all the shards for the whisks access. This would be specially useful for databases where sharded queries are done from client which may add higher latency. Compared to this Couchdb proxies the queries and talks to all the shards on behalf of client. As such calls happen within same data center they may incur less latency. So I am interested in this PR to see how to model OW entities on other sharded storage systems |
So you are thinking of assigning a shard per namespace, right? But if there are huge number of data, one shard may not be enough. And accessing to shards are proceeded in parallel. And in my experience, storing activation has more huge impact on performance than reading whisk entity because there is cache layer in controller. |
Ack. But it depends on kind of data being stored. This scheme may be ok for whisks where one namespace may contain say 1M entities (which can be stored in single shard). This may not work fine for activations where number of activations may of the order of 10-100M. So use of sharding key would depend on number of objects being stored
This is fine for read and write of single instance. However for queries all shards would need to be queried
Is the cache layer used for queries also or its only used for individual entity access i.e. lookups by docId? |
@chetanmeh Second, query is only used to list entities. And I can't expect such huge number of That's the reason why I think action invocation(which includes storing activations) will affect more on the performance and incline to scalable approach. And, I could not find any support for custom partition key. |
Makes sense. Would keep that in mind when modeling for other dbs
Thanks for confirming. So for couchdb the partition key decision is moot! |
The queries (list operations) are not cached today. They could be since we allow stale results and queue indexing operations in couch as configured. In general as already noted the bulk of the load isn’t on crud or query operations. |
c31ecad
to
6e30f92
Compare
I have tested this pr is working with a couchdb cluster and a single couchdb setup. |
Travis complains there is no |
@@ -94,6 +94,8 @@ db.whisk.activations={{ db.whisk.activations }} | |||
db.whisk.actions.ddoc={{ db.whisk.actions_ddoc }} | |||
db.whisk.activations.ddoc={{ db.whisk.activations_ddoc }} | |||
db.whisk.activations.filter.ddoc={{ db.whisk.activations_filter_ddoc }} | |||
db.hosts={{ groups["db"] | map('extract', hostvars, 'ansible_host') | list | join(",") }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about renaming this value to db.hostsList
as well? In the following code you always use dbHostsList.
} | ||
} | ||
|
||
def pingDB(host: String, port: Int) = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what do you think about using one ping method and passing the path
as an argument.
505f341
to
3d2da88
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. I'll take care about merging.
Thanks a lot for your contribution to OpenWhisk :)
3d2da88
to
7d77126
Compare
This is a follow-up patch to the below: - Add couchdb clustering. (apache#2810) commit e587bf8
This is a follow-up patch to the below: - Add couchdb clustering. (apache#2810) commit e587bf8
This is a follow-up patch to the below: - Add couchdb clustering. (apache#2810) commit e587bf8
* Add couchdb clustering
This pr is to deploy couchdb cluster.
From the version 2.0, CouchDB officially supports clustering.
Notable changes are as follow:
Image of CouchDB is changed to the one from Apache.
klaemo/couchdb
is superseded byapache/couchdb
.Accordingly version is also updated to 2.1
Coordinator node.
Since we need one coordinator node to setup CouchDB cluster, first host in db group becomes coordinator node.
New environment variables for cluster.
Important factors for CouchDB cluster are the number of shards and the number of quorums.
Corresponding environment variables are introduced.
Note: Please be informed that, current version of
apache/couchdb:2.1
does not support these values, so I created a pull request for this.Once this pr is merged, those environment variables will be available.
apache/couchdb-docker#32
This pr also can address the problem reported by this issue: #2808