In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >
Share
Shulou(Shulou.com)05/31 Report--
This article focuses on "what are the contents of the redis data structure", interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Now let the editor take you to learn "what is the content of the redis data structure"?
Redis is not just a simple key-value database, it is actually a data structure server that supports various types of values. That is, in a traditional key-value database, you associate a string key with a string value, while in redis, the value is not limited to a simple string, but can also be a more complex data structure. All the data structures supported by redis are listed below, which are described below:
Binary secure string
Lists: a collection of string elements stored sequentially based on the insertion order. Mainly chain list.
Sets: a unique, unordered collection of string elements.
Sorted sets: similar to sets, but each string element is associated with a floating-point number called a score. Unlike sets, elements can be sorted based on scores, so you can retrieve a range of elements (for example, you can query the top 10 or the last 10).
Hashes: a mapping consisting of the relationship between a fields and a value. Fields and values are strings. This is very similar to Ruby or Python hashes.
Bitmap bitmaps: you can use special commands to deal with strings just like bitmaps: set and clear a bit, count the number of bits set to 1, find the first bit set or not set, and so on.
HyperLogLogs: this is a probabilistic data structure used to estimate the potential of a set. Don't be scared. It's not that hard. This article is described in the HyperLogLog section below.
When there is a problem, it is not that trivial to understand how data structures work and how they are used. Therefore, this document is a crash course on Redis data types and their common patterns.
For all the examples here, we use the redis client (redis-cli). This is a simple and convenient command line console compared to the redis server.
Key of redis
Redis keys are binary safe [1], that is, you can use any binary sequence as keys, such as the string "foo" or the contents of a JPEG file.
The empty string is also a valid key.
Some other rules about keys:
Keys that are too long are not recommended. For example, a key with a length of 1024 bytes is not good, either from a memory perspective or from a query key point of view. Because querying keys from a dataset requires multiple key matching steps. Even if the task at hand is to determine whether a large value exists, it's a good idea to hash it in some way, especially in terms of memory and bandwidth.
Keys that are too short are usually not recommended. It may be a bit of a problem if you write the key "user:1000:followers" as "u1000flw". Because the former is more readable and only needs a little more space. Short keys obviously take up less space, so you need to find a balance.
Try to stick to the pattern. For example, "object-type:id" is recommended, like "user:1000". Dots and short lines are often used in situations with multiple words, such as "comment:1234:reply.to" or "comment:1234:reply-to".
The size of the key cannot exceed 512MB.
Strings in Redis
The string type in Redis is the simplest type that can be associated with a key. It is the only data type in Memcached and is the most commonly used type for beginners to Redis.
Since the keys of Redis are strings, use strings as values, that is, string-to-string mapping. The string data type can be used in many scenarios, such as caching HTML fragments or pages.
Let's try some string types with the redis client (all of the examples in this article are performed on the redis client).
> set mykey somevalueOK > get mykey "somevalue"
As you can see, the GET and SET commands are used to set or get a string value. It is important to note that if the key already exists, SET overrides its value, even if the key is not associated with a value of type string. SET is the equivalent of an assignment.
The value can be any type of string (including binary data), or you can use a jpeg image. The value cannot be greater than 512MB in size.
The SET command, with some extra parameters, can achieve some interesting functions. For example, I can ask that SET fail if the key already exists, or conversely, SET will succeed if the key already exists.
> set mykey newval nx (nil) > set mykey newval xxOK
Although a string is the most basic data type, you can still perform some interesting operations on it, such as atomic self-increment:
> set counter 100OK > incr counter (integer) 101 > incr counter (integer) 102 > incrby counter 50 (integer) 152
The INCR command parses the string into an integer, then + 1, and stores the resulting result as a new value. There are other similar commands: INCRBY, DECR, DECRBY. In terms of the principle of the implementation of the command, these commands are the same, but with a slight difference.
Why is INCR atomic? Because even if multiple clients use the INCR command on the same key, there is no race condition. For example, a situation like this won't happen: client 1 reads that the key is 10, client 2 also reads that the key value is 10, they execute self-incrementing commands on it at the same time, and the final value is 11. In fact, the final value is 12, because when a client reads-increments-writes keys, other clients cannot perform the process at the same time.
There are many commands for manipulating strings, such as the GETSET command, which sets a new value to the key and returns the old value. For example, you have a system that uses INCR to increment a key every time a new visitor logs in to your site. You may want to count every hour of information, but you don't want to lose each self-increment operation. You can use the GETSET command to set a new value of "0" while reading the old value.
Redis supports setting or reading multiple keys at the same time with a single command, which is useful for reducing latency. This is the MSET command and the MGET command:
> mset a 10 b 20 c 30OK > mget a b C1) "10" 2) "20" 3) "30"
When using MGET, redis returns an array containing multiple values.
Change or query key space
[2]
Some commands do not specify a specific type, but are useful in interacting with key spaces, so they can be used for any type of key.
For example, the EXISTS command returns 1 or 0 to indicate whether a given key exists in the database. The DEL command deletes the key and its corresponding value, regardless of the value.
> set mykey helloOK > exists mykey (integer) 1 > del mykey (integer) 1 > exists mykey (integer) 0
Whether DEL returns 1 or 0 depends on whether the key is (key exists) or not (key does not exist) is deleted.
There are many commands related to keyspace, but these two commands and the TYPE command are the most basic. The function of the TYPE command is to return the type of value of this key.
> set mykey xOK > type mykeystring > del mykey (integer) 1 > Life cycle of type mykeynone key
Before introducing more and more complex data structures, let's first discuss another feature that is independent of the value type, which is the redis expires of redis. Basically, you can set a timeout for the key, which is the lifetime of the key. When the life cycle has passed, the key is automatically destroyed as if it had been DEL by the user.
Some quick information about redis deadlines:
The life cycle can be set in units of time from seconds to milliseconds.
The time accuracy of the life cycle is 1 millisecond.
There are multiple copies of data about the life cycle and stored on the hard disk, based on the Redis server stopped, time is still passing, which means that redis stores the time when the key expires.
Setting the life cycle is a trivial matter:
> set key some-valueOK > expire key 5 (integer) 1 > get key (immediately) "some-value" > get key (after some time) (nil)
The key disappears between two calls because the second call is delayed by more than five seconds. In the above example, we use the EXPIRE command to set the lifecycle (it can also be used to reset the lifecycle for a key that has already been set, and the PERSIST command can be used to remove the command cycle of the key so that it can last for a long time). We can also use the redis command to set the lifecycle while creating the key. For example, use the SET command with parameters:
> set key 100 ex 10OK > ttl key (integer) 9
In the above example, a key is created with a value of 100 and a lifetime of 10 seconds. The following TTL command is used to view the remaining time of the key.
If you want to set or query the life cycle of the key in milliseconds, query the PEXPIRE and PTTL commands, as well as the parameter list for the SET command.
List in redis (lists)
To explain the list data type, it's best to start with a little theory. Because the term list is often misused by information technology personnel. The "python list", for example, is not an array (actually the same data type as an array in Ruby), as its command suggests (a linked list).
In a broad sense, a list is just an ordered sequence of elements: 10, 10, 20, 1, 1, 2, and 3 is a list. But lists implemented in arrays and lists implemented in linked lists have very different properties.
The list of redis is implemented as a linked list. That is, even if there are millions of elements in the list, the execution time of adding a new element to the head or tail of the list is a constant time. Use the LPUSH command to add a new element to the head of a list of 10 elements, or to the head of a list of 10 million elements, at the same speed.
What are the disadvantages? The operation of accessing an element through an index is very fast in the list implemented by the array (constant time), but not so fast in the list implemented by the linked list (proportional to the speed of finding the corresponding subscript for the element).
Redis chose to implement lists with linked lists because it is important for a database to quickly add elements to a large list. Another powerful advantage of using linked lists, as you will see later, is the ability to get a fixed-length redis list in constant time.
It is also important to quickly read the middle elements of a large set of elements, where you can use another data structure called sorted sets. We will talk about ordered sets later in this article.
The first step of regis list
The LPUSH command adds a new element to the left (header) of the list, while the RPUSH command adds a new element to the right (tail) of the list. The LRANGE command extracts elements within a range from the list
> rpush mylist A (integer) 1 > rpush mylist B (integer) 2 > lpush mylist first (integer) 3 > lrange mylist 0-11) "first" 2) "A" 3) "B"
Note that the LRANGE command requires two subscripts to be entered, the first element subscript of the range and the last element subscript. Both subscripts can be negative, meaning counting from the tail: so-1 is the last element,-2 is the penultimate element, and so on.
As you can see, RPUSH adds elements to the right of the list, and LPUSH adds elements to the left of the list. The parameters of all commands are variable, that is, you can optionally put multiple commands that add elements to the list into one call:
> rpush mylist 1 23 4 5 "foo bar" (integer) 9 > lrange mylist 0-11) "first" 2) "A" 3) "B" 4) "1" 5) "2" 6) "3" 7) "4" 8) "5" 9) "foo bar"
An important operation defined in Redis is to delete elements. The delete command can retrieve and delete elements from the list at the same time. You can delete elements from the left or right, similar to adding elements from both sides:
> rpush mylist a b c (integer) 3 > rpop mylist "c" > rpop mylist "b" > rpop mylist "a"
We added and deleted three elements, so the final list is empty and there are no elements to delete. If we try to continue to delete elements, we will get this result:
> rpop mylist (nil)
Redis returns a null value indicating that there are no elements in the list.
Common use cases for lists
Lists can be used to accomplish a variety of tasks, and here are two very representative use cases:
Keep in mind the latest updates that users post to social networks.
Using the consumer-producer model for interprocess communication, the generation puts items into the list, and the consumer (usually the worker) consumes the items and performs some behavior. Redis has some special list commands for this use case, which are both reliable and efficient.
For example, the very famous Ruby libraries resque and sidekip use Redis lists to implement background jobs at the bottom.
The famous social network Twitter uses Redis lists to get the latest messages posted by users.
To describe a common use case step by step, suppose you want to show the latest shared photos on your social network on your home page and speed up access.
Whenever a user posts a new photo, we use the LPUSH command to add its ID to the list.
When users visit the home page, we use LRANGE 0 9 to get the latest 10 table items.
Restriction list
In many cases, we just want to use lists to store the latest items, such as social networking updates, logs, or other items.
Redis allows us to use lists as a fixed collection, using the LTRIM command to record only the latest N records and discard all earlier records.
The LTRIM command is similar to the LRANGE command, but instead of displaying a specific range of elements like LRANGE, the list is reset with values within that range. All elements outside the scope have been deleted.
Use an example to illustrate this point:
> rpush mylist 1 2 3 4 5 (integer) 5 > ltrim mylist 0 2OK > lrange mylist 0-11) "1" 2) "2" 3) "3"
The above LTRIM command tells Redis to get only the elements in the list with subscript 0 to 2, and discard everything else. This is a simple and useful pattern that makes it possible: push element operation + list extraction element operation = add an element and delete an element so that the total number of list elements is limited:
LPUSH mylist LTRIM mylist 0 999
The above operation is combined to add an element, but only 1000 of the latest elements exist in the list. With LRANGE you can get the latest items without having to remember the old data.
Note: since LRANGE is theoretically an O (N) command, reading a small range of data starting from the beginning or from the end is a constant-time operation.
There are blocking operations in the list.
Some features of the list make it suitable for real-world queues (queues) and are often used as a basic component of interprocess communication systems: blocking operations.
Suppose you add elements to the list through one process and use another process to do something practical with those elements. This is the usual producer / consumer basis, and you can do it in this simple way:
The producer calls LPUSH to add the element to the list
The consumer calls RPOP to remove or process the element from the list
Is it possible that the list is empty and there is nothing to deal with, so RPOP returns NULL. In this case, consumers have to wait a while before trying RPOP. It's called polling. This is not a good approach because it has the following disadvantages:
Ask redis and the client to execute meaningless commands (when the list is empty, all requests will not perform the actual work, just return NULL)
The worker adds a delay after receiving the NULL to make it wait for some time. If the delay is smaller, the waiting time between calls to RPOP will be shorter, which becomes the magnification of the first problem-calling Redis is more meaningless.
So Redis implements the commands BRPOP and BLPOP, which are blocking versions of RPOP and LPOP: when the list is empty, they wait until a new element is added to the list, or when the user-defined wait time is up.
This is an example of a BRPOP call that we can use in the worker process:
> brpop tasks 51) "tasks" 2) "do_something"
It means: wait for the elements in the list if no elements are available for 5 seconds.
Note that if you use 0 as the timeout, you will wait forever, and you can define multiple lists instead of just one, so you will wait for multiple lists at the same time, and will be notified when any list receives an element.
A few things to pay attention to about BRPOP:
Clients are served sequentially: the first client to wait for a list, and when another client adds an element to the list, it processes it first.
The return value is different from that of RPOP: you only get an array of two elements containing key names, because BRPOP and BLPOP are blocked by waiting for multiple lists.
If the time expires, NULL will be returned.
There's more you should know about lists and blocking operations. We recommend that you read the following materials:
You can use RPOPLPUSH to create more secure queues or rotate queues.
This command has one blocking parameter, BRPOPLPUSH
Automatically create and remove keys
So far our example does not cover these scenarios, creating an empty list between adding elements, or removing a list when it has no elements. Redis has the responsibility to delete a list that becomes empty, or to create an empty list when we try to add elements. For example, LPUSH
This applies not only to lists, but to all Redis data structures that contain multiple elements-sets, ordered sets, and hashes.
Basically, we summarize its behavior into three rules:
When we add an element to a collection class data type, if the key does not exist, an empty collection class data type is created before it is added.
When we remove an element from a collection class data type, the key is automatically deleted if the value remains empty.
Call a read-only command such as LLEN (return the length of the list), or a write command that removes the element but the key is empty and the result does not change. [3]
Rule 1, for example:
> del mylist (integer) 1 > lpush mylist 1 2 3 (integer) 3
However, we cannot perform a different type of operation on an existing key:
> set foo barOK > lpush foo 1 2 3 (error) WRONGTYPE Operation against a key holding the wrong kind of value > type foostring
Rule 2, for example:
> lpush mylist 1 2 3 (integer) 3 > exists mylist (integer) 1 > lpop mylist "3" > lpop mylist "2" > lpop mylist "1" > exists mylist (integer) 0
When all elements are taken out, the key no longer exists.
Rule 3, for example:
> del mylist (integer) 0 > llen mylist (integer) 0 > lpop mylist (nil) redis hash (hashed)
The hash of redis is very similar to the "hash" as we know it, which is a domain-value pair.
> hmset user:1000 username antirez birthyear 1977 verified 1OK > hget user:1000 username "antirez" > hget user:1000 birthyear "1977" > hgetall user:10001) "username" 2) "antirez" 3) "birthyear" 4) "1977" 5) "verified" 6) "1"
Hash represents an object (object) that is very convenient. In fact, there is no limit to the number of fields that can be put into a hash (regardless of available memory), so you can use hashes in many different ways in your application.
The HMSET command sets multiple domains for hash, while HGET gets a domain. HMGET is similar to HGET, but it returns an array of values.
> hmget user:1000 username birthyear no-such-field1) "antirez" 2) "1977" 3) (nil)
There are also commands that can perform operations on a single domain, such as HINCRBY:
> hincrby user:1000 birthyear 10 (integer) 1987 > hincrby user:1000 birthyear 10 (integer) 1997
You can view this document, "hash commands are all listed".
It is not difficult to store small hashes (a small number of elements, small values) in memory in a special way, so they are very space efficient.
Set of redis (sets)
The set of Redis is an unordered collection of strings. SADD adds some elements to the set. There are many other operations for collections, such as testing the existence of a given element, finding an intersection, set, or difference between multiple sets, and so on.
> sadd myset1 23 (integer) 3 > smembers myset1. thirty-two。 13. 2
In this example, I added three elements to myset and asked redis to return all the elements. As you can see, they are disordered. Redis may return elements in any order with each call, so here the user cannot require the order of the elements.
Redis provides commands for test members. Does this given element exist?
> sismember myset 3 (integer) 1 > sismember myset 30 (integer) 0
"3" is a member of this collection, while "30" is not.
Set is good at expressing the relationship between objects. For example, we can easily use set implementation tags (tags). A simple model for dealing with this problem is to set up a set of all the objects to be tagged. Sets the ID that contains the labels of related objects.
Suppose we want to tag the news. News with an ID of 1000 is labeled as 1 ID 2 5 and 77, and we can use a set to associate these tags with news:
> sadd news:1000:tags 1 2 5 77 (integer) 4
Sometimes, however, I want the opposite relationship: all the news in the list is labeled with a given label:
> sadd tag:1:news 1000 (integer) 1 > sadd tag:2:news 1000 (integer) 1 > sadd tag:5:news 1000 (integer) 1 > sadd tag:77:news 1000 (integer) 1
It is troublesome to get all the tags of an object.
> smembers news:1000:tags1. fifty-two。 13. 774. two
Note: in this example we assume that you also have another data structure, such as redis's hash, for tag ID to tag signature mapping.
If you use the correct redis command, you can do it in a way that is not tedious but simple. For example, we might think of all objects that have tags 1, 2, 10 and 27 at the same time. We can use the SINTER command to perform intersection operations between different sets. We can use it like this:
> sinter tag:1:news tag:2:news tag:10:news tag:27:news... Results here...
Finding the intersection operation is not the only operation that can be performed, you can also perform union operation, difference set operation, extract any element, and so on.
The command to extract an element is SOP, which is convenient for simulating certain problems. For example, to implement a web-based poker game, you might make your deck into a set. Suppose we use a character prefix to represent C (clubs), D (diamonds), H (hearts), S (spades):
> sadd deck C1 C2 C4 C5 C6 C7 C8 C9 C10 CJ CQ CK D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 DJ DQ DK H1 H2 H3 H4 H5 H7 H8 H9 H10 HJ HQ HK S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 SJ SQ SK (integer) 52
Now we give each player 5 cards. The SPOP command removes a random element and returns it to the client, so it is the best operation in this use case.
Then if we call it directly to deck, we need to fill in all the cards again in the next round of the game, which is not ideal. So before you start, make a backup of the centrally stored deck key to game. Use SUNIONSTORE to do this, saving the results to another set. This command is usually run on the union of multiple sets. The union operation on a set is itself, so it can be used to copy:
> sunionstore game:1:deck deck (integer) 52
Now I'm ready to deal five cards for the first player.
> spop game:1:deck "C6" > spop game:1:deck "CQ" > spop game:1:deck "D1" > spop game:1:deck "CJ" > spop game:1:deck "SJ"
A pair of J, not so good.
Now is the time to introduce the command for the number of elements in the set. In set theory, the number of elements is often regarded as the potential of a set, so this command is SCARD.
> scard game:1:deck (integer) 47
Calculation formula: 52-5-47
If you just want to get a random element but don't remove it from the set, the SRANDMEMBER command is appropriate for this task. It can also provide the ability to return repeating or non-important elements.
Ordered set of Redis
An ordered set is like a data type that mixes sets with hashes. Like a set, an ordered set consists of unique string elements that are not repeated. So in a sense, an ordered set is also a set.
The elements in the set are unordered, while the elements in the ordered set are sorted based on an associated floating point value. This floating-point value is called a score (each element is mapped to a value, so it is similar to a hash).
In addition, the elements in the ordered set are taken in order (they are not sorted as required, sorting is a feature of this data structure used to represent the ordered set [4]). They are sorted by the following rules:
Suppose An and B are two elements with different scores. If the score of A > the score of B, then A > B.
Assuming that the scores of An and B are the same, if the lexical order of string An is greater than that of string B, then A > B. The An and B strings cannot be the same because the elements of the ordered set are unique.
Let's start with a simple example, add some hackers' names to the ordered set, and take their year of birth as a "score".
> zadd hackers 1940 "Alan Kay" (integer) 1 > zadd hackers 1957 "Sophie Wilson" (integer 1) > zadd hackers 1953 "Richard Stallman" (integer) 1 > zadd hackers 1949 "Anita Borg" (integer) 1 > zadd hackers 1965 "Yukihiro Matsumoto" (integer) 1 > zadd hackers 1914 "Hedy Lamarr" (integer) 1 > zadd hackers 1916 "Claude Shannon" (integer) 1 > zadd hackers 1969 "Linus Torvalds" (integer) 1 > zadd hackers 1912 "Alan Turing" (integer) 1
one
As you can see, ZADD is similar to SADD, but requires an additional parameter (position before the element to be added), which is the score. ZADD is also variable in parameters, and you can define multiple "score-value" pairs at will, although the above example does not say so.
There is no point in requiring ordered hacker lists to be sorted by the year in which they were born, because they already are.
Implementation details: the ordered set is implemented based on a dual-port data structure, including a jump table and a hash table. Therefore, the execution time of adding an element is O (log (N)). This is good, no other work is needed when we request ordered elements, they are already sorted:
> zrange hackers 0-11) "Alan Turing" 2) "Hedy Lamarr" 3) "Claude Shannon" 4) "Alan Kay" 5) "Anita Borg" 6) "Richard Stallman" 7) "Sophie Wilson" 8) "Yukihiro Matsumoto" 9) "Linus Torvalds"
Note: 0 and-1 mean to start with the element with the subscript 0 to the last element (- 1 here is the same as-1 in the LRANGE command).
What if you want to sort it in reverse, from the youngest to the oldest? Use ZREVERANGE instead of ZRANGE.
> zrevrange hackers 0-11) "Linus Torvalds" 2) "Yukihiro Matsumoto" 3) "Sophie Wilson" 4) "Richard Stallman" 5) "Anita Borg" 6) "Alan Kay" 7) "Claude Shannon" 8) "Hedy Lamarr" 9) "Alan Turing"
You can also return a score using the WITHSCORES parameter:
> zrange hackers 0-1 withscores1) "Alan Turing" 2) "1912" 3) "Hedy Lamarr" 4) "1914" 5) "Claude Shannon" 6) "1916" 7) "Alan Kay" 8) "1940" 9) "Anita Borg" 10) "1949" 11) "Richard Stallman" 12) "1953" 13) "Sophie Wilson" 14) "1957" 15) "Yukihiro Matsumoto" 16) "1965" 17) "Linus Torvalds" 18) "1969" scope-based operations
Ordered sets are much more powerful than that. It can also operate based on scope. To get all those born earlier than (including) 1950, we use the ZRANGEBYSCORE command to achieve:
> zrangebyscore hackers-inf 19501) "Alan Turing" 2) "Hedy Lamarr" 3) "Claude Shannon" 4) "Alan Kay" 5) "Anita Borg"
We ask Redis to return all elements with scores between infinity and 1950 (with closed intervals on both sides).
You can also remove elements within a range. We want to remove all hackers whose birth years are between 1940 and 1960 from the ordered set:
> zremrangebyscore hackers 1940 1960 (integer) 4
The name of the ZREMRANGEBYSCORE command may not be very good, but it is really useful because it returns the number of elements that have been removed.
Another very useful operation defined for ordered set elements is the get get-rank operation. You can ask for the location of an element in its ordered set.
> zrank hackers "Anita Borg" (integer) 4
The ZREVRANK command can also get rankings, but the elements are sorted in reverse order.
The score of dictionary order
The recent version of Redis 2.8 introduces a new feature that allows ranges to be obtained in lexicographic order on the assumption that all elements in the ordered set have the same score (using the memcmp function of the C language to compare elements to ensure that each redis instance will return the same result). [5]
The main commands for lexicographic range operations are ZRANGEBYLEX, ZREVRANGEBYLEX, ZREMRANGEBYLEX, and ZLEXCOUNT.
For example, let's add all the famous hackers to the list again, but this time the score for all elements is 0:
> zadd hackers 0 "Alan Kay" 0 "Sophie Wilson" 0 "Richard Stallman" 0 "Anita Borg" 0 "Yukihiro Matsumoto" 0 "Hedy Lamarr" 0 "Claude Shannon" 0 "Linus Torvalds" 0 "Alan Turing"
Collations based on ordered sets, which are lexicographically sorted:
> zrange hackers 0-11) "Alan Kay" 2) "Alan Turing" 3) "Anita Borg" 4) "Claude Shannon" 5) "Hedy Lamarr" 6) "Linus Torvalds" 7) "Richard Stallman" 8) "Sophie Wilson" 9) "Yukihiro Matsumoto"
We can use the ZRANGEBYLEX command to request the scope of the dictionary order:
> zrangebylex hackers [B [P1) "Claude Shannon" 2) "Hedy Lamarr" 3) "Linus Torvalds"
Whether the range is an open interval or a closed interval (determined by the first character), the string positive infinity and negative infinity are defined by + and -, respectively. Please check the documentation for more information.
This feature is important because it allows us to use an ordered set as a common index. For example, if you want to index an element using a 128-bit unsigned integer, all you have to do is add the element to an ordered set and set the same score (such as 0) and an 8-byte prefix consisting of 128-bit values. Because the values are large, the lexical order (the original byte order) is actually numeric, and you can request the range in 128-bit space, prefixed in descending order to return the value of the element.
If you want to see a more rigorous demonstration of this feature, check out Redis autocomplete demo.
Update score: ranking
This is the last point about ordered sets before moving on to the next topic. The scores of ordered sets can be updated at any time. You only need to ZADD an element that already exists in the ordered set to update its score (and position) on O (log (N)). Similarly, it is appropriate to use ordered sets when they are updated frequently.
A common use case for this feature is the rankings. A typical application is a game of Facebook, where you can enable users to rank based on their high scores, increase the operation of getting rankings, and display the top N users and their rankings on the rankings (for example, you have a good score of 4932).
Bitmap
A bitmap is not really a data type, but there are a series of bit-based operations on this string type. Because strings are binary safe and the maximum length is 512MB, up to 2 ^ 32 different bit strings can be set.
There are two types of bit operations, one is a constant time operation for a bit, if a bit is set to 1 or 0, or gets the value of a bit. The other is the operation on all bits, such as calculating the number of bits set to 1 in a given range (such as headcount).
One of the biggest advantages of bitmaps is that there is very little space to store information. For example, in a system where each user is represented by a different incremental user ID, it takes only 512MB of memory to record some information about 4 billion users (whether the user wants to receive mail or not).
Set or get bits through the SETBIT command and the GETBIT command:
> setbit key 10 1 (integer) 1 > getbit key 10 (integer) 1 > getbit key 11 (integer) 0
The SETBIT command takes the first parameter as the sequence number of the bit, and the second parameter, as the value to be set for this bit, can only be 1 or 0. If the address bit is greater than the length of the current string, this command automatically expands the string.
GETBIT returns only values that are located in a certain location. Bits that exceed the length (the address bit is greater than the length of the string) will inevitably get 0.
These three commands operate on all bits:
BITOP: performs bit operations between different strings. Includes AND, OR, XOR, and NOT.
BITCOUNT: performs a statistical operation to return the number of 1 in the bit set
BITPOS: find the first location that is set to 0 or 1
Both BITPOS and BITCOUNT can accept the address range of bits as parameters, so that the entire string is not manipulated. Here is a simple example of BITCOUNT:
> setbit key 0 1 (integer) 0 > setbit key 100 1 (integer) 0 > bitcount key (integer) 2
Common usage of bitmaps:
Various real-time analysis
Storage requires space and time efficient binary information associated with the object ID.
If you want to know the longest daily visits of your web users [6], you record the number of days from the beginning, the first day you make your web page public, count to 0, and then use SETBIT to set one every time a user page is available. The subscript of bit can be simply thought of as the current system time, minus the first day to get the offset, and then divided by 360024.
In this way, for each user, you have a string that contains daily access information. Use the BITCOUNT command to get the number of days a user visits a web page. With multiple BITOPs calls, the longest streak can be easily calculated by simply getting and analyzing the bitmap.
To share data or avoid manipulating a large key, bitmap can be split into multiple keys. One of the more troublesome ways to split a bitmap into multiple keys instead of setting them all into one key is to have each key store M bits, the number of keys / M, and the address of the Nth bit in this key is the position of the number% M.
HyperLogLogs
HyperLogLogs is a probabilistic data structure used to calculate something special (technically often used to estimate the potential of a set). Calculating a particular table item requires a lot of memory relative to the item to be calculated, because you need to remember the elements you have already seen to avoid double counting. Then there are a series of algorithms that can use memory with precision: in the implementation of redis, you are less than 1% likely to end up with a standard error estimate [7]. The magic of this algorithm is that no matter how much memory you need relative to the item to be calculated, you may only use a constant amount of space. In the worst case, 12K bytes, this space will be even smaller if there are fewer elements.
HLL in Redis is technically a completely different data structure, but encoded like a string, so you can use GET to serialize a HLL and use SET to parallel to the server.
Conceptually, HLL's interface uses sets to do the same thing. You will use SADD to write each observation into the set, and SCARD to query the number of elements in the set. Because SADD does not repeatedly add an existing element, the elements in the set are unique.
But you can't really add a table item to a HLL, because the data structure only contains the state of elements that don't really exist, and API is the same:
Whenever you see a new element, use the PFADD count to increment
Whenever you want to restore the current approximation, use PFCOUNT. [8]
> pfadd hll a b c d (integer) 1 > pfcount hll (integer) 4
Use an example of this data structure to count the number of requests executed by the user per day in an adjustment.
Redis can also perform union operations on HLL. Please consult the complete file for more information.
Other remarkable characteristics
There are other important information about the interface of redis that can't be put in this document, but it deserves your attention:
The key space can be iterated incrementally
You can run LUA scripts on the server side to get potential factors and bandwidth
Redis is also a publish-subscribe server
All the commands of REDIS
LPOP key: delete and get an element in the LIST header
RPOP key: delete and get an element at the end of the LIST
BLPOP key [key...] Timeout: delete and get an element in the LIST header. If not, BLOCK.
BRPOP key [key...] Timeout: delete and get an element at the end of LIST. If not, BLOCK.
LPUSH key value: extend an element in the LIST header
RPUSH key value: extend an element at the end of the LIST
LPUSHX key value: if LIST exists, extend an element in the LIST header
RPUSHX key value: if LIST exists, extend an element at the end of the LIST
LINDEX key index: get an element of LIST through INDEX
LLEN key: gets the length of the LIST
LRANGE key start stop: gets the element of LIST within the specified range
LREM key count value: delete elements of LIST
LSET key index value: sets the value of the element whose LIST index is INDEX
LTRIM key start stop: crop LIST to retain a certain range of elements
RPOPLPUSH source destination: removes an element from the tail of the current LIST and extends it to the tail of another LIST
BRPOPLPUSH source destination timeout:
Pop up an element of LIST, insert it into another LIST, and return, BLOCK if the previous LIST is empty
SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern...]] [ASC | DESC] [ALPHA] [STORE destination]:
Sort LIST,SET, SORTED SET
SADD key member: add a member to the SET
SREM key member: removes a member from the SET
SDIFF key [key...]: set difference set
SINTER key [key...]: set to find the intersection
SUNION key [key...]: set union
SDIFFSTORE destination key [key.]: the collection subtracts the set and saves the result set to another set
SINTERSTORE destination key [key.]: collections intersect and save the result set to another collection
SUNIONSTORE destination key [key.]: join the collection and save the result set to another collection
SCARD key: get the total number of SET members
SISMEMBER key member: determines whether a given value is a SET member
SPOP key: delete and return any member of SET
SRANDMEMBER key: returns any member of SET
SMEMBERS key: get all members of SET
SMOVE source destination member: move a member of one SET to another SET
ZADD key score member: add a member to the SSET, or update the SCORE of an existing member
ZCARD key: get the total number of members of the SSET
ZCOUNT key min max: calculates the total number of SCORE members in the SSET within a given range
ZINCRBY key: add SCORE for members of SSET
ZINTERSTORE destination numkeys key [key...] [WEIGHTS weight [weight...]] [AGGREGATE SUM | MIN | MAX]:
Find the SSET intersection and save the result set to a new KEY
ZRANGE key start stop [WITHSCORES]: returns members within a certain range of INDEX in the SSET
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]: returns members within a certain range of SCORE in the SSET
ZREM key member: delete a member of SSET
ZREMRANGEBYRANK key start stop: delete members within a certain INDEX range of SSET
ZREMRANGEBYSCORE key min max: delete members within a certain SCORE range of SSET
ZREVRANGE key start stop [WITHSCORES]: returns members within a certain range of INDEX in the SSET, in the order of SCORE from highest to lowest
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]: returns members within a certain range of SCORE in the SSET, in the order of SCORE from highest to lowest
ZSCORE key member: gets the SCORE associated with a given MEMBER in the SSET
ZUNIONSTORE destination numkeys key [key...] [WEIGHTS weight [weight...]] [AGGREGATE SUM | MIN | MAX]:
SSET merges the set and saves the result set in a new KEY
HDEL key field: delete a HASHFIELD
HEXISTS key field: determine whether a HASHFIELD exists
HGET key field: get a value of HASHFIELD
HGETALL key: get all the FIELDs and VALUEs of a HASH
HINCRBY key field increment: increase the integer value of increment to the integer value of HASHFIELD
HKEYS key: get all the FIELD of HASH
HLEN key: get the total number of FIELD in HASH
HMGET key field [field...]: get all the values of the FIELD specified by HASH
HMSET key field value [field value...]: set up some FILED and VALUE of HASH
HSET key field value: set a FIELD of HASH to a certain value
HSETNX key field value: when a FIELD of HASH does not exist, set it to a value
HVALS key: get all the values of HASH
DEL key [key...]: delete a KEY
GET key: get a value of KEY
SETEX key seconds value: setting VALUE and EXP time for KEY
SETNX key value: sets the VALUE of KEY, provided that KEY does not exist before
SET key value: setting KEY,VALUE
APPEND key value: extend a value to a KEY
DEBUG OBJECT key: get the DEBUG information of a KEY
DECR key: give a KEY-1
DECRBY key integer: give a KEY-integer
EXISTS key: determine whether a KEY exists
EXPIRE key seconds: set a KEY TTL (second)
EXPIREAT key timestamp: set a KEY TTL (unix timestamp)
TTL key: get the TTL of KEY
PERSIST key: removes an expiration flag for a KEY
KEYS pattern: find all PATTERN-compliant KEY
MOVE key db: move one KEY to another DATABASE
RENAME key newkey: rename a KEY
RENAMENX key newkey: rename a KEY as long as the new KEYNAME does not exist
RANDOMKEY: returns any KEY from KEYSPACE
GETRANGE key start end: get the substrings of the specified range in the string corresponding to KEY
GETSET key value: set the VALUE for KEY and return the old VALUE
INCR key: the integer value corresponding to KEY is incremented by 1
INCRBY key increment: self-increment increment for the integer value corresponding to KEY
MGET key [key...]: get all the values of the specified KEY
MSET key value [key value...]: sets the specified VALUES for the specified KEYS
MSETNX key value [key value.]: sets the specified VALUES for the specified KEYS when the specified KEY exists
STRLEN key: get the VALUE length of KEY
INFO: get server status and statistics
MONITOR: monitors all requests obtained by SERVER in real time
PING: Ping server
QUIT: closing links
PUBLISH channel message: publish a message to a CHANNEL
AUTH password: authentication server
LASTSAVE: get the timestamp of the last successful SAVETODISK
OBJECT subcommand [arguments [arguments...]]: detects the interior of a REDIS object
PSUBSCRIBE pattern [pattern...]: listens for all PATTERN-compliant messages posted to CHANNEL
PUNSUBSCRIBE [pattern [pattern...]]: stop listening for all PATTERN-compliant messages posted to CHANNEL
CONFIG RESETSTAT: reset the status information returned by the INFO command
SUBSCRIBE channel [channel...]: listens to messages for a specified CHANNEL
UNSUBSCRIBE [channel [channel...]]: stops listening to messages for the specified CHANNEL
UNWATCH: Forget about all watched keys stops monitoring all monitored KEY
WATCH key [key...]: monitors all given KEY to determine the execution of MULTI and EXEC blocks
SAVE Synchronously: saving DATASET to hard disk
SELECT index: toggles current database
BGSAVE: asynchronously save DATASET to hard disk
DBSIZE: returns the total number of KEY of a DATABASE
FLUSHALL: delete all KEY on all DATABASE
FLUSHDB: delete all KEY on the current DATABASE
SHUTDOWN Synchronously: after saving the DATASET to the hard drive, shut down the server
CONFIG GET parameter: get a configuration parameter value
CONFIG SET parameter value: set a configuration parameter to the given value
GETBIT key offset: returns the bit value of VALUE corresponding to KEY in OFFSET
MULTI: identifies the beginning of a business block
SETRANGE key offset value: overwrites the VALUE string corresponding to writing KEY from the specified OFFSET
BGREWRITEAOF: asynchronous rewriting append-only file
DEBUG SEGFAULT: make the server crash
DISCARD: ignore all commands that start with MULTI
ECHO message: ECHO message
EXEC: execute all commands that start with MULTI
SLAVEOF host port: make this server another REDIS HOST SLAVE, or make this server the master server
SYNC: internal backup command
LINSERT key BEFORE | AFTER refvalue value: inserts value before or after the refvalue of the list key
At this point, I believe you have a deeper understanding of "what is the content of the redis data structure?" you might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
1. Multi-statement table-valued function-- =-- Author:-- Create date:-- De
© 2024 shulou.com SLNews company. All rights reserved.