Hash in Redis
Storage Characteristics
Hashes in Redi are used to store multiple unordered key-value pairs. They can store up to 232 - 1 entries (approximately 4 billion).
It's important to note that Redis' outer key-value structure is already a hash table (called the "outer hash"). The hash we're discussing here is an inner hash structure, used for storing related fields under a single key.
Advantages of Hash Over String
- Organizes related values under a single key, saving memory space
- Reduces key namespace pollution by grouping related data
- Allows batch operations with a single command, reducing memory I/O and CPU usage
Limitations
- Individual fields cannot have separate expiration times
- Data distribution considerations - when a hash contains many fields, it cannot be split across multiple nodes
Common Operations
hset user:1000 name "Alice"
hset user:1000 email "alice@example.com"
hset user:1000 age 30
hmset user:1001 name "Bob" email "bob@example.com" age 25
hget user:1000 name
hmget user:1001 name email
hkeys user:1000
hvals user:1000
hgetall user:1001
hdel user:1000 email
hlen user:1001
Internal Implementation
Redis Hashes can be implemented using two different internal structures:
- Ziplist (OBJ_ENCODING_ZIPLIST) - A compact, memory-efficient structure for small hashes
- Hash Table (OBJ_ENCODING_HT) - A standard hash table for larger hashes
Ziplist - Memory Optimized Structure
Ziplist is a special encoded doubly-linked list made of contiguous memory blocks. It stores previous node length and current node length instead of pointers to next/previous nodes, trading CPU computation for memory savings.
Ziplist internal structure:
- - Total size of the ziplist
- - Offset to the last entry
- - Number of entries in the ziplist
- ... - Actual entries
- - Special end marker
Ziplist encoding options:
#define ZIP_STR_06B (0<<6) // Strings up to 63 bytes
#define ZIP_STR_14B (1<<6) // Strings up to 16383 bytes
#define ZIP_STR_32B (2<<6) // Strings up to 4294967295 bytes
Ziplist Configuration
Redis uses ziplist encoding when both conditions are met:
- Hash has fewer than 512 entries
- All keys and values are shorter than 64 bytes
Configuration parameters in redis.conf:
hash-max-ziplist-value 64 // Maximum string length for ziplist entries
hash-max-ziplist-entries 512 // Maximum number of entries in ziplist
Hash Table Implementation
When hash size exceeds the thresholds, Redis switches to a standard hash table implementation.
Key structures in Redis hash table:
dictEntry- Represents a single key-value pairdictht- Contains the actual hash table arraydict- Top-level dictionary structure with two hash tables
Hash table expansion (rehashing) process:
- Create a larger ht[1] table (typically double the size)
- Rehash all entries from ht[0] to ht[1]
- Swap ht[0] and ht[1] when complete, then prepare new ht[1] for future rehashing
Triggering Epxansion
Redis uses a load factor to determine when to expand the hash table. The default expansion threshold is when the ratio of entries to table size reaches 5:1.
Typical Use Cases
- Storing structured data like user profiles or database records
- Implementing shopping carts (user ID as key, product ID as field, quantity as value)
- Grouping related configuration settings