This article details how Python uses Redis
1, installation
Pip Install Redis
2, basic use
use:
import Redis
r = Redis. Redis (host= ' localhost ', port=6379, db=0)
r[' test '] = ' Test ' # Or you can r.set (' Test ', ' test ') to set key
r.get (' Test ') #获取test的值
r.delete (' Test ') #删除这个key
r.flushdb () #清空数据库
r.keys () # List all key
r.exists (' Test ') #检测这个key是否存在
r.dbsize () #数据库中多少个条数
>>> import redis>>> pool = Redis. ConnectionPool (host= ' localhost ', port=6379, db=0) >>> r = Redis. Strictredis (Connection_pool = Pool) >>> r.set (' foo ', ' Bar ') true>>> r.get (' foo ') ' Bar '
3.API Reference
The Redis official documentation explains each command in detail (http://www.php.cn/). REDIS-PY provides two client classes that implement these commands. The Strictredis class attempts to comply with the official command syntax, but there are several exceptions:
· SELECT: Not implemented. See the "Thread Safety" section below for explanations.
· Del: ' del ' is a reserved keyword for the Python syntax. So redis-py uses "delete" instead.
· CONFIG get| SET: Implemented by Config_get and Config_set, respectively.
· Multi/exec: Implemented as part of the Pipeline class. If you specify use_transaction=true when calling the pipeline method, pipeline operations are encapsulated with MULTI and EXEC when pipeline is executed. See the Pipeline section below.
· Subscribe/listen: Similar to pipeline, PubSub is implemented as a separate class due to the need for lower-level connections to remain in state. The PubSub method that calls the Redis client returns an instance of PubSub that can subscribe to a channel or listen for a message. Two classes (Strictredis and PubSub classes) can publish (PUBLISH) messages.
In addition to the above changes, Strictredis's sub-Redis provides compatibility with older versions of Redis-py:
· Lrem: The order of the parameter ' num ' and ' value ' is exchanged, so that ' num ' can provide a default value of 0.
· Zadd: The order of score and value was not carefully reversed when implemented, then someone used it, that's all.
· The order of Setex:time and value is reversed.
Note: It's best not to use Redis, this class is just for compatibility
4. Detailed description
4.1 Connection Pool
In the background, Redis-py uses a connection pool (ConnectionPool) to manage the connection to the Redis server. By default, each Redis instance creates its own connection pool. You can also use the Connection_pool parameter of the Redis class to pass the created connection pool. In this way, the management of the client shard or the precise control of the connection can be achieved:
>>> pool = Redis. ConnectionPool (host= ' localhost ', port=6379, db=0) >>> r = Redis. Strictredis (Connection_pool=pool)
4.2 Connections
ConnectionPool manages a set of Connection instances. Redis-py offers two types of Connection. By default, Connection is a normal TCP connection. Unixdomainsocketconnection allows clients that are running on the same device as the server to connect through a UNIX socket. To use a unixdomainsocketconnection connection, you only need to pass a string of UNIX socket files through the Unix_socket_path parameter. Also, make sure that the redis.conf file is configured with the Unixsocket parameter (commented out by default):
>>> r = Redis. Strictredis (unix_socket_path= '/tmp/redis.sock ')
You can also create a Connection subclass yourself. This feature can be used to control the behavior of the socket when using the asynchronous framework. To initialize the client class with your own connection, you need to create a connection pool that passes the Connection_class parameter to your own class. The other keyword arguments passed are passed to the custom class at initialization time:
>>> pool = Redis. ConnectionPool (Connection_class=yourconnectionclass, your_arg= ' ...)
4.3 Analyzer
The analysis class provides a way to control how the Redis server responds to the analysis. REDIS-PY provides two analysis classes, Pythonparser and Hiredisparser. By default, if the Hiredis module is installed, Redis-py tries to use Hiredisparser, otherwise pythonparser is used.
Hiredis is a C library maintained by the Redis core team. Pieter Noordhuis created the implementation of Python. When analyzing the response of a Redis server, the Hiredis can provide 10 times times the speed boost. Performance improvements are obvious when fetching large amounts of data, such as Lrange and smembers operations.
Like Redis-py, Hiredis is available in Pypi and can be installed via PIP or Easy_install:
$ pip Install Hiredis
Or:
$ Easy_install Hiredis
4.4 Response callback function
The client class uses a series of callback functions to convert the Redis response into the appropriate Python type. Some callback functions are defined in the dictionary response_callbacks of the Redis client class.
The Set_response_callback method allows you to add a custom callback function to a single instance. This method accepts two parameters: a command name and a callback function. The callback function added by this method is valid only for the object to which it is added. To define or reload a callback function globally, you should create a subclass of the Redis client and add the callback function to the class's Response_callbacks (the original is mistaken for redis_callbacks).
The response callback function has at least one parameter: The response of the Redis server. To further control how the response is interpreted, you can also use the keyword parameter. These keyword parameters are specified when the command for Execute_command is called. With the "withscores" parameter, Zrange demonstrates how the callback function uses the keyword parameter.
4.5 Thread Safety
Redis client instances can be securely shared between threads. From an internal implementation, the connection instance is only obtained when the command executes, and the connection pool is returned directly after completion, and the command never modifies the state of the client instance.
However, one thing to note: the SELECT command. The SELECT command allows you to toggle the database used by the current connection. The new database remains selected until another database is selected or the connection is closed. This causes the connection to be able to specify a different database when the connection pool is returned.
Therefore, Redis-py does not implement the SELECT command in the client instance. If you want to use multiple Redis databases in the same application, you should create a separate client instance for the first database (and possibly a separate connection pool).
It is not safe to pass PubSub and Pipeline objects between threads.
4.6 Pipeline
Pipeline is a subclass of the Strictredis class that supports multiple commands that send buffers in a single request. By reducing the packets that are exchanged between the client and the server, the performance of the command group can be greatly improved.
Pipeline is very simple to use:
>>> r = Redis. Redis (...) >>> r.set (' Bing ', ' Baz ') >>> # Use the pipeline () method to create a pipeline instance>>> pipe = R.pipeline () >>> # The following SET commands is buffered>>> pipe.set (' foo ', ' Bar ') >>> pipe.g ET (' Bing ') >>> # The EXECUTE call sends all bufferred commands to the server, Returning>>> # a list of RE Sponses, one for each command.>>> pipe.execute () [True, ' Baz ']
For ease of use, all commands buffered to pipeline return the pipeline object itself. So the call can be chained up:
>>> pipe.set (' foo ', ' Bar '). Sadd (' Faz ', ' Baz '). INCR (' Auto_number '). Execute () [True, 6]
In addition, pipeline can also guarantee that the buffered command group is an atomic operation. The default is this mode. To use the command buffer, but prohibit pipeline atomic manipulation properties, you can turn off transaction:
>>> pipe = r.pipeline (Transaction=false)
A common problem is that you need to get the data from Redis before you perform atomic transaction operations. For example, suppose the INCR command does not exist, but we need to create an atomic version of INCR with Python.
An immature implementation is to get the value (get), add one in Python, set a new value. However, this is not an atomic operation, because multiple clients may do it at the same time, each of which gets the same value through get.
The Watch command provides the ability to monitor one or more keys before starting a transaction. If any of these keys changes before the transaction executes, the entire transaction is canceled and the Watcherror exception is thrown. To implement our Customer INCR command, you can do this in the following way:
>>> with R.pipeline () as pipe: ... while 1: .... Try: ... # Watch the key for the serial number ... pipe.watch (' Our-sequence-key ') ... # after Watch executes, pipeline is set to execute mode immediately until we notify it ... # Restart the buffering command. ... # This allows us to get the value of the serial number ... current_value = pipe.get (' Our-sequence-key ') ... next_value = un Icode (int (current_value) + 1) ... # Now we can use the MULTI command to set the pipeline to buffer mode ... pipe.multi (...) Pipe.set (' Our-sequence-key ', next_value) ... # Finally, execute the pipeline (SET command) ... Pipe.execute () ... # If the execution does not throw watcherror, we just did "atom" ... # finished ... break ... except watcherror: ... # It must be the other clients changed between WATCH and execute pipeline ... # ' Our-sequence-key ', our best choice is to try again ... continue
Note that because the Pipeline must be bound to a connection throughout the WATCH process, the Reset () method must be called to ensure that the connection is returned to the connection pool. If Pipeline is used as the Context Manager (as shown in the example above), reset () is automatically called. Of course, you can also explicitly call reset () in a manual way:
>>> pipe = R.pipeline () >>> while 1: ... Try: ... Pipe.watch (' Our-sequence-key ') ... Current_value = Pipe.get (' Our-sequence-key ') ... Next_value = Unicode (int (current_value) + 1) ... Pipe.multi () ... Pipe.set (' Our-sequence-key ', next_value) ... Pipe.execute () ... Break ... Except Watcherror: ... continue ... Finally: ... Pipe.reset ()
Focus (Translator Note):
· After WATCH executes, pipeline is set to execute mode immediately
• Set pipeline to buffer mode with the MULTI command
• Either use with or explicitly call reset ()
There is a simple method called "transaction" to handle this processing and the mode of retry in Watcherror. Its argument is an executable object and the key to WATCH any number, where the executable object accepts a pipeline object as a parameter. The above client INCR command can be rewritten as follows (more readable):
>>> def CLIENT_SIDE_INCR (pipe): ... Current_value = Pipe.get (' Our-sequence-key ') ... Next_value = Unicode (int (current_value) + 1) ... Pipe.multi () ... Pipe.set (' Our-sequence-key ', next_value) >>> >>> r.transaction (CLIENT_SIDE_INCR, ' Our-sequence-key ')