267 lines
10 KiB
Markdown
267 lines
10 KiB
Markdown
A cluster is a collection of git-annex repositories which are combined to
|
|
form a single logical repository.
|
|
|
|
A cluster is accessed via a gateway repository. The gateway is not itself
|
|
a node of the cluster.
|
|
|
|
A cluster's nodes can be any combination of git-annex repositories and
|
|
special remotes.
|
|
|
|
[[!toc ]]
|
|
|
|
## using a cluster
|
|
|
|
To use a cluster, your repository needs to have its gateway configured as a
|
|
remote. Clusters can currently only be accessed via ssh or by an annex+http
|
|
url. This gateway remote is added the same as any other git remote:
|
|
|
|
$ git remote add bigserver me@bigserver:annex
|
|
|
|
The gateway publishes information about the cluster to the git-annex
|
|
branch. So you may need to fetch from it to learn about the cluster:
|
|
|
|
$ git fetch bigserver
|
|
|
|
That will make available an additional remote for the cluster, eg
|
|
"bigserver-mycluster", as well as some remotes for each node.
|
|
|
|
$ git annex info bigserver
|
|
...
|
|
gateway to cluster: bigserver-mycluster
|
|
proxying: bigserver-node1 bigserver-node2 bigserver-node3
|
|
...
|
|
|
|
You can get files from the cluster without caring which node it comes
|
|
from:
|
|
|
|
$ git-annex get foo --from bigserver-mycluster
|
|
copy foo (from bigserver-mycluster...) ok
|
|
|
|
And you can send files to the cluster, without caring what nodes
|
|
they are stored to:
|
|
|
|
$ git-annex move bar --to bigserver-mycluster
|
|
move bar (to bigserver-mycluster...) ok
|
|
|
|
In fact, a single upload like that can be sent to every node of the cluster
|
|
at once, very efficiently.
|
|
|
|
$ git-annex whereis bar
|
|
whereis bar (3 copies)
|
|
acae2ff6-6c1e-8bec-b8b9-397a3755f397 -- [bigserver-mycluster]
|
|
9f514001-6dc0-4d83-9af3-c64c96626892 -- node 1 [bigserver-node1]
|
|
d81e0b28-612e-4d73-a4e6-6dabbb03aba1 -- node 2 [bigserver-node2]
|
|
5657baca-2f11-11ef-ae1a-5b68c6321dd9 -- node 3 [bigserver-node3]
|
|
|
|
Notice that the file is shown as present in the cluster, as well as on
|
|
individual nodes. But the cluster itself does not count as a copy of the file,
|
|
so the 3 copies are the copies on individual nodes.
|
|
|
|
Most other git-annex commands that operate on repositories can also operate on
|
|
clusters.
|
|
|
|
A cluster is not a git repository, and so `git pull bigserver-mycluster`
|
|
will not work.
|
|
|
|
## setting up a cluster
|
|
|
|
A new cluster first needs to be initialized. Run [[git-annex-initcluster]] in
|
|
the repository that will serve as the cluster's gateway. In the example above,
|
|
this was the "bigserver" repository.
|
|
|
|
$ git-annex initcluster mycluster
|
|
|
|
Once a cluster is initialized, the next step is to add nodes to it.
|
|
To make a remote be a node of the cluster, configure
|
|
`git config remote.name.annex-cluster-node`, setting it to the
|
|
name of the cluster.
|
|
|
|
In the example above, the three cluster nodes were configured like this:
|
|
|
|
$ git remote add node1 /media/disk1/repo
|
|
$ git remote add node2 /media/disk2/repo
|
|
$ git remote add node3 /media/disk2/repo
|
|
$ git config remote.node1.annex-cluster-node mycluster
|
|
$ git config remote.node2.annex-cluster-node mycluster
|
|
$ git config remote.node3.annex-cluster-node mycluster
|
|
|
|
Finally, run [[git-annex-updatecluster]] to record the cluster configuration
|
|
in the git-annex branch. That tells other repositories about the cluster.
|
|
|
|
$ git-annex updatecluster
|
|
Added node node1 to cluster: mycluster
|
|
Added node node2 to cluster: mycluster
|
|
Added node node3 to cluster: mycluster
|
|
Started proxying for node1
|
|
Started proxying for node2
|
|
Started proxying for node3
|
|
|
|
The cluster will now be accessible over ssh. To also let the cluster be
|
|
accessed over http, you would need to set up a [[tips/smart_http_server]].
|
|
|
|
Operations that affect multiple nodes of a cluster can often be sped up by
|
|
configuring annex.jobs in the gateway repository.
|
|
In the example above, the nodes are all disk bound, so operating
|
|
on more than one at a time will likely be faster.
|
|
|
|
$ git config annex.jobs cpus
|
|
|
|
## preferred content of clusters
|
|
|
|
The preferred content of the cluster can be configured. This tells
|
|
users what files the cluster as a whole should contain.
|
|
|
|
To configure the preferred content of a cluster, as well as other related
|
|
things like [[groups|git-annex-group]] and [[required_content]], it's easiest
|
|
to do the configuration in a repository that has the cluster as a remote.
|
|
|
|
For example:
|
|
|
|
$ git-annex wanted bigserver-mycluster standard
|
|
$ git-annex group bigserver-mycluster archive
|
|
|
|
By default, when a file is uploaded to a cluster, it is stored on every node
|
|
of the cluster. To control which nodes to store to, the [[preferred_content]]
|
|
of each individual node can be configured.
|
|
|
|
For example, to balance content evenly across nodes:
|
|
|
|
$ git-annex groupwanted bigserver-node balanced=bigserver-node
|
|
$ git-annex group bigserver-node1 bigserver-node
|
|
$ git-annex group bigserver-node2 bigserver-node
|
|
$ git-annex group bigserver-node3 bigserver-node
|
|
$ git-annex wanted bigserver-node1 groupwanted
|
|
$ git-annex wanted bigserver-node2 groupwanted
|
|
$ git-annex wanted bigserver-node3 groupwanted
|
|
|
|
It's also a good idea to configure the preferred content of the cluster's
|
|
gateway. To avoid files redundantly being stored on the gateway
|
|
(which remember, is not a node of the cluster), you might make it not want
|
|
any files:
|
|
|
|
$ git-annex wanted bigserver nothing
|
|
|
|
## special remotes as cluster nodes
|
|
|
|
Cluster nodes don't have to be regular git remotes. They can
|
|
also be special remotes.
|
|
|
|
Even special remotes with `exporttree=yes` can be
|
|
used as cluster nodes. Those also need to be configured with
|
|
`annexobjects=yes` though. And, you will also need to configure
|
|
`remote.name.annex-tracking-branch` to the branch that will
|
|
trigger an update of the exported tree when it is pushed to the
|
|
cluster gateway.
|
|
|
|
Let's set up a directory special remote as cluster node,
|
|
with the "master" branch exported as a tree:
|
|
|
|
$ git-annex initremote node4 type=directory directory=/media/disk3/repo exporttree=yes annexobjects=yes
|
|
$ git config remote.node4.annex-tracking-branch master
|
|
$ git config remote.node4.annex-cluster-node mycluster
|
|
$ git-annex updatecluster
|
|
|
|
## adding additional gateways to a cluster
|
|
|
|
A cluster can have more than one gateway. One way to use this is to
|
|
make a cluster that is distributed across several locations.
|
|
|
|
Suppose you have a datacenter in AMS, and one in NYC. There
|
|
will be a gateway in each datacenter which provides access to the nodes
|
|
there. And the gateways will relay data between each other as well.
|
|
|
|
Start by setting up the cluster in Amsterdam. The process is the same
|
|
as in the previous section.
|
|
|
|
AMS$ git-annex initcluster mycluster
|
|
AMS$ git remote add node1 /media/disk1/repo
|
|
AMS$ git remote add node2 /media/disk2/repo
|
|
AMS$ git config remote.node1.annex-cluster-node mycluster
|
|
AMS$ git config remote.node2.annex-cluster-node mycluster
|
|
AMS$ git-annex updatecluster
|
|
AMS$ git config annex.jobs cpus
|
|
|
|
Now in a clone of the same repository in NYC, add AMS as a git remote
|
|
accessed with ssh:
|
|
|
|
NYC$ git remote add AMS me@amsterdam.example.com:annex
|
|
NYC$ git fetch AMS
|
|
|
|
Setting up the cluster in NYC is different, rather than using
|
|
`git-annex initcluster` again (which would make a new, different
|
|
cluster), we ask git-annex to [[extend|git-annex-extendcluster]]
|
|
the cluster from AMS:
|
|
|
|
NYC$ git-annex extendcluster AMS mycluster
|
|
|
|
The rest of the setup process for NYC is the same, of course different
|
|
nodes are added.
|
|
|
|
NYC$ git remote add node3 /media/disk3/repo
|
|
NYC$ git remote add node4 /media/disk4/repo
|
|
NYC$ git config remote.node3.annex-cluster-node mycluster
|
|
NYC$ git config remote.node4.annex-cluster-node mycluster
|
|
NYC$ git-annex updatecluster
|
|
NYC$ git config annex.jobs cpus
|
|
|
|
Finally, the AMS side of the cluster has to be updated, adding a git remote
|
|
for NYC, and extending the cluster to there as well:
|
|
|
|
AMS$ git remote add NYC me@nyc.example.com:annex
|
|
AMS$ git-annex sync NYC
|
|
NYC$ git-annex extendcluster NYC mycluster
|
|
|
|
A user can now add either AMS or NYC as a remote, and will have access
|
|
to the entire cluster as either `AMS-mycluster` or `NYC-mycluster`.
|
|
|
|
user$ git-annex move foo --to AMS-mycluster
|
|
move foo (to AMS-mycluster...) ok
|
|
|
|
Looking at where files end up, all the nodes are visible, not only those
|
|
served by the current gateway.
|
|
|
|
user$ git-annex whereis foo
|
|
whereis foo (4 copies)
|
|
acfc1cb2-b8d5-8393-b8dc-4a419ea38183 -- cluster mycluster [AMS-mycluster]
|
|
11ab09a9-7448-45bd-ab81-3997780d00b3 -- node4 [AMS-NYC-node4]
|
|
36197d0e-6d49-4213-8440-71cbb121e670 -- node2 [AMS-node2]
|
|
43652651-1efa-442a-8333-eb346db31553 -- node3 [AMS-NYC-node3]
|
|
7fb5a77b-77a3-4032-b3e5-536698e308b3 -- node1 [AMS-node1]
|
|
ok
|
|
|
|
Notice that remotes for cluster nodes have names indicating the path through
|
|
the cluster used to access them. For example, "AMS-NYC-node3" is accessed via
|
|
the AMS gateway, which then relays to NYC where node3 is located.
|
|
|
|
## considerations for multi-gateway clusters
|
|
|
|
When a cluster has multiple gateways, nothing keeps the git repositories on
|
|
the gateways in sync. A branch pushed to one gateway will not be able to
|
|
be pulled from another one. And gateways only learn about the locations of
|
|
keys that are uploaded to the cluster via them. So in the example above,
|
|
after an upload to AMS-mycluster, NYC-mycluster will only know that the
|
|
key is stored in its nodes, but won't know that it's stored in nodes
|
|
behind AMS.
|
|
|
|
So, it's best to have a single git repository that is synced with, or
|
|
perhaps run [[git-annex-remotedaemon]] on each gateway to keep its git
|
|
repository in sync with the other gateways.
|
|
|
|
When using special remotes with `exporttree=yes` as nodes, it's
|
|
particularly important that pushes reach all the gateways, since the
|
|
exported tree will only get updated when the annex-tracking-branch is
|
|
pushed.
|
|
|
|
Clusters can be constructed with any number of gateways, and any internal
|
|
topology of connections between gateways. But there must always be a path
|
|
from any gateway to all nodes of the cluster, otherwise a key won't
|
|
be able to be stored from, or retrieved from some nodes.
|
|
|
|
It's best to avoid there being multiple paths to a node that go via
|
|
different gateways, since all paths will be tried in parallel when eg,
|
|
uploading a key to the cluster.
|
|
|
|
A breakdown in communication between gateways will temporarily split the
|
|
cluster. When communication resumes, some keys may need to be copied to
|
|
additional nodes, and of course the git repositories will need to be pushed
|
|
as well to get things back in sync.
|