Amazon Driver: Performance Tuning with the AWS CLI
Note
This section applies only to the Amazon driver of the S3/Amazon Cloud
Plugin. The deprecated S3 driver uses
bacula-sd-cloud-s3-driver and does not read the files described here.
The Amazon driver (bacula-sd-cloud-aws-driver) performs its transfers by
invoking the AWS CLI. The Cloud resource directives control what Bacula
asks the CLI to do – which endpoint, which bucket, how many parts at a time –
while the CLI itself decides how each individual transfer is executed: how
the object is split, how many HTTP requests run in parallel, which timeouts
and retries apply.
Those lower-level settings have no equivalent Bacula directive. They are read from the AWS CLI configuration file, and they can have a significant effect on throughput because the CLI defaults are tuned for transfers across the internet to AWS rather than for an on-premises object store reached over a local network.
Configuration File Location
The Storage Daemon runs as the Bacula user, normally bacula, whose home
directory is /opt/bacula/working. Every AWS CLI process started by the
Amazon driver inherits that environment, so the CLI looks for its
configuration at:
/opt/bacula/working/.aws/config
Create the directory if it does not exist, and make sure it is owned by the Bacula user:
mkdir -p /opt/bacula/working/.aws
touch /opt/bacula/working/.aws/config
chown -R bacula:bacula /opt/bacula/working/.aws
chmod 700 /opt/bacula/working/.aws
chmod 600 /opt/bacula/working/.aws/config
Important
If the Bacula user’s home directory is not /opt/bacula/working, the
file must be placed under whatever that home directory actually is. Confirm
it with:
getent passwd bacula | cut -d: -f6
A configuration file placed in /root/.aws/ or in the home directory of
the administrator performing the configuration will not be read by the
Storage Daemon.
Warning
Do not place aws_access_key_id or aws_secret_access_key in this
file. Credentials for the Amazon driver come from the Access Key and
Secret Key directives of the Cloud resource. Use this file for transfer
tuning only.
File Format
The settings that control transfer behavior live in a nested s3 block
inside a profile. Indentation is significant: each sub-key must be indented
beneath the s3 = line. Settings that control retries and timeouts are
top-level keys of the profile and are placed outside the s3 block.
[default]
max_attempts = 10
retry_mode = adaptive
s3 =
multipart_threshold = 64MB
multipart_chunksize = 64MB
max_concurrent_requests = 16
max_queue_size = 10000
Note
The keys inside the s3 block can only be set in the configuration file.
Unlike most AWS CLI options they have no environment-variable equivalent,
which is why this file is the only way to apply them to the Amazon driver.
AWS CLI Settings and Cloud Directives
Bacula writes a Volume as a sequence of part files in the local cache, then uploads those part files as S3 objects. Two layers of splitting are therefore involved, and they are configured in different places:
Layer |
Configured by |
Effect |
|---|---|---|
Volume split into parts |
|
Size of each object uploaded to the bucket |
Number of parts in flight |
|
How many AWS CLI transfers run at the same time |
Part split into chunks |
|
Size of each HTTP |
Chunks in flight per part |
|
Parallel requests within one part upload |
The total number of parallel HTTP requests reaching the object store is therefore approximately:
MaximumConcurrentUploads x max_concurrent_requests
Both layers must be considered together. Raising one while ignoring the other commonly produces either an idle network or an overloaded storage target.
Relevant AWS CLI Settings
Note
The settings below are defined and maintained by AWS as part of the AWS CLI. This section only describes how they interact with the Cloud Plugin. For the full definition, accepted values and current defaults of each setting, refer to the AWS CLI documentation:
Default values and available options may change between AWS CLI
versions. Check the version installed on the Storage Daemon host with
aws --version.
The suggested starting points are intended for an on-premises or S3-compatible object store reached over a local network. They are a basis for measurement, not final values; see Tuning Method.
Throughput Settings
Note
Place these settings inside the s3 block.
Setting |
Why it matters with Bacula |
Suggested starting point |
|---|---|---|
|
Bacula part files are usually much larger than the CLI default chunk,
so each part is sent as many |
|
|
Bacula part files are normally larger than the threshold, so
effectively every part upload is a multipart upload. Keep it aligned
with |
Same value as |
|
Multiplies with |
|
|
Raise it in proportion to |
|
|
Must match the Cloud resource: use |
|
|
Limits a single CLI process only. Prefer the Cloud resource directive Maximum Upload Bandwidth, which limits the aggregate across all devices using that Cloud resource. |
Leave unset |
|
Only relevant with |
Leave unset |
|
The |
Leave unset |
Warning
Setting payload_signing_enabled = false together with
Protocol = HTTP means that neither TLS nor request signing protects the
integrity of the uploaded data. Consider it only on a trusted, isolated
storage network, and treat it as a deliberate security decision.
Note
If you evaluate preferred_transfer_client = crt, test it thoroughly
against your object store, including restores, before adopting it in
production. Check the AWS CLI documentation for which s3 settings the
CRT client ignores and which ones it uses instead.
Memory Considerations
The AWS CLI holds approximately multipart_chunksize x
max_concurrent_requests of data in memory per process, and the Amazon
driver runs up to MaximumConcurrentUploads processes concurrently. The
worst-case footprint is therefore:
multipart_chunksize x max_concurrent_requests x MaximumConcurrentUploads
With multipart_chunksize = 64MB, max_concurrent_requests = 16 and
MaximumConcurrentUploads = 4, this is approximately 4 GB of RAM used by
transfers alone, in addition to the memory required by the Storage Daemon
itself.
Always verify this calculation against the memory available on the Storage Daemon host before adopting a tuned configuration. A configuration that performs well in a short test can cause memory pressure when several jobs run concurrently during the backup window.
Complete Example
A Storage Daemon writing to an on-premises S3-compatible object store over a local network using HTTPS, with the corresponding Bacula resources shown for context:
# /opt/bacula/working/.aws/config
# Owned by the Bacula user. No credentials here: they come from the
# Access Key and Secret Key directives of the Cloud resource.
[default]
max_attempts = 10
retry_mode = adaptive
connect_timeout = 60
read_timeout = 120
tcp_keepalive = true
s3 =
addressing_style = path
multipart_threshold = 64MB
multipart_chunksize = 64MB
max_concurrent_requests = 16
max_queue_size = 10000
Cloud {
Name = MyCloud
Driver = "Amazon"
HostName = "objectstore.example.com"
BlobEndpoint = "https://objectstore.example.com"
BucketName = "bacula-backup"
AccessKey = "..."
SecretKey = "..."
Protocol = HTTPS
UriStyle = Path
Upload = EachPart
TruncateCache = AfterUpload
MaximumConcurrentUploads = 4
MaximumConcurrentDownloads = 4
}
Device {
Name = CloudDevice0
DeviceType = Cloud
Cloud = MyCloud
ArchiveDevice = /mnt/bacula-cache
MaximumPartSize = 5GB
MaximumFileSize = 5GB
MaximumConcurrentJobs = 1
MediaType = CloudType
LabelMedia = yes
RandomAccess = yes
AutomaticMount = yes
RemovableMedia = no
AlwaysOpen = no
}
Note
With MaximumPartSize = 5GB, make sure the local cache filesystem can hold at
least MaximumConcurrentUploads part files in addition to the data
being written. Larger part files also mean that a restore downloads more data from
the object store, since part files are retrieved whole.
Configuration Verification
The AWS CLI reports which settings it has loaded and where each value came from. Run it as the Bacula user so that the same home directory is used:
su - bacula -s /bin/bash -c "aws configure list"
To confirm that the file is syntactically valid and being read, check a single value:
su - bacula -s /bin/bash -c "aws configure get s3.multipart_chunksize"
If this returns nothing, the file is not being read. The usual causes are a
home directory other than /opt/bacula/working, incorrect ownership, or
sub-keys of the s3 block that are not indented.
After changing the file, restart the Storage Daemon so that new transfers pick up the settings:
systemctl restart bacula-sd
Tuning Method
Optimal values depend on the object store, the network and the cache filesystem, so they should be measured rather than assumed. A practical sequence is:
Establish a baseline with the current configuration, using
status storageand the Cloud statistics described in Cloud Plugin: Status Storage and Cloud Statistics Explained.Measure the read throughput of the cache filesystem. If the cache cannot be read faster than the object store can accept data, no amount of transfer tuning will help.
Vary one layer at a time. Test
MaximumPartSizeandMaximumConcurrentUploadsfirst, since these govern how Bacula presents work to the CLI, then tunemultipart_chunksizeandmax_concurrent_requests.Watch for throughput that decreases as concurrency rises. This indicates contention inside the storage target rather than a client limitation, and in that situation lowering
MaximumConcurrentUploadscan increase total throughput.Validate the chosen settings with a real backup job, and confirm that a restore from the resulting Volume completes correctly.
Tip
If you need assistance with fine-tuning backup performance using the Amazon driver of the S3/Amazon Cloud Plugin, please contact Bacula Systems Support. Support can also supply a collection script that performs this measurement sequence automatically and produces a report with suggested values.
Go back to: Cloud Plugin: Best Practices.