1# libkv 2 3[![GoDoc](https://godoc.org/github.com/docker/libkv?status.png)](https://godoc.org/github.com/docker/libkv) 4[![Build Status](https://travis-ci.org/docker/libkv.svg?branch=master)](https://travis-ci.org/docker/libkv) 5[![Coverage Status](https://coveralls.io/repos/docker/libkv/badge.svg)](https://coveralls.io/r/docker/libkv) 6[![Go Report Card](https://goreportcard.com/badge/github.com/docker/libkv)](https://goreportcard.com/report/github.com/docker/libkv) 7 8`libkv` provides a `Go` native library to store metadata. 9 10The goal of `libkv` is to abstract common store operations for multiple distributed and/or local Key/Value store backends. 11 12For example, you can use it to store your metadata or for service discovery to register machines and endpoints inside your cluster. 13 14You can also easily implement a generic *Leader Election* on top of it (see the [docker/leadership](https://github.com/docker/leadership) repository). 15 16As of now, `libkv` offers support for `Consul`, `Etcd`, `Zookeeper` (**Distributed** store) and `BoltDB` (**Local** store). 17 18## Usage 19 20`libkv` is meant to be used as an abstraction layer over existing distributed Key/Value stores. It is especially useful if you plan to support `consul`, `etcd` and `zookeeper` using the same codebase. 21 22It is ideal if you plan for something written in Go that should support: 23 24- A simple metadata storage, distributed or local 25- A lightweight discovery service for your nodes 26- A distributed lock mechanism 27 28You can find examples of usage for `libkv` under in `docs/examples.go`. Optionally you can also take a look at the `docker/swarm` or `docker/libnetwork` repositories which are using `docker/libkv` for all the use cases listed above. 29 30## Supported versions 31 32`libkv` supports: 33- Consul versions >= `0.5.1` because it uses Sessions with `Delete` behavior for the use of `TTLs` (mimics zookeeper's Ephemeral node support), If you don't plan to use `TTLs`: you can use Consul version `0.4.0+`. 34- Etcd versions >= `2.0` because it uses the new `coreos/etcd/client`, this might change in the future as the support for `APIv3` comes along and adds more capabilities. 35- Zookeeper versions >= `3.4.5`. Although this might work with previous version but this remains untested as of now. 36- Boltdb, which shouldn't be subject to any version dependencies. 37 38## Interface 39 40A **storage backend** in `libkv` should implement (fully or partially) this interface: 41 42```go 43type Store interface { 44 Put(key string, value []byte, options *WriteOptions) error 45 Get(key string) (*KVPair, error) 46 Delete(key string) error 47 Exists(key string) (bool, error) 48 Watch(key string, stopCh <-chan struct{}) (<-chan *KVPair, error) 49 WatchTree(directory string, stopCh <-chan struct{}) (<-chan []*KVPair, error) 50 NewLock(key string, options *LockOptions) (Locker, error) 51 List(directory string) ([]*KVPair, error) 52 DeleteTree(directory string) error 53 AtomicPut(key string, value []byte, previous *KVPair, options *WriteOptions) (bool, *KVPair, error) 54 AtomicDelete(key string, previous *KVPair) (bool, error) 55 Close() 56} 57``` 58 59## Compatibility matrix 60 61Backend drivers in `libkv` are generally divided between **local drivers** and **distributed drivers**. Distributed backends offer enhanced capabilities like `Watches` and/or distributed `Locks`. 62 63Local drivers are usually used in complement to the distributed drivers to store informations that only needs to be available locally. 64 65| Calls | Consul | Etcd | Zookeeper | BoltDB | 66|-----------------------|:----------:|:------:|:-----------:|:--------:| 67| Put | X | X | X | X | 68| Get | X | X | X | X | 69| Delete | X | X | X | X | 70| Exists | X | X | X | X | 71| Watch | X | X | X | | 72| WatchTree | X | X | X | | 73| NewLock (Lock/Unlock) | X | X | X | | 74| List | X | X | X | X | 75| DeleteTree | X | X | X | X | 76| AtomicPut | X | X | X | X | 77| Close | X | X | X | X | 78 79## Limitations 80 81Distributed Key/Value stores often have different concepts for managing and formatting keys and their associated values. Even though `libkv` tries to abstract those stores aiming for some consistency, in some cases it can't be applied easily. 82 83Please refer to the `docs/compatibility.md` to see what are the special cases for cross-backend compatibility. 84 85Other than those special cases, you should expect the same experience for basic operations like `Get`/`Put`, etc. 86 87Calls like `WatchTree` may return different events (or number of events) depending on the backend (for now, `Etcd` and `Consul` will likely return more events than `Zookeeper` that you should triage properly). Although you should be able to use it successfully to watch on events in an interchangeable way (see the **docker/leadership** repository or the **pkg/discovery/kv** package in **docker/docker**). 88 89## TLS 90 91Only `Consul` and `etcd` have support for TLS and you should build and provide your own `config.TLS` object to feed the client. Support is planned for `zookeeper`. 92 93## Roadmap 94 95- Make the API nicer to use (using `options`) 96- Provide more options (`consistency` for example) 97- Improve performance (remove extras `Get`/`List` operations) 98- Better key formatting 99- New backends? 100 101## Contributing 102 103Want to hack on libkv? [Docker's contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md) apply. 104 105## Copyright and license 106 107Copyright © 2014-2016 Docker, Inc. All rights reserved, except as follows. Code is released under the Apache 2.0 license. The README.md file, and files in the "docs" folder are licensed under the Creative Commons Attribution 4.0 International License under the terms and conditions set forth in the file "LICENSE.docs". You may obtain a duplicate copy of the same license, titled CC-BY-SA-4.0, at http://creativecommons.org/licenses/by/4.0/. 108