django uses redis to cache the database

Posted by jozard on Wed, 09 Feb 2022 10:32:18 +0100

Redis installation

1. Download, unzip, install

[root@incisor ~]# yum install -y gcc gcc-c++ make cmake
[root@incisor ~]# wget http://download.redis.io/releases/redis-5.0.3.tar.gz
[root@incisor ~]# tar -zxvf redis-5.0.3.tar.gz 
[root@incisor ~]# cd redis-5.0.3
[root@incisor redis-5.0.3]# make PREFIX=/usr/local/redis install
 Copy code

2. Configure Redis startup script
1) The utils / redis of the source package_ init_ Copy script to / etc / init D / and rename to redis

[root@incisor redis-5.0.3]# cp -p utils/redis_init_script /etc/init.d/redis
[root@incisor redis-5.0.3]# vi /etc/init.d/redis
 Copy code

Modified content:

REDISPORT=6379  #Defines the listening port of redis
EXEC=/usr/local/redis/bin/redis-server  # redis default server execution path
CLIEXEC=/usr/local/redis/bin/redis-cli  # Redis cli startup path
PIDFILE=/var/run/redis_${REDISPORT}.pid

#Redis configuration file, so we need to create a redis directory in the / etc directory to save the redis configuration file and copy the configuration file to this directory
CONF="/etc/redis/redis.conf" # redis configuration file
Copy code

2) Redis. Redis package Copy conf to / etc/redis /

[root@incisor redis-5.0.3]# mkdir /etc/redis
[root@incisor redis-5.0.3]# cp -p redis.conf /etc/redis/
[root@incisor redis-5.0.3]# vi /etc/redis/redis.conf
 Copy code

Modified content:

bind 127.0.0.1   # For remote access, change to public IP
daemonize yes  # Change to yes to run as a daemon
 Copy code

There are only these two basic settings, but now I just want to use Redis as a cache and do not need the persistence function, so I also modify some other configurations. The following settings are set as needed:

loglevel notice  # Log level
logfile "/usr/local/redis/log/redis.log"  # Log save path

maxmemory 67108864  # Set the maximum memory occupation of 64M, and set it as required

databases 1  # Set the maximum number of databases

requirepass 12345678  # Set password

#save 900 1
#save 300 10
#save 60 10000
save ""  # Turn off RDB persistence

appendonly no  # Turn off AOF persistence
 Copy code

Create the log directory / usr/local/redis/log.

3. Join system services

[root@incisor redis]# cd /etc/init.d/
[root@incisor init.d]# chkconfig --add redis
[root@incisor init.d]# chkconfig --level 235 redis on
[root@incisor init.d]# chkconfig --list redis  # 
redis      	0:close	1:close	2:Enable	3:Enable	4:close	5:Enable	6:close
 Copy code

The chkconfig deletion service is: chkconfig --del [name], for example, chkconfig --del redis.

4. Start and stop Redis

[root@incisor init.d]# service redis start
[root@incisor init.d]# service redis stop
 Copy code

If / etc / redis / redis The bind in conf is set to the public IP address. service redis stop cannot be closed. At this time, I find out the process number and kill it directly.

Because the stop command executes / etc / init Stop function in D / redis.

among

$CLIEXEC -p $REDISPORT shutdown
 Copy code

Is to stop the Redis task, and $CLIEXEC is the Redis cli command. If the - h parameter is ignored, the default connection is 127.0.0.1, so if / etc / Redis / Redis If the bind in conf is not 127.0.0.1, you need to modify / etc / init D / Redis file. Amend as follows:

IP=127.0.0.1  # /etc/redis/redis. bind parameter value in conf
REDISPORT=6379
EXEC=/usr/local/redis/bin/redis-server
CLIEXEC=/usr/local/redis/bin/redis-cli
......ellipsis
$CLIEXEC -h $IP -p $REDISPORT shutdown  # Add -h $IP

But I usually use my own test. I don't bother to change it and just kill it.

5. Client access via command line

[root@incisor ~]# /usr/local/redis/bin/redis-cli -h host -p port -a password
 Copy code

Python connection to Redis

1. Install redis Library: pip3 install redis

Redis provides two classes: redis and StrictRedis, which are used to implement the commands of redis server. Redis is a subclass of StrictRedis and is used for backward compatibility with the old version of redis py. Therefore, redis classes are often used.

The redis connection instance is thread safe. You can directly set the redis connection instance as a global variable.

2. Connect to Redis server

import redis

r = redis.Redis(host='127.0.0.1', port=6379, decode_responses=True)
r.set('skey', 'svalue')
print(r['skey'])
print(r.get('skey'))
print(type(r.get('skey')))
Copy code

You need to add decode_responses=True, so the value written is str type, and if it is False, it is byte type.

3. Connection pool

import redis

pool = redis.ConnectionPool(max_connections=10, host='127.0.0.1', port=6379, decode_responses=True)
r = redis.Redis(connection_pool=pool)
r.set('skey', 'svalue')
print(r['skey'])
print(id®)
Copy code

Parameter max_connections: sets the maximum number of connections

Here is a document that analyzes redis The source code of connectionpool() connection pool. If you are interested, you can see: www.u3v3.com/ar/1346.

4. Set the connection pool to singleton mode
pool.py file

import redis

pool = redis.ConnectionPool(max_connections=10, host='127.0.0.1', port=6379, decode_responses=True)
Copy code

Then, import the pool variable from other files, so that a singleton connection pool can be realized.

test.py file

import redis
from pool import pool

r = redis.Redis(connection_pool=pool)
r.set('skey', 'svalue')
print(r['skey'])
Copy code

The specific Redis data types and corresponding methods can be viewed by yourself.

Redis is used in Django as the cache of relational database

1. Install Django redis: PIP3 install Django redis

2. Set settings Py file add

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/0",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {"max_connections": 10, "decode_responses": True},
            # "PASSWORD": ""
        }
    }
}
Copy code

Where, "LOCATION" refers to the connection string, which can be set in three ways:
redis://[:password]@localhost:6379/0
rediss://[:password]@localhost:6379/0
unix://[:password]@/path/to/spcket.sock?db=0
However, some documents say that it is not safe to put the connection password at the url in some environments. At this time, you can choose to ignore the password or use the "OPTIONS" setting, so choose as needed.

"CONNECTION_POOL_KWARGS": connection pool settings
"max_connections": maximum connections
"decode_responses": write Redis in the form of string. If it is False, write the byte type.

Django redis uses the connection pool interface of redis py. By default, redis py will not close the connection and reuse the connection as much as possible. Redis py is actually the connection pool in redis of redis library. As mentioned in the previous section, it shows that the principle of connection pool is the same.

3. Redis access
There are two ways:

1) Use Django core. cache. Cache class, this class has a huge pit!

from django.core.cache import cache
from django.http import HttpResponse

def hello(request):
key = 'skey'
value = 'svalue'
cache.set(key, value)
if key in cache:
return HttpResponse('<h1>{0}: {1}</h1>'.format(key, cache.get(key)))
else:
return HttpResponse('< H1 > not found < / H1 >')
Copy code

Before running this code, you need to set settings Decode in cache in py file_ The responses parameter is set to False. I didn't delve into the specific reasons.

There is no problem running this code. It can be written and read. But!!! What if this key value is written by another client? If I add key value through redis cli command-line tool, I can use cache Get (key) cannot be obtained. Of course, skey svalue added in this code cannot be obtained when get skey is executed on the client.

Let's check the key value added in this code through the command line tool, as follows:

[root@incisor ~]# /usr/local/redis/bin/redis-cli -h 127.0.0.1  # 127.0.0.1, the - h parameter can be ignored
127.0.0.1:6379> keys *  # View all keys
1) ":1:skey"
Copy code

... Originally through cache Set (key, value) will splice a string ": 1:" in front of the key. I don't know why. So I say this cache is an invisible giant pit.

2) Through get_redis_connection()

from django_redis import get_redis_connection
from django.http import HttpResponse

def hello(request):
key = 'skey'
value = 'svalue'
conn = get_redis_connection('default')
conn.set(key, value)
if conn.get(key):
return HttpResponse('<h1>{0}: {1}</h1>'.format(key, conn.get(key)))
else:
return HttpResponse('< H1 > not found < / H1 >')
Copy code

After execution, use redis cli to check the key value:

127.0.0.1:6379> keys *
1) "skey"
Copy code

Now the key value will not be spliced into strings, so I often use this function.

Use get_redis_connection() is better to set settings Decode in cache in py file_ The responses parameter is set to True and conn = get_ redis_ 'default 'in connection ('default') is settings 'default 'of cache setting in py file.

Topics: Django