Mastering Redis Strings: SDS Internals, Memory Tricks, and Distributed ID Generation
This article explains Redis String data type usage, the Simple Dynamic String (SDS) implementation details, memory‑saving techniques, encoding options, and demonstrates a practical distributed ID generator built with Redis commands and persistence strategies.
2.1.1 String (String)
Redis provides the String data type for counters, caches, distributed locks, and storing serialized user information (e.g.,
SET user:token:666 {"name":"码哥","gender":"M","city":"shenzhen"}). It is the most widely used type due to its versatility.
MySQL: "You already have C strings, why bother?"
Redis does not rely on raw C strings; instead it uses a custom structure called SDS (Simple Dynamic String) to achieve high performance, binary‑safety, and memory efficiency.
2.1.2 SDS Internals
SDS stores the actual characters in a char array, tracks length with an int len field, and records allocated capacity with an int alloc field (the unused bytes are alloc - len). The structure ends with a null byte, but the null is not counted in len.
Five SDS header variants exist (sdshdr5, sdshdr8, sdshdr16, sdshdr32, sdshdr64), differing in the size of len and alloc. For example, sdshdr8 is defined as:
struct __attribute__((__packed__)) sdshdr8 {
uint8_t len;
uint8_t alloc;
unsigned char flags;
char buf[];
};Using __attribute__((__packed__)) forces the compiler to pack the fields without padding, saving memory. The len field enables O(1) length retrieval, and the alloc field allows pre‑allocation of extra space to reduce reallocations during appends.
SDS can store binary data safely because it relies on len rather than a terminating \0 to determine the end of the string.
Redis encodes String values in three formats: int (small integers), embstr (strings ≤ 44 bytes), and raw (larger strings). The encoding can be inspected with OBJECT ENCODING key. The following diagram (omitted) shows the selection flow.
3. Practical Use: Distributed ID Generator
Generating unique, monotonically increasing IDs is a common requirement for order numbers, user IDs, etc. The generator must provide ordering, global uniqueness, high performance, high availability, and compact storage.
Redis clusters satisfy high availability and performance. By storing the counter as a numeric String and using the INCR command, IDs are generated atomically. To avoid data loss on restart, enable AOF persistence (e.g., everysec policy) and optionally replicate the generated ID to MySQL via an asynchronous pipeline.
Typical workflow:
On service start, read the maximum existing ID M from MySQL.
If counter:order does not exist in Redis, SET counter:order M; otherwise, set it to max(M, K) where K is the current Redis value.
For each new ID request, execute INCR counter:order and obtain the next ID.
Publish the ID to a message queue; a consumer updates MySQL with the new value.
The article concludes that mastering Redis String internals and SDS design enables efficient memory usage and high‑throughput ID generation, while the same principles apply to other Redis data types covered elsewhere.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITPUB
Official ITPUB account sharing technical insights, community news, and exciting events.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
