1 @title Clustering Introduction
4 Guide to configuring Phabricator across multiple hosts for availability and
11 WARNING: This feature is a prototype. Installs should expect a challenging
12 adventure when deploying clusters. In the best of times, configuring a
13 cluster is complex and requires significant operations experience.
15 Phabricator can be configured to run on multiple hosts with redundant services
16 to improve its availability and scalability, and make disaster recovery much
19 Clustering is more complex to setup and maintain than running everything on a
20 single host, but greatly reduces the cost of recovering from hardware and
23 Each Phabricator service has an array of clustering options that can be
24 configured somewhat independently. Configuring a cluster is inherently complex,
25 and this is an advanced feature aimed at installs with large userbases and
26 experienced operations personnel who need this high degree of flexibility.
28 The remainder of this document summarizes how to add redundancy to each
29 service and where your efforts are likely to have the greatest impact.
31 For additional guidance on setting up a cluster, see "Overlaying Services"
32 and "Cluster Recipes" at the bottom of this document.
38 This table provides an overview of clusterable services, their setup
39 complexity, and the rough impact that converting them to run on multiple hosts
40 will have on availability, resistance to data loss, and scalability.
42 | Service | Setup | Availability | Loss Resistance | Scalability
43 |---------|-------|--------------|-----------|------------
44 | **Databases** | Moderate | **High** | **High** | Low
45 | **Repositories** | Complex | Moderate | **High** | Moderate
46 | **Daemons** | Minimal | Low | No Risk | Low
47 | **SSH Servers** | Minimal | Low | No Risk | Low
48 | **Web Servers** | Minimal | **High** | No Risk | Moderate
49 | **Notifications** | Minimal | Low | No Risk | Low
50 | **Fulltext Search** | Minimal | Low | No Risk | Low
52 See below for a walkthrough of these services in greater detail.
55 Preparing for Clustering
56 ========================
58 To begin deploying Phabricator in cluster mode, set up `cluster.addresses`
59 in your configuration.
61 This option should contain a list of network address blocks which are considered
62 to be part of the cluster. Hosts in this list are allowed to bend (or even
63 break) some of the security and policy rules when they make requests to other
64 hosts in the cluster, so this list should be as small as possible. See "Cluster
65 Whitelist Security" below for discussion.
67 If you are deploying hardware in EC2, a reasonable approach is to launch a
68 dedicated Phabricator VPC, whitelist the whole VPC as a Phabricator cluster,
69 and then deploy only Phabricator services into that VPC.
71 If you have additional auxiliary hosts which run builds and tests via Drydock,
72 you should //not// include them in the cluster address definition. For more
73 detailed discussion of the Drydock security model, see
74 @{article:Drydock User Guide: Security}.
76 Most other clustering features will not work until you define a cluster by
77 configuring `cluster.addresses`.
80 Cluster Whitelist Security
81 ========================
83 When you configure `cluster.addresses`, you should keep the list of trusted
84 cluster hosts as small as possible. Hosts on this list gain additional
85 capabilities, including these:
87 **Trusted HTTP Headers**: Normally, Phabricator distrusts the load balancer
88 HTTP headers `X-Forwarded-For` and `X-Forwarded-Proto` because they may be
89 client-controlled and can be set to arbitrary values by an attacker if no load
90 balancer is deployed. In particular, clients can set `X-Forwarded-For` to any
91 value and spoof traffic from arbitrary remotes.
93 These headers are trusted when they are received from a host on the cluster
94 address whitelist. This allows requests from cluster loadbalancers to be
95 interpreted correctly by default without requiring additional custom code or
98 **Intracluster HTTP**: Requests from cluster hosts are not required to use
99 HTTPS, even if `security.require-https` is enabled, because it is common to
100 terminate HTTPS on load balancers and use plain HTTP for requests within a
103 **Special Authentication Mechanisms**: Cluster hosts are allowed to connect to
104 other cluster hosts with "root credentials", and to impersonate any user
107 The use of root credentials is required because the daemons must be able to
108 bypass policies in order to function properly: they need to send mail about
109 private conversations and import commits in private repositories.
111 The ability to impersonate users is required because SSH nodes must receive,
112 interpret, modify, and forward SSH traffic. They can not use the original
113 credentials to do this because SSH authentication is asymmetric and they do not
114 have the user's private key. Instead, they use root credentials and impersonate
115 the user within the cluster.
117 These mechanisms are still authenticated (and use asymmetric keys, like SSH
118 does), so access to a host in the cluster address block does not mean that an
119 attacker can immediately compromise the cluster. However, an over-broad cluster
120 address whitelist may give an attacker who gains some access additional tools
123 Note that if an attacker gains access to an actual cluster host, these extra
124 powers are largely moot. Most cluster hosts must be able to connect to the
125 master database to function properly, so the attacker will just do that and
126 freely read or modify whatever data they want.
132 Configuring multiple database hosts is moderately complex, but normally has the
133 highest impact on availability and resistance to data loss. This is usually the
134 most important service to make redundant if your focus is on availability and
137 Configuring replicas allows Phabricator to run in read-only mode if you lose
138 the master and to quickly promote the replica as a replacement.
140 For details, see @{article:Cluster: Databases}.
143 Cluster: Repositories
144 =====================
146 Configuring multiple repository hosts is complex, but is required before you
147 can add multiple daemon or web hosts.
149 Repository replicas are important for availability if you host repositories
150 on Phabricator, but less important if you host repositories elsewhere
151 (instead, you should focus on making that service more available).
153 The distributed nature of Git and Mercurial tend to mean that they are
154 naturally somewhat resistant to data loss: every clone of a repository includes
157 Repositories may become a scalability bottleneck, although this is rare unless
158 your install has an unusually heavy repository read volume. Slow clones/fetches
159 may hint at a repository capacity problem. Adding more repository hosts will
160 provide an approximately linear increase in capacity.
162 For details, see @{article:Cluster: Repositories}.
168 Configuring multiple daemon hosts is straightforward, but you must configure
171 With daemons running on multiple hosts you can transparently survive the loss
172 of any subset of hosts without an interruption to daemon services, as long as
173 at least one host remains alive. Daemons are stateless, so spreading daemons
174 across multiple hosts provides no resistance to data loss.
176 Daemons can become a bottleneck, particularly if your install sees a large
177 volume of write traffic to repositories. If the daemon task queue has a
178 backlog, that hints at a capacity problem. If existing hosts have unused
179 resources, increase `phd.taskmasters` until they are fully utilized. From
180 there, adding more daemon hosts will provide an approximately linear increase
183 For details, see @{article:Cluster: Daemons}.
189 Configuring multiple SSH hosts is straightforward, but you must configure
192 With multiple SSH hosts you can transparently survive the loss of any subset
193 of hosts without interruption to repository services, as long as at last one
194 host remains alive. SSH services are stateless, so putting multiple hosts in
195 service provides no resistance to data loss because no data is at risk.
197 SSH hosts are very rarely a scalability bottleneck.
199 For details, see @{article:Cluster: SSH Servers}.
205 Configuring multiple web hosts is straightforward, but you must configure
208 With multiple web hosts you can transparently survive the loss of any subset
209 of hosts as long as at least one host remains alive. Web services are stateless,
210 so putting multiple hosts in service provides no resistance to data loss
211 because no data is at risk.
213 Web hosts can become a bottleneck, particularly if you have a workload that is
214 heavily focused on reads from the web UI (like a public install with many
215 anonymous users). Slow responses to web requests may hint at a web capacity
216 problem. Adding more hosts will provide an approximately linear increase in
219 For details, see @{article:Cluster: Web Servers}.
222 Cluster: Notifications
223 ======================
225 Configuring multiple notification hosts is simple and has no pre-requisites.
227 With multiple notification hosts, you can survive the loss of any subset of
228 hosts as long as at least one host remains alive. Service may be briefly
229 disrupted directly after the incident which destroys the other hosts.
231 Notifications are noncritical, so this normally has little practical impact
232 on service availability. Notifications are also stateless, so clustering this
233 service provides no resistance to data loss because no data is at risk.
235 Notification delivery normally requires very few resources, so adding more
236 hosts is unlikely to have much impact on scalability.
238 For details, see @{article:Cluster: Notifications}.
241 Cluster: Fulltext Search
242 ========================
244 Configuring search services is relatively simple and has no pre-requisites.
246 By default, Phabricator uses MySQL as a fulltext search engine, so deploying
247 multiple database hosts will effectively also deploy multiple fulltext search
250 Search indexes can be completely rebuilt from the database, so there is no
251 risk of data loss no matter how fulltext search is configured.
253 For details, see @{article:Cluster: Search}.
259 Although hosts can run a single dedicated service type, certain groups of
260 services work well together. Phabricator clusters usually do not need to be
261 very large, so deploying a small number of hosts with multiple services is a
264 In planning a cluster, consider these blended host types:
266 **Everything**: Run HTTP, SSH, MySQL, notifications, repositories and daemons
267 on a single host. This is the starting point for single-node setups, and
268 usually also the best configuration when adding the second node.
270 **Everything Except Databases**: Run HTTP, SSH, notifications, repositories and
271 daemons on one host, and MySQL on a different host. MySQL uses many of the same
272 resources that other services use. It's also simpler to separate than other
273 services, and tends to benefit the most from dedicated hardware.
275 **Repositories and Daemons**: Run repositories and daemons on the same host.
276 Repository hosts //must// run daemons, and it normally makes sense to
277 completely overlay repositories and daemons. These services tend to use
278 different resources (repositories are heavier on I/O and lighter on CPU/RAM;
279 daemons are heavier on CPU/RAM and lighter on I/O).
281 Repositories and daemons are also both less latency sensitive than other
282 service types, so there's a wider margin of error for under provisioning them
283 before performance is noticeably affected.
285 These nodes tend to use system resources in a balanced way. Individual nodes
286 in this class do not need to be particularly powerful.
288 **Frontend Servers**: Run HTTP and SSH on the same host. These are easy to set
289 up, stateless, and you can scale the pool up or down easily to meet demand.
290 Routing both types of ingress traffic through the same initial tier can
291 simplify load balancing.
293 These nodes tend to need relatively little RAM.
299 This section provides some guidance on reasonable ways to scale up a cluster.
301 The smallest possible cluster is **two hosts**. Run everything (web, ssh,
302 database, notifications, repositories, and daemons) on each host. One host will
303 serve as the master; the other will serve as a replica.
305 Ideally, you should physically separate these hosts to reduce the chance that a
306 natural disaster or infrastructure disruption could disable or destroy both
307 hosts at the same time.
309 From here, you can choose how you expand the cluster.
311 To improve **scalability and performance**, separate loaded services onto
312 dedicated hosts and then add more hosts of that type to increase capacity. If
313 you have a two-node cluster, the best way to improve scalability by adding one
314 host is likely to separate the master database onto its own host.
316 Note that increasing scale may //decrease// availability by leaving you with
317 too little capacity after a failure. If you have three hosts handling traffic
318 and one datacenter fails, too much traffic may be sent to the single remaining
319 host in the surviving datacenter. You can hedge against this by mirroring new
320 hosts in other datacenters (for example, also separate the replica database
323 After separating databases, separating repository + daemon nodes is likely
324 the next step to consider.
326 To improve **availability**, add another copy of everything you run in one
327 datacenter to a new datacenter. For example, if you have a two-node cluster,
328 the best way to improve availability is to run everything on a third host in a
329 third datacenter. If you have a 6-node cluster with a web node, a database node
330 and a repo + daemon node in two datacenters, add 3 more nodes to create a copy
331 of each node in a third datacenter.
333 You can continue adding hosts until you run out of hosts.
341 - learning how Phacility configures and operates a large, multi-tenant
342 production cluster in ((cluster)).