In-depth introduction to Redis (I) and brief introduction to redis
What is Redis official description Redis is an open-source log-type key-value store that supports Network and memory persistence. I personally think this description is too simple to reflect the strength of Redis. Redis is much more powerful than traditional key-value warehousing. In fact, Redis supports five types of data structures, while traditional key-value storage is only one of them. To truly understand the power of Redis, you must understand the five types of data structures it supports, how they are operated, and what types of problems they can solve.
The flexible data structure is only powerful for Redis. On the other hand, its high performance is too fast. Some tests say it is faster than Memcached. The emergence of Redis largely makes up for the shortage of key-value storage such as memcached. In some cases, it can play a good complementary role for relational databases. In addition, Redis supports a large number of client APIs, from java, C to Ruby and so on, You can query your apios from the official website http://redis.io/clients.
Redis basic since Redis is a key-value warehouse, let's talk about the key and value first. The key is an identifier, just like the name of a variable defined in the program language. For example, the key a: B: c, with the colon ':', has no special meaning, it is the same as other characters, but it can be used as a separator to better maintain all the keys of the system. Value is what we really care about. It is bound with a key. You can store a string, a number, or serialize an object in json or xml format, because Redis does not care about what you store, it only saves them as byte arrays. For example:
set people:id001 '{"id":"id001","name":"ZhangSan","age":"21","sex":"male"}'
Here, we use the set command to save a value (the object is serialized in json format) to the people: zhangsan key. Then, you can use the get command to query the corresponding values:
get people:id001
Can I query objects based on their age or gender like relational databases or document databases? Sorry, no. Redis does not support object-based Attribute query, because Redis simply stores data in bytes and does not care about the stored content. This is not only the limitation of Redis, but also the biggest advantage: fast.
Although Redis itself does not support Query Based on Object Attributes, we can implement it by ourselves. For example, to query based on name, we can do this:
hset people:lookup:name ZhangSan id001
Save the ing between name and id, then you can query the id by name, and then query the object by id. We have proposed the implementation scheme here, but whether it is worth doing so requires more consideration. After all, we still have relational databases, it is not easy to manually maintain such dependencies. If you delete an object, you have to update the people: lookup: name key.
So far, we have seen three Redis commands: set, get, and hset. How does Redis know which data structure to use? In fact, each data structure provides several separate commands. When a specific command is used, the specific data structure is determined. For example, when the set or get command is used, values of the String type are operated; when the hset command is used, values of the Hash type are operated.
StringsStrings is the most basic data type in Redis, but do not be confused by this name. Because Redis does not care about the value, you can store strings, numbers, decimal strings, and other things, or even object serialization. Just as we used the set command to save the value to the key and then use the get command to retrieve the corresponding value of the key, Redis is so simple. Of course, there are many other Strings-related commands. You can go to http://redis.io/commands?string=to make a full command. Here we will not mention it here.
It is worth noting that the Strings type also supports bit operations, such:
127.0.0.1:6379> setbit mykey 1 1(integer) 0127.0.0.1:6379> setbit mykey 2 1(integer) 0127.0.0.1:6379> setbit mykey 3 1(integer) 0127.0.0.1:6379> setbit mykey 10 1(integer) 0127.0.0.1:6379> getbit mykey 3(integer) 1127.0.0.1:6379> bitcount mykey(integer) 4
The setbit command can set a specified key location to 1 or 0. getbit can query the value (0 or 1) of a specified key location ), the bitcount command can be used to query the total number of 1 decimal digits of a key. Here is an article about how many active users can access in a day using the Redis bit operation ", 0.13 billion of the access traffic is calculated using 50 ms and 16 MB of memory on a macbook. Isn't that amazing.
Another point is that although Redis does not care about the stored values, some commands depend on the value type. For example, for commands such as incr and decr, an error is reported when the key value is not a value:
127.0.0.1:6379> set mykey 1OK127.0.0.1:6379> incr mykey(integer) 2127.0.0.1:6379> incr mykey(integer) 3127.0.0.1:6379> get mykey"3"127.0.0.1:6379> set akey abcOK127.0.0.1:6379> incr akey(error) ERR value is not an integer or out of range
The existence of HashHash makes Redis more powerful, and its function is similar to Map in Java. For Hash, a value can have several fields or attributes. it is more reasonable to use Hash to store conversations than the Strings type uses serialization to store objects:
127.0.0.1:6379> hset people:id001 id id001(integer) 1127.0.0.1:6379> hset people:id001 name ZhangSan(integer) 1127.0.0.1:6379> hset people:id001 age 21(integer) 1127.0.0.1:6379> hset people:id001 sex male(integer) 1127.0.0.1:6379> hget people:id001 name"ZhangSan"
Compared with Strings, one advantage of using Hash to store objects is that when an attribute needs to be updated, the serialization string of the entire object does not need to be updated.
ListList is equivalent to an array in programming languages, but it is much more flexible than Array Operations. The List type is ordered in Redis. The lpush and rpush commands can be used to add elements to the left and right of the data respectively. The lindex command can obtain the elements at the specified position, the lrange command can obtain multiple elements in the specified position range. The lpop (rpop) command deletes and returns the leftmost (rightmost) elements:
127.0.0.1:6379> lpush mylist b(integer) 1127.0.0.1:6379> lpush mylist a(integer) 2127.0.0.1:6379> rpush mylist c(integer) 3127.0.0.1:6379> rpush mylist d(integer) 4127.0.0.1:6379> lindex mylist 1"b"127.0.0.1:6379> lrange mylist 2 31) "c"2) "d"127.0.0.1:6379> lpop mylist"a"127.0.0.1:6379> rpop mylist"d"127.0.0.1:6379> lrange mylist 0 -11) "b"2) "c"
Through List, we can easily implement various linked lists, stacks, and other data structures. Thanks to the advantages of Redis, these implementations are extremely fast in performance.
SetsSets is a set. Compared with List, it does not allow repeated values and is not ordered. Therefore, it cannot obtain elements through subscript indexes. You can use the sadd command to add new elements to the set. The smember command returns all elements in the set, the sismember command determines whether an element belongs to a set (it is worth mentioning that the complexity of the sismember command is O (1), regardless of the number of elements in the set, it always takes a fixed period of time to complete the execution ).
127.0.0.1:6379> sadd myset java(integer) 1127.0.0.1:6379> sadd myset c++(integer) 1127.0.0.1:6379> sadd myset objective-c(integer) 1127.0.0.1:6379> sadd myset java(integer) 0127.0.0.1:6379> smembers myset1) "objective-c"2) "c++"3) "java"127.0.0.1:6379> sismember myset java(integer) 1127.0.0.1:6379> sismember myset c(integer) 0
For systems with massive data volumes, using Sets to identify uniqueness is not a good solution.
Sorted SetsSorted Sets is a very powerful data structure. Based on Sets, it binds a value to each element in the set, in this way, you can perform sorting operations on the set. The zadd command adds an element to the set and specifies the value corresponding to the element. zank returns the subscript index of the element sorted by the value in the set. zrevrank is similar to zank, only the sorting method is large to small. The zrange and zrevrange commands can obtain the sorted elements according to the subscript, which is very useful. For example, if we use Sorted Sets to store a two‑dimensional table, it is very easy to process such as: How many people are above 90, how many people fail, and who are above 80, who ranks first, how many points, and so on:
127.0.0.1: 6379> zadd math: score 58 person1 63 person2 78 person3 85 person4 90 person5 100 person6 (integer) 6127.0.0.1: 6379> zrevrangebyscore math: score 100 60 // who pass? 1) "person6" 2) "person5" 3) "person4" 4) "person3" 5) "person2" 127.0.0.1: 6379> zrevrangebyscore math: score 100 90 // who scored 90 + (including 90) "person6" 2) "person5" 127.0.0.1: 6379> zrevrangebyscore math: score 100 (90 // 90 points or higher (excluding 90) who are 1) "person6" 127.0.0.1: 6379> zcount math: score 90 + inf // how many people (integer) 2127.0.0.1: 6379> zcount math: score-inf 59 // how many people fail (integer) 1127.0.0.1: 6379> zrevrange math: score 0 0 withscores // who ranks first, how many points 1) "person6" 2) "100"
Sorted Sets can be used in many similar scenarios and businesses in real life. The e-commerce system can use Sorted Sets to maintain the monthly consumption quota of each user, classify users, and perform different promotion measures. The portal website can record the number of logins per week or month, and reward the active users with points. The blog system can collect statistics on the reading volume and favorable ratings of each blog and select high-quality articles. There are too many application scenarios that you can't think, and don't forget, Redis is very fast.
As we have seen before the Redis command, each data type of Redis provides a set of related commands, master and use these commands flexibly is the most basic requirement to make good use of Redis, the official document provides a detailed description of each command, so we will not be able to handle it here. It is worth noting that the time complexity of each command is generally O (1), O (logN) and O (N). In the production environment, check the complexity of each command, if deduplication is a command similar to O (logN) related to the data volume, it may become a performance bottleneck when the data volume is huge, check the document to see if other commands or combinations of other commands can perform the same function to improve performance.
All Redis commands are atomic because Redis is implemented in a single thread. Even if multiple commands are sent to the Redis Server at the same time on different clients, these commands are also executed in a serial manner, because there is only one thread in Redis Server to process them in sequence. Can Redis support the atomicity of multiple commands like database transactions? The answer is yes. Redis supports transactions. We will introduce related content later.
In addition to the data type-related commands, there are also some type-independent commands. Here we will briefly introduce some.
Redis also has the concept of a database, just as we can create multiple databases in a database system. In Redis, the database is identified by a number. By default, it is connected to the database 0. You can use select to select the current database.
127.0.0.1: 6379> select 1 // change the current database to 1OK127. 0.0.1: 6379 [1]> select 0 // change the current database to 0. The default database is OK127.0.0.1: 6379>
The exists command can check whether a key exists; the del command deletes the key; the keys command can query which keys are based on regular expressions, but it is best not to use this command in the production environment; rename can modify the key name.
127.0.0.1:6379> set key1 1OK127.0.0.1:6379> set key2 2OK127.0.0.1:6379> exists key1(integer) 1127.0.0.1:6379> exists key0(integer) 0127.0.0.1:6379> del key1(integer) 1127.0.0.1:6379> keys *1) "key2"127.0.0.1:6379> rename key2 key2-newOK127.0.0.1:6379> keys *1) "key2-new"127.0.0.1:6379>
Redis also supports specifying an expiration time for a key. When a key expires, Redis will delete the key. This feature makes Redis very suitable for caching. The expire command can set how long a key expires (unit: seconds), ttl command can query how long the key expires, and persist command can delete the key expiration time (never expires ).
Wagner. 0.0.1: 6379> set key1 1OK127. 0.0.1: 6379> set key2 2OK127. 0.0.1: 6379> expire key1 30 (integer) 1127.0.0.1: 6379> ttl key1 // key1 expires after 26 seconds (integer) 26127.0.0.1: 6379> ttl key2 // key2 never expires (integer) -1127.0.0.1: 6379> keys * 1) "key1" 2) "key2" 127.0.0.1: 6379> keys * // Delete key1 after expiration 1) "key2" 127.0.0.1: 6379> expire key2 10 (integer) 1127.0.0.1: 6379> ttl key2 (integer) 5127.0.0.1: 6379> persist key2 // enable key2 to never expire (integer) 1127.0.0.1: 6379> ttl key2 (integer)-1127.0.0.1: 6379> keys * 1) "key2" 127.0.0.1: 6379>
Configure redisthe file to be downloaded from redis. decompress it to the directory and run the make command to compile the file.
$ cd redis-2.8.19$ make<pre name="code" class="plain">$ ./src/redis-server
After compilation, some executable files are generated in the src directory. You can run the redis-server command to start the Redis Server. Then you can connect to the redis-cli (Client Connection Tool.
$ ./src/redis-cli 127.0.0.1:6379>
When we started Redis Server, no parameters were specified. Redis will be configured with default parameters. Redis configures its behavior through a configuration file. You can see a redis. in the conf file, each configuration is described in detail. When starting redis, specify the configuration file. You can specify the path of the configuration file after the redis-server command.
$ ./src/redis-server ./redis.conf
By default, all clients can connect to and operate on the Redis Server. You can set requirepass in the redis. conf file to set the password. Redis does not support permission management. Once the client passes verification, it can execute any command, which is very insecure, especially in the production environment. You can use rename-command in the redis. conf file to rename some security-sensitive commands.
For other advanced functions and related configurations of Redis, please look forward to the subsequent chapters...