Key-value stores don’t actually store keys and values directly; they use a distributed hash table (DHT) to map keys to nodes.

Let’s watch Redis in action. Imagine a simple Python script:

import redis

# Connect to a local Redis instance
r = redis.Redis(host='localhost', port=6379, db=0)

# Set a key-value pair
r.set('mykey', 'myvalue')

# Get the value for a key
value = r.get('mykey')
print(f"Value for 'mykey': {value.decode('utf-8')}")

# Increment a counter
r.incr('counter')
print(f"Counter value: {r.get('counter').decode('utf-8')}")

When you run this, Redis, under the hood, isn’t just dumping mykey:myvalue into a single file. For a single-node Redis, it might use an in-memory hash table. But when we talk about distributed systems like etcd or DynamoDB, the story gets more complex.

These systems solve the problem of storing massive amounts of data reliably and accessibly across multiple machines. The core challenge is consistency: how do you ensure that if you write a value, you can read that same value back, even if the node you’re reading from is different from the one you wrote to, and even if nodes fail?

Internally, they use variations of distributed hash tables. A key is hashed, and that hash determines which node (or set of nodes) is responsible for that key. For example, in etcd, which uses Raft for consensus, a key might be stored on a majority of nodes in a cluster. When you SET mykey myvalue, etcd proposes this change to its consensus group. A leader node receives the request, logs it, and replicates it to followers. Once a majority acknowledges the write, it’s considered committed and visible. Reads might go to the leader or a follower, depending on consistency configurations.

DynamoDB, on the other hand, uses a different approach. It partitions data based on a partition key. A hash function applied to the partition key determines the partition. Within a partition, data is sorted by the sort key (if present). DynamoDB also replicates data across multiple Availability Zones for durability. When you PUT { 'pk': 'user123', 'sk': 'profile', 'data': '...' }, DynamoDB hashes user123 to find the correct partition, writes the data to multiple replicas within that partition, and then acknowledges the write. Reads follow a similar path.

The "hash table" analogy breaks down slightly when you consider how these systems handle failures and consistency. etcd’s Raft ensures that all nodes agree on the order of operations, guaranteeing strong consistency. If a node fails, the remaining nodes can elect a new leader and continue operating. DynamoDB offers tunable consistency. A "strongly consistent" read will always return the most up-to-date data, but might be slower. An "eventually consistent" read might return slightly stale data but is typically faster and more available.

The critical insight for many of these systems is how they manage partitions and replication to balance consistency, availability, and partition tolerance (the CAP theorem). For instance, in etcd, a key-value pair isn’t just on one machine; it’s replicated across multiple nodes. When a write occurs, it’s sent to the leader, which then broadcasts it to its followers. A majority of nodes must acknowledge the write before it’s considered committed. This replication is what protects against node failures and ensures data durability. If a node goes offline, the data it held is still available on the other replicas.

The next hurdle is understanding how these systems handle complex queries and data modeling beyond simple key-value lookups.

Want structured learning?

Take the full Storage course →