If you already have a database server running and you know how to administrate it properly, you probably just want to use the appropriate implementation for that. Let's say you're already running a MySQL server. Setting up a Redis server and using the gokv
Redis implementation will probably lead to a higher performance, but to be honest, you should always go with the service you already know well, except if you're willing to learn about a new service anyway.
Otherwise (if you don't already have a database server running), you might be overwhelmed with the choice of implementations.
First of all, you need to know the key differences between the store categories. Then you can look into the differences of concrete stores / implementations.
- Local in-memory
- These are the fastest stores, because the data doesn't need to be transferred anywhere, not even to disk.
- But if your application crashes, all data is lost, because it's not persisted anywhere.
- Some of the implementations offer the possibility to limit the memory usage, leading to old data being evicted from the cache.
- Embedded
- The data is written to disk. Easy to back up, no servers to handle.
- Some implementations cache the data and only write to disk periodically, which leads to a high performance, but bears the risk that the data that's not persisted yet is lost when the system crashes.
- Well fitted for standalone client-side applications.
- Not fitted for web services, because you usually want to scale your services horizontally. When the DB gets filled with data by your first service instance and then you start another service instance, this second instance won't see any of the data of the first instance. Sharing the DB usually doesn't work due to open file handles and doesn't make sense anyway, because your services are probably (and should be) located on different servers with different disks.
- Distributed store
- The database runs as a separate server.
- The data is persisted (either immediately or periodically, depending on the implementation), so a server crash doesn't lead to data loss.
- The servers can be run as cluster, leading to the data being even when a database server crashes.
- Most implementations are specifically engineered to be key-value stores with very high performance.
- Perfectly fitted for web services, because you can scale horizontally and each service instance can access the same data.
- Distributed cache
- Similar to the distributed stores: Runs as separate server, can be run as cluster, engineered as key-value store with high performance
- But without any persistence, so when a database server crashes, its data is lost.
- (Some implementations offer optional persistence, but discourage it. If you need a distributed store with persistence, you should use one that's specifically engineered for that use-case, and not a cache.)
- Can be useful if you only need to cache values temporarily and don't want a database to constantly grow.
- Cloud
- Databases running in the cloud can be great if you need a database server (in-memory and embedded are not an option), but you can't or don't want to deal with the server administration.
- Most DB-as-a-Service providers offer high availability and redundancy across regions, so even if an entire datacenter is unreachable for example due to some natural desaster or some powerlines being accidentally cut off (both happened in the past), your applications and web services still have access to all the data.
- It might be more expensive than running your own database server, but maybe only when not taking the administrative overhead of managing your own servers into account.
- It might be slower than running your own database server, depending on if your applications / web services run in the same cloud or not, due to network latency.
- SQL, NoSQL, NewSQL
- Most of these implementations are probably only interesting for people who are already running their own database servers.
- Local in-memory
- Go
sync.Map
- Faster then a regular map when there are lots of reads and only very few writes
- Go
map
(withsync.RWMutex
) - FreeCache
- Zero GC cache with strictly limited memory usage
-
Note: Old entries are evicted from the cache when the cache's size limit is reached
- BigCache
- Similar to FreeCache in that no GC is required even for gigabytes of data, but the memory limit is optional
- Difference according to the BigCache creators: BigCache vs. FreeCache
- Go
- Embedded
- bbolt (formerly known as Bolt / Bolt DB)
- bbolt is a fork of Bolt which was maintained by CoreOS, and now by Red Hat (since CoreOS was acquired by them)
- It's used for example in etcd as underlying persistent store
- It uses a B+ tree, which generally means that it's very fast for read operations
- BadgerDB
- It's used for example in Dgraph, a distributed graph DB
- It uses an LSM tree, which generally means that it's very fast for write operations
- LevelDB / goleveldb
- Local files
- One file per key-value pair, with the key being the filename and the value being the file content
- bbolt (formerly known as Bolt / Bolt DB)
- Distributed store
- Redis
- Consul
- Probably the most popular service registry. Has a key-value store as additional feature.
- Official comparison with ZooKeeper, doozerd and etcd
-
Note: Consul doesn't allow values larger than 512 KB
- etcd
- It's used for example in Kubernetes
- Official comparison with ZooKeeper, Consul and some NewSQL databases
-
Note: By default, the maximum request size is 1.5 MiB and the storage size limit is 2 GB. See the documentation.
- Apache ZooKeeper
- TiKV (
⚠️ Not implemented yet!)- Originally created as foundation of TiDB, but acts as a proper key-value store on its own and became a project in the CNCF
- Distributed cache
- Memcached
-
Note: Memcached is meant to be used as LRU (Least Recently Used) cache, which means items automatically expire and are deleted from the server after not being used for a while. See Memcached Wiki: Forgetting is a feature.
-
- Hazelcast
- Memcached
- Cloud
- Amazon DynamoDB
-
Note: The maximum value size is 400 KB. See the documentation.
-
- Amazon S3
- Also works for other S3-compatible cloud services like Google Cloud Storage, Alibaba Cloud Object Storage Service (OSS), DigitalOcean Spaces and Scaleway Object Storage, as well as for self-hosted solutions like OpenStack Swift, Ceph and Minio
- S3 is advertised as file storage (website assets, images, videos etc.), but any blob can be stored, so the
[]byte
representation of your value thatgokv
gets after automatically marshalling it can be stored as well - S3 is designed for high availability and redundancy, as well as low cost (compared to regular cloud databases)
- S3 is not meant to match the performance of dedicated key-value stores
- Azure Cosmos DB
- Azure Table Storage
- Not as performant, scalable, flexible as Cosmos DB: Table Storage vs. Cosmos DB Table Storage API
- But much cheaper than Cosmos DB: Cosmos DB pricing vs. Table Storage pricing
-
Note: Maximum entity size is 1 MB.
- Google Cloud Datastore
- Google Cloud Firestore
- Currently still in beta, but might become the successor to Cloud Datastore
- Alibaba Cloud Table Store
-
Note: The size limit of the key is 1 KB. The size limit of the value is 2 MB, see the official documentation
-
- Amazon DynamoDB
- SQL
- MySQL
- PostgreSQL
- Seems to be seen as more advanced, robust and performant than MySQL, especially in the Go community.
- NoSQL
- MongoDB
- Apache Cassandra (
⚠️ Not implemented yet!)
- NewSQL
- CockroachDB
- Inspired by the Google Spanner design, CockroachDB offers horizontal scalability and replication without sacrificing strong consistency
- Official comparison with MongoDB and PostgreSQL
- TiDB (
⚠️ Not implemented yet!)
- CockroachDB
- Multi-model
- Apache Ignite
- The
gokv.Store
implementation uses the key-value store model of Ignite. - The key-value store model seems to be meant to be used as cache by default, so the Ignite administrator must ensure the proper configuration for persistence. See: https://apacheignite.readme.io/docs/distributed-persistent-store.
- The
- ArangoDB (
⚠️ Not implemented yet!) - OrientDB (
⚠️ Not implemented yet!)- Claims to be the fastest graph database
- Apache Ignite
- Misc
- Go
nop
does nothing except validate the inputs, if applicable.
- Go