- Core concepts: sharding, hashing, consistent hashing, bucketing, and rebalancing.
- Practical skills: implement stable sharding, measure imbalance, and migrate shards with minimal disruption.
- Tools and techniques: deterministic hashing with Python, design patterns for partitioning, and strategies to reduce hot spots.
- A simple way to partition identifiers across N shards is to hash the identifier and take the remainder modulo N.
- This approach is easy to implement and efficient, but it has limitations when the number of shards changes.
- Python’s built-in
hash()is randomized per process for security reasons. That means the value ofhash(id)can differ between runs, processes, or machines. - For stable sharding (persisted assignments or cross-process consistency), use a deterministic hash function such as MD5, SHA1, or a non-cryptographic hash library like
xxhash.
- Rebalancing: changing
num_shards(e.g., adding or removing shards) typically forces nearly all keys to move to different shards. - Hotspots: uneven distribution of keys or traffic can overload certain shards.
- Operational complexity: migrating data and updating routing can be costly and time-consuming.
- Consistent hashing: reduces key movement when shards change by assigning keys and nodes to the same hash ring.
- Bucketing (or virtual nodes): increases distribution granularity by mapping each physical shard to multiple positions on the hash ring.
- Hybrid strategies: combine bucketing and consistent hashing or use rendezvous hashing for more predictable distribution.
Links and references
- Hash functions — hashlib documentation (Python)
- Consistent hashing — Wikipedia
- Rendezvous hashing (HRW) — Wikipedia
This course assumes no prior knowledge. Labs and examples are incremental, so you’ll build understanding step by step.