summary refs log tree commit diff
path: root/nixos/modules/services/databases/foundationdb.xml
blob: 51fe9ae3f910317d866045311125a2909cb3aeff (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
<chapter xmlns="http://docbook.org/ns/docbook"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xmlns:xi="http://www.w3.org/2001/XInclude"
         version="5.0"
         xml:id="module-services-foundationdb">

<title>FoundationDB</title>

<para><emphasis>Source:</emphasis> <filename>modules/services/databases/foundationdb.nix</filename></para>

<para><emphasis>Upstream documentation:</emphasis> <link xlink:href="https://apple.github.io/foundationdb/"/></para>

<para><emphasis>Maintainer:</emphasis> Austin Seipp</para>

<para><emphasis>Available version(s):</emphasis> 5.1.x</para>

<para>FoundationDB (or "FDB") is a distributed, open source, high performance,
transactional key-value store. It can store petabytes of data and deliver
exceptional performance while maintaining consistency and ACID semantics
(serializable transactions) over a large cluster.</para>

<section><title>Configuring and basic setup</title>

<para>To enable FoundationDB, add the following to your
<filename>configuration.nix</filename>:

<programlisting>
services.foundationdb.enable = true;
services.foundationdb.package = pkgs.foundationdb51; # FoundationDB 5.1.x
</programlisting>
</para>

<para>The <option>services.foundationdb.package</option> option is required,
and must always be specified. Because FoundationDB network protocols and
on-disk storage formats may change between (major) versions, and upgrades must
be explicitly handled by the user, you must always manually specify this
yourself so that the NixOS module will use the proper version. Note that minor,
bugfix releases are always compatible.</para>

<para>After running <command>nixos-rebuild</command>, you can verify whether
FoundationDB is running by executing <command>fdbcli</command> (which is added
to <option>environment.systemPackages</option>):

<programlisting>
$ sudo -u foundationdb fdbcli
Using cluster file `/etc/foundationdb/fdb.cluster'.

The database is available.

Welcome to the fdbcli. For help, type `help'.
fdb> status

Using cluster file `/etc/foundationdb/fdb.cluster'.

Configuration:
  Redundancy mode        - single
  Storage engine         - memory
  Coordinators           - 1

Cluster:
  FoundationDB processes - 1
  Machines               - 1
  Memory availability    - 5.4 GB per process on machine with least available
  Fault Tolerance        - 0 machines
  Server time            - 04/20/18 15:21:14

...

fdb>
</programlisting>
</para>

<para>FoundationDB is run under the <command>foundationdb</command> user and
group by default, but this may be changed in the NixOS configuration. The
systemd unit <command>foundationdb.service</command> controls the
<command>fdbmonitor</command> process.</para>

<para>By default, the NixOS module for FoundationDB creates a single
SSD-storage based database for development and basic usage. This storage engine
is designed for SSDs and will perform poorly on HDDs; however it can handle far
more data than the alternative "memory" engine and is a better default choice
for most deployments. (Note that you can change the storage backend on-the-fly
for a given FoundationDB cluster using <command>fdbcli</command>.)</para>

<para>Furthermore, only 1 server process and 1 backup agent are started in the
default configuration. See below for more on scaling to increase this.</para>

<para>FoundationDB stores all data for all server processes under
<filename>/var/lib/foundationdb</filename>. You can override this using
<option>services.foundationdb.dataDir</option>, e.g.

<programlisting>
services.foundationdb.dataDir = "/data/fdb";
</programlisting>

</para>

<para>Similarly, logs are stored under
<filename>/var/log/foundationdb</filename> by default, and there is a
corresponding <option>services.foundationdb.logDir</option> as well.</para>

</section>

<section><title>Scaling processes and backup agents</title>

<para>Scaling the number of server processes is quite easy; simply specify
<option>services.foundationdb.serverProcesses</option> to be the number of
FoundationDB worker processes that should be started on the machine.</para>

<para>FoundationDB worker processes typically require 4GB of RAM per-process at
minimum for good performance, so this option is set to 1 by default since the
maximum amount of RAM is unknown. You're advised to abide by this restriction,
so pick a number of processes so that each has 4GB or more.</para>

<para>A similar option exists in order to scale backup agent processes,
<option>services.foundationdb.backupProcesses</option>. Backup agents are not
as performance/RAM sensitive, so feel free to experiment with the number of
available backup processes.</para>

</section>

<section><title>Clustering</title>

<para>FoundationDB on NixOS works similarly to other Linux systems, so this
section will be brief. Please refer to the full FoundationDB documentation for
more on clustering.</para>

<para>FoundationDB organizes clusters using a set of
<emphasis>coordinators</emphasis>, which are just specially-designated worker
processes. By default, every installation of FoundationDB on NixOS will start
as its own individual cluster, with a single coordinator: the first worker
process on <command>localhost</command>.</para>

<para>Coordinators are specified globally using the
<command>/etc/foundationdb/fdb.cluster</command> file, which all servers and
client applications will use to find and join coordinators. Note that this file
<emphasis>can not</emphasis> be managed by NixOS so easily: FoundationDB is
designed so that it will rewrite the file at runtime for all clients and nodes
when cluster coordinators change, with clients transparently handling this
without intervention. It is fundamentally a mutable file, and you should not
try to manage it in any way in NixOS.</para>

<para>When dealing with a cluster, there are two main things you want to
do:</para>

<itemizedlist>
  <listitem><para>Add a node to the cluster for storage/compute.</para></listitem>
  <listitem><para>Promote an ordinary worker to a coordinator.</para></listitem>
</itemizedlist>

<para>A node must already be a member of the cluster in order to properly be
promoted to a coordinator, so you must always add it first if you wish to
promote it.</para>

<para>To add a machine to a FoundationDB cluster:</para>

<itemizedlist>
  <listitem><para>Choose one of the servers to start as the initial coordinator.
      </para></listitem>
  <listitem><para>Copy the <command>/etc/foundationdb/fdb.cluster</command> file
      from this server to all the other servers. Restart FoundationDB on all of
      these other servers, so they join the cluster.</para></listitem>
  <listitem><para>All of these servers are now connected and working together
      in the cluster, under the chosen coordinator.</para></listitem>
</itemizedlist>

<para>At this point, you can add as many nodes as you want by just repeating
the above steps. By default there will still be a single coordinator: you can
use <command>fdbcli</command> to change this and add new coordinators.</para>

<para>As a convenience, FoundationDB can automatically assign coordinators
based on the redundancy mode you wish to achieve for the cluster. Once all the
nodes have been joined, simply set the replication policy, and then issue the
<command>coordinators auto</command> command</para>

<para>For example, assuming we have 3 nodes available, we can enable double
redundancy mode, then auto-select coordinators. For double redundancy, 3
coordinators is ideal: therefore FoundationDB will make
<emphasis>every</emphasis> node a coordinator automatically:</para>

<programlisting>
fdbcli> configure double ssd
fdbcli> coordinators auto
</programlisting>

<para>This will transparently update all the servers within seconds, and
appropriately rewrite the <command>fdb.cluster</command> file, as well as
informing all client processes to do the same.</para>

</section>

<section><title>Client connectivity</title>

<para>By default, all clients must use the current
<command>fdb.cluster</command> file to access a given FoundationDB cluster.
This file is located by default in
<command>/etc/foundationdb/fdb.cluster</command> on all machines with the
FoundationDB service enabled, so you may copy the active one from your cluster
to a new node in order to connect, if it is not part of the cluster.</para>

</section>

<section><title>Client authorization and TLS</title>

<para>By default, any user who can connect to a FoundationDB process with the
correct cluster configuration can access anything. FoundationDB uses a
pluggable design to transport security, and out of the box it supports a
LibreSSL-based plugin for TLS support. This plugin not only does in-flight
encryption, but also performs client authorization based on the given
endpoint's certificate chain. For example, a FoundationDB server may be
configured to only accept client connections over TLS, where the client TLS
certificate is from organization <emphasis>Acme Co</emphasis> in the
<emphasis>Research and Development</emphasis> unit.</para>

<para>Configuring TLS with FoundationDB is done using the
<option>services.foundationdb.tls</option> options in order to control the peer
verification string, as well as the certificate and its private key.</para>

<para>Note that the certificate and its private key must be accessible to the
FoundationDB user account that the server runs under. These files are also NOT
managed by NixOS, as putting them into the store may reveal private
information.</para>

<para>After you have a key and certificate file in place, it is not enough to
simply set the NixOS module options -- you must also configure the
<command>fdb.cluster</command> file to specify that a given set of coordinators
use TLS. This is as simple as adding the suffix <command>:tls</command> to your
cluster coordinator configuration, after the port number. For example, assuming
you have a coordinator on localhost with the default configuration, simply
specifying:</para>

<programlisting>
XXXXXX:XXXXXX@127.0.0.1:4500:tls
</programlisting>

<para>will configure all clients and server processes to use TLS from now
on.</para>

</section>

<section><title>Backups and Disaster Recovery</title>

<para>The usual rules for doing FoundationDB backups apply on NixOS as written
in the FoundationDB manual. However, one important difference is the security
profile for NixOS: by default, the <command>foundationdb</command> systemd unit
uses <emphasis>Linux namespaces</emphasis> to restrict write access to the
system, except for the log directory, data directory, and the
<command>/etc/foundationdb/</command> directory. This is enforced by default
and cannot be disabled.</para>

<para>However, a side effect of this is that the <command>fdbbackup</command>
command doesn't work properly for local filesystem backups: FoundationDB uses a
server process alongside the database processes to perform backups and copy the
backups to the filesystem. As a result, this process is put under the
restricted namespaces above: the backup process can only write to a limited
number of paths.</para>

<para>In order to allow flexible backup locations on local disks, the
FoundationDB NixOS module supports a
<option>services.foundationdb.extraReadWritePaths</option> option. This option
takes a list of paths, and adds them to the systemd unit, allowing the
processes inside the service to write (and read) the specified
directories.</para>

<para>For example, to create backups in <command>/opt/fdb-backups</command>,
first set up the paths in the module options:</para>

<programlisting>
services.foundationdb.extraReadWritePaths = [ "/opt/fdb-backups" ];
</programlisting>

<para>Restart the FoundationDB service, and it will now be able to write to
this directory (even if it does not yet exist.) Note: this path
<emphasis>must</emphasis> exist before restarting the unit. Otherwise, systemd
will not include it in the private FoundationDB namespace (and it will not add
it dynamically at runtime).</para>

<para>You can now perform a backup:</para>

<programlisting>
$ sudo -u foundationdb fdbbackup start  -t default -d file:///opt/fdb-backups
$ sudo -u foundationdb fdbbackup status -t default
</programlisting>

</section>

<section><title>Known limitations</title>

<para>The FoundationDB setup for NixOS should currently be considered beta.
FoundationDB is not new software, but the NixOS compilation and integration has
only undergone fairly basic testing of all the available functionality.</para>

<itemizedlist>
  <listitem><para>There is no way to specify individual parameters for
      individual <command>fdbserver</command> processes. Currently, all server
      processes inherit all the global <command>fdbmonitor</command> settings.
      </para></listitem>
  <listitem><para>Python bindings are not currently installed.</para></listitem>
  <listitem><para>Ruby bindings are not currently installed.</para></listitem>
  <listitem><para>Go bindings are not currently installed.</para></listitem>
</itemizedlist>

</section>

<section><title>Options</title>

<para>NixOS's FoundationDB module allows you to configure all of the most
relevant configuration options for <command>fdbmonitor</command>, matching it
quite closely. For a complete list of all options, check <command>man
configuration.nix</command>.</para>

</section>

<section><title>Full documentation</title>

<para>FoundationDB is a complex piece of software, and requires careful
administration to properly use. Full documentation for administration can be
found here: <link xlink:href="https://apple.github.io/foundationdb/"/>.</para>

</section>

</chapter>