Key-Value Store

Key-Value stores like etcd and consul have become corner stones of modern infrastructure. In short, they are simple schemaless stores where you can store any bytes in a bucket given a single key name. The values can later be retrieved.

Choria Key-Value Store is built on Choria Streams and share many of the features plus some KV specific:

  • Replicated, share-nothing storage
  • Possibility to make regional read-replicas
  • History kept per key
  • Non destructive deletes
  • Ability to watch a key or entire bucket for changes
  • Fast in-memory read caches
  • Integrated with Choria Autonomous Agent
  • Client libraries for Go with more to follow

This feature added in Choria v0.23.0

Managing and Using a Bucket

Adding a bucket

To store data you have to add a bucket, with Choria Streams enabled this is easy:

$ choria kv add CFG \
     --history 5 \
     --replicas 3 \
     --max-value-size 10240 \
     --max-bucket-size 102400

Above we add a bucket CFG, it keeps 5 historic values for any key, the data is replicated across 3 Choria Brokers, and some limits are set for sizes.

As of version 0.27.0 of the choria/choria module, you can also use Puppet to manage Key-Value Buckets:

choria_kv_bucket { 'CONFIGURATION':
  history => 5,
  replicas => 3,
  max_value_size => 100,
  max_bucket_size => 1024*1024*100,
  ensure => 'present',

Writing a value

Any data can be stored in the bucket:

$ choria kv put CFG username myservice
$ cat cfg.json|choria kv put CFG config -- -

Getting a value

You can get the value with a bit of metadata shown:

$ choria kv get CFG username
CFG > username created @ 13 Jul 21 10:38 UTC


But we can also use it in a script friendly manner:

USER=$(choria kv get CFG username --raw)

echo "Username: ${USER}"

Deleting a key

Deletes are non-destructive, meaning the past data will be kept if history is configured:

$ choria kv del CFG username
? Really remove the username key from bucket CFG (y/N)
$ choria kv get CFG username
FATA[0000] Could not run Choria: unknown key

You can pass -f to not be prompted

Viewing history for a key

Above we configure 5 value history for the bucket, so we can see the historic values:

$ choria kv history CFG username
| SEQ | OPERATION | TIME                 | LENGTH | VALUE     |
| 1   | PUT       | 13 Jul 21 12:38 CEST | 9      | myservice |
| 2   | DEL       | 13 Jul 21 12:40 CEST | 0      |           |

Here we can see the DEL operation was added which represents the delete.

Watching a bucket or key

One can watch writes into a bucket in real time, this can be for the entire bucket which will show full history.

$ choria kv watch CFG username
[2021-07-13 12:38:10] PUT CFG.username: myservice
[2021-07-13 12:40:07] DEL CFG.username

There’s a special form of watch that is like a waiting Get, best to show it:

set -e
USERNAME=$(choria kv watch CFG username --once --timeout 10s)

Here if there is a value at start time the value will be got and set in USERNAME, if there is not a value immediately it will wait for up to 10 seconds for a value to be created.

If after 10 seconds nothing arrived a timeout will be reached and error raised

Purging a bucket

All the values can be removed from a bucket and history will not be kept. Note any active watchers will not be notified that the purge has happened.

$ choria kv purge CFG
? Really remove the CFG bucket Yes
$ choria kv info CFG
CFG Key-Value Store

     Bucket Name: CFG
   Values Stored: 0
         History: 5
             TTL: 0s
 Max Bucket Size: 102400
  Max Value Size: 10240

We can see after purge no values are stored.

Removing a bucket

Finally, the bucket can be completely removed using choria kv rm CFG.

Backup and Restore

Choria can create a backup for a bucket while the bucket is online and without interruption:

$ choria kv backup CFG /srv/backup/cfg
Created 791 bytes backup of bucket CFG in /srv/backup/cfg

# on another cluster
$ choria kv restore /srv/backup/cfg
Restored 791 bytes backup from /srv/backup/cfg
$ choria kv ls
| CFG    | 5       | 6      |

Autonomous Agent Integration

Choria Autonomous Agents let us build small Kubernetes Operator like managed finite state machines. Since version 0.23.0 they integrate with key-value stores and have a built-in data layer.

  - name: kv_watch
    type: kv
    interval: 10s
    state_match: [WAIT]
    success_transition: update_deployment
      bucket: CFG
      key: username
      mode: poll

This will watch the bucket in a polling mode and if the username key update will transition to update_deployment.

Any exec watchers that will follow will have access to a new environment variable WATCHER_DATA that is a path to a JSON file holding any data the machine manages.

Right now only a single key poll is supported, we’ll add an entire bucket watch which will be more suitable for complex automations.