Decoding Redis Performance Myths: The Wisdom Symphony of Core Data Structures

Follow the WeChat official account "Programmer Xiao Pang" for daily technical insights, delivered to you immediately!

Introduction

Redis is an open-source in-memory data structure storage system that supports multiple types of data structures, such as strings, hashes, lists, sets, sorted sets, and more. Redis is renowned for its excellent performance and low-latency characteristics, which mainly benefits from the design and implementation of its core data structures, as well as its high-performance storage and access mechanism.

Core Data Structures

Redis' data structure design is very flexible: it not only supports basic data types, but also complex data types, and provides a rich set of operation commands.

String

Strings are the most basic data structure in Redis, allowing users to perform operations such as setting, getting, and deleting string values.

Use cases:

  • Caching data (such as HTML pages, JSON-serialized objects)
SET  key  value //Store string key-value pair
MSET  key  value [key value ...] //Batch store multiple string key-value pairs
SETNX  key  value //Store a string key-value pair only if the key does not exist
GET  key //Get the value of a string key
MGET  key  [key ...] //Batch get multiple string key values
DEL  key  [key ...] //Delete one or more keys
EXPIRE  key  seconds //Set the expiration time of a key (in seconds)
  • Counter (such as Weibo like counts, video play counts)
INCR  key //Increment the numeric value stored in key by 1
DECR  key //Decrement the numeric value stored in key by 1
INCRBY  key  increment //Add increment to the value stored in key
DECRBY  key  decrement //Subtract decrement from the value stored in key
  • Distributed lock
SETNX  product:10001  true //Return 1 means lock acquisition succeeded
SETNX  product:10001  true //Return 0 means lock acquisition failed
DEL  product:10001//Release the lock after business logic completes
SET product:10001 true  ex  10  nx//Prevent deadlock caused by unexpected program termination

Advantages:

  • Simple and easy to use
  • Suitable for simple caching and counting scenarios

Disadvantages:

  • Not suitable for storing complex data structures

Hash

A set is an unordered collection implemented with a hash table, featuring fast add, delete, and search operations.

Use cases:

  • Storing user information
  • Recording object attributes (user information)
  • Caching row data from relational databases
HMSET  user  1:name  zhangsan  1:age  18
HMSET  user  2:name  lisi      1:age  19
HMGET  user  1:name  1:age  

Command execution result:

id name age
1 zhangsan 18
2 lisi 19

Advantages:

  • Supports storage of complex data structures
  • High access and update efficiency
  • Similar data is categorized and stored together, facilitating data management

Disadvantages:

  • Not suitable for storing large amounts of data, since all data is stored under a single key
  • Expiration cannot be set for individual fields, only for the entire key
  • Not suitable for large-scale use under the Redis cluster architecture

List

Lists are simple linked lists of strings that support inserting and deleting elements from both ends, and are commonly used for scenarios such as message queues.

Use cases:

  • Message queue
Blocking MQ (blocking queue) = LPUSH + BRPOP
Queue = LPUSH + RPOP

Insert element from the left side of the list

LPUSH tasks “process_video”

Pop element from the right side of the list

BPOP tasks

  • WeChat Moments timeline
LPUSH message:{user id} 1
LPUSH message:{user id} 2
LPUSH message:{user id} 3
LPUSH message:{user id} 4

LRANGE message:{user id} 0 3

Advantages:

  • Supports bidirectional operations (adding/removing elements from the head or tail)
  • Can be used as a queue or a stack

Disadvantages:

  • Accessing middle elements is slow when there are a large number of elements
  • Add and remove operations at the tail of the list are fast, but operations at the head are slow

Set

A Set is an unordered collection implemented with a hash table, featuring fast add, delete, and search operations.

Use cases:

  • Likes and bookmarks on WeChat and Weibo
1) Like
SADD  like:{message ID}  {user ID}
2) Cancel like
SREM like:{message ID}  {user ID}
3) Check if the user has already liked
SISMEMBER  like:{message ID}  {user ID}
4) Get the list of users who liked
SMEMBERS like:{message ID}
5) Get the number of users who liked 
SCARD like:{message ID}

  • Friend relationships (mutual follows)

SINTER set1 set2 set3  { c }
SUNION set1 set2 set3  { a,b,c,d,e }
SDIFF set1 set2 set3  { a }
  • Lottery activities (randomly selecting winners)
1) Click to participate in the lottery and add to the set
SADD key {userlD}
2) View all users participating in the lottery
SMEMBERS key  
3) Draw count winners
SRANDMEMBER key [count] / SPOP key [count]

Advantages:

  • Elements are unique, no duplicates allowed
  • Supports operations between sets, such as union and intersection

Disadvantages:

  • Does not support sorting
  • Cannot directly retrieve elements from the set

Sorted Set

A sorted set combines the properties of a set and a hash table: it assigns a score to each element, and sorts elements based on their score.

Use cases:

  • Ranking systems
//Show the top 10 rankings of the day
ZREVRANGE  hotNews:20190819  0  9  WITHSCORES 

High Performance Principles

  1. Why is Redis fast?

This is because all of Redis' data is stored in memory, all operations are memory-level operations, and single-threading avoids the performance overhead of multi-thread context switching. Precisely because Redis is single-threaded, you need to be careful when using Redis commands. For time-consuming commands (such as keys), you must use them with caution, as improper use can easily cause Redis to lag.

  1. Redis threading model

Redis' single-threading mainly refers to the fact that Redis network IO and key-value read/write operations are handled by a single thread, which is also the main workflow of Redis providing key-value storage services. Redis also has multi-threaded functions for tasks such as persistence, asynchronous deletion, and cluster data synchronization.

  1. Redis support for high concurrency

Redis IO multiplexing: Redis uses epoll to implement IO multiplexing. It puts connection information and events into a queue, which is then passed to the file event dispatcher in sequence, and the event dispatcher distributes events to event handlers.

Conclusion

The reason Redis can provide high-performance data storage and access is mainly due to its in-memory storage, single-threaded model, efficient data structure design, and persistence mechanism. Understanding Redis' core data structures and high-performance principles is of great significance for us to use Redis better and optimize application performance.


This is a discussion topic separated from the original topic at https://juejin.cn/post/7369054503084245030