Redis, as an open source, in-memory data structure storage system, is widely used in various scenarios such as caching, message queues, and publish-subscribe systems with its excellent performance and flexible data types. Among the five basic data types of Redis, the Hash type is a very important data type. It can store a collection of key-value pairs, and can add, delete, update, and search operations with a time complexity of less than 1 millisecond, so it has a wide range of uses in practical applications.
In the next article, I will introduce the Hash type of Redis in detail, including its internal implementation, main features, common commands and application scenarios. Whether you are new to Redis or a developer with some experience, I believe you can learn some useful knowledge from this article. Let's have a deep understanding of Redis's Hash type and explore its charm.
Article Directory
1. Redis-Hash data type
1.1. Introduction to Redis-Hash type
The Hash type of Redis is a collection of key-value pairs, and this data type is suitable for storing objects. In the Hash type, each key has a corresponding value, which is very similar to Python's dictionary, Java's HashMap, and JavaScript objects.
Here are some key features of the Redis Hash type:
-
Key-value pair collection: The Hash type can store multiple key-value pairs, and each key has a corresponding value.
-
Binary Safe: Hash type keys and values are binary safe, meaning they can contain any data, including binary data.
-
Large capacity: A single Hash type can store more than 400 million key-value pairs.
-
Efficient lookup speed: No matter how much data is stored in the Hash, the speed of finding a key is very fast.
1.2. Redis-Hash application scenarios
The Hash type of Redis is a collection of key-value pairs, suitable for storing objects, so it has a wide range of applications in many scenarios. Here are some common application scenarios:
-
Store objects: The Hash type can store multiple key-value pairs, which is very suitable for storing objects. For example, you can use the Hash type to store user information, such as username, password, email, etc.;
-
Data analysis: You can use the Hash type to store various statistical data, such as user behavior data, and then perform data analysis;
-
Social network: In a social network application, you can use the Hash type to store the user's friend list, follower list, etc.
The above are just some common application scenarios. In fact, due to the flexibility of Redis, you can apply the Hash type of Redis to more scenarios according to your own needs.
2. Redis-Hash underlying structure
2.1. Introduction to the underlying structure of Redis-Hash
The underlying implementation of Redis's Hash type is a very optimized data structure, which will choose to use a compact compressed list (ziplist) or hashtable (hashtable) as the underlying implementation according to the actual situation.
The Hash type of Redis will switch between the compressed list (ziplist) and the hash table (hashtable) according to the actual situation, which mainly depends on two configuration parameters: hash-max-ziplist-entries
and hash-max-ziplist-value
.
hash-max-ziplist-entries
: This parameter is used to set the maximum number of nodes that the compressed list can store. If the number of elements of a Hash type exceeds this value, then it will switch from a compressed list to a hash table. The default value is 512;hash-max-ziplist-value
: This parameter is used to set the maximum size (in bytes) of each node in the compression list. If the size of any element of a Hash type exceeds this value, then a switch is made from the compressed list to the hash table. The default value is 64.
Both of these parameters can be set in the Redis configuration file. By adjusting these two parameters, you can choose to save memory or improve performance according to your application characteristics.
- Convert from compressed list to hash table: When the number of fields and values stored by the Hash type exceeds the
hash-max-ziplist-entries
value, or the size of any field or value exceedshash-max-ziplist-value
the value, Redis will convert the underlying structure from a compressed list to a hash table. This process is automatic and transparent to the user. - Conversion from hash table to compressed list: However, once the underlying structure of the Hash type has been converted to a hash table, it cannot be converted back to a compressed list. This is because the performance of the hash table is higher, and in most cases, once the size of a Hash type exceeds a certain threshold, its size is likely to continue to grow.
2.2, Redis-compressed list (ziplist)
When the number of fields and values stored in the Hash type is small, and the string length of the fields and values is short, Redis will choose to use the compressed list as the underlying implementation. A compressed list is a special encoding structure designed to save memory, which stores all fields and values together compactly. The advantage of this method is that it occupies less memory, but when the data needs to be modified, the entire compressed list may need to be rewritten, and the performance is low.
Redis' compressed list (ziplist) is a special encoding structure designed to save memory. A compressed list stores all elements compactly together, and each element occupies only contiguous memory space.
A compressed list has the following structure:
+---------+---------+--------+---------+---------+---------+--------+
| zlbytes | zltail | zllen | entry_1 | entry_2 | ... | zlend |
+---------+---------+--------+---------+---------+---------+--------+
Ps: In the source code of Redis, the structure of the compressed list (ziplist) is not directly defined as a C structure, but a continuous memory is operated through a series of macros and functions.
Attributes | illustrate |
---|---|
“zlbytes” | A 4-byte integer, indicating the number of bytes occupied by the entire compression list, including <zlbytes> its own size. |
"golden" | A 4-byte integer representing the offset of the last element in the compressed list. This offset is relative to the starting address of the entire compressed list. |
“zllen” | A 2-byte integer representing the number of elements in the compressed list. If the number of elements exceeds 65535, then this value will be set to 65535, and the entire compressed list needs to be traversed to get the actual number of elements. |
“entry” | Compress the elements in the list, each element consisting of one or more bytes. The first byte of each element (also known as "entry header") is used to indicate the length of the element and the encoding method. |
“zlend” | A byte with a value of 255 indicating the end of the compressed list. |
2.3, Redis-hash table (hashtable)
When the number of fields and values stored in the Hash type is large, or the string length of the fields and values is long, Redis will choose to use the hash table as the underlying implementation. A hash table is a common key-value pair mapping structure, which maps keys to a bucket through a hash function, and then searches in the bucket. The advantage of this method is that the performance of searching and modifying data is high, but it also takes up more memory.
Redis's hash table (hash table) is a common key-value pair mapping structure, which maps keys to a bucket through a hash function, and then searches in the bucket. Redis's hash table uses the linked list method to resolve hash conflicts, that is, when multiple keys are mapped to the same bucket, they are stored in the same linked list.
In the source code of Redis, the structure of the hash table is defined as follows:
typedef struct dictEntry {
void *key;
void *val;
struct dictEntry *next;
} dictEntry;
typedef struct dictht {
dictEntry **table;
unsigned long size;
unsigned long sizemask;
unsigned long used;
} dictht;
typedef struct dict {
dictht ht[2];
long rehashidx; /* rehashing not in progress if rehashidx == -1 */
int iterators; /* number of iterators currently running */
} dict;
in:
-
dictEntry
A structure represents a node in a hash table, containing a key (key
), a value (val
), and a pointer to the next node (next
). -
dictht
The structure represents a hash table, which contains a pointer to the hash table array (table
), the size of the hash table array (size
), the hash table array size mask (sizemask
), and the number of used nodes (used
). -
dict
The structure represents a dictionary containing two hash tables (ht
), the index currently being rehashed (rehashidx
), and the number of iterators currently running (iterators
).
This is the structure of a Redis hash table.
3. Hash common commands
The following are some commands related to the Hash type in Redis:
3.1. Set Hash value
The command to set the Hash value in Redis is HSET
that its syntax is as follows:
HSET key field value
Among them, key
is the name of the hash table, field
is the field name in the hash table, and value
is the value corresponding to the field. If the field does not already exist in the hash table, a new field is created and its value is set to the specified value. If the field already exists, the original value will be overwritten.
For example, we can set the value of user:1001
a field in a hash table named with the following command :name
Alice
HSET user:1001 name Alice
If you need to set the values of multiple fields at the same time, you can use HMSET
the command, its syntax is as follows:
HMSET key field1 value1 [field2 value2 ...]
For example, we can set the value of both the and fields user:1001
in a hashtable at the same time using the following command :name
age
HMSET user:1001 name Alice age 25
This allows you to set the values of multiple fields at once.
In Redis, the command to get the Hash value is HGET
, its syntax is as follows:
HGET key field
Where, key
is the name of the hash table, field
and is the field name in the hash table.
For example, we can get the value of user:1001
a field in a hashtable named using the following command name
:
HGET user:1001 name
3.2. Get Hash value
If you need to get the values of multiple fields in the hash table, you can use HMGET
the command, its syntax is as follows:
HMGET key field1 [field2 ...]
For example, we can get the values of the and fields user:1001
in the hashtable using the following command :name
age
HMGET user:1001 name age
If you need to get all the fields and values in the hash table, you can use HGETALL
the command, its syntax is as follows:
HGETALL key
For example, we can get user:1001
all the fields and values in a hash table with the following command:
HGETALL user:1001
3.3. Delete Hash value
In Redis, the command to delete the Hash value is HDEL
, and its syntax is as follows:
HDEL key field [field ...]
where key
is the name of the hash table and field
is the name of the field to be deleted. You can delete one or more fields at a time.
For example, we can delete a user:1001
field in a hash table named with the following command name
:
HDEL user:1001 name
If you want to delete multiple fields, you can list the names of these fields in turn after the command, for example:
HDEL user:1001 name age
This command will delete the and fields user:1001
in the hash table .name
age
It should be noted that HDEL
the command will only delete the specified field and its value, but not the entire hash table. If you want to delete the entire hash table, you can use DEL
the command, for example:
DEL user:1001
This command deletes the entire user:1001
hash table.
3.4. Other Hash commands
Some other common commands of Hash in Redis are:
HEXISTS key field
: Check whether the specified field exists in the hash table key.HLEN key
: Get the number of fields in the hash table.HKEYS key
: Get all the fields in the hash table.HVALS key
: Get all the values in the hash table.HGETALL key
: Get all the fields and values of the specified key in the hash table.HINCRBY key field increment
: Add increment to the integer value of the specified field in the hash table key.HINCRBYFLOAT key field increment
: Add increment to the floating-point value of the specified field in the hash table key.HMSET key field value [field value ...]
: Set multiple field-value (field-value) pairs to the key of the hash table at the same time.HMGET key field [field ...]
: Get all the values of the given field.