Django中使用Redis緩存數據庫中部分數據

Redis安裝

一、下載,解壓,安裝c++

[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
複製代碼

二、配置Redis啓動腳本
1)將源碼包的utils/redis_init_script拷貝到/etc/init.d/下,重命名爲redisredis

[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
複製代碼

修改內容:數據庫

REDISPORT=6379  #定義了redis的監聽端口
EXEC=/usr/local/redis/bin/redis-server  # redis默認的server執行路徑
CLIEXEC=/usr/local/redis/bin/redis-cli  # redis-cli啓動路徑
PIDFILE=/var/run/redis_${REDISPORT}.pid

#redis的配置文件, 因此咱們須要在/etc目錄下建立redis目錄用來保存redis的配置文件,並將配置文件拷貝到該目錄下
CONF="/etc/redis/redis.conf"  # redis的配置文件
複製代碼

2)將源碼包下的redis.conf拷貝到/etc/redis/下django

[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
複製代碼

修改內容:緩存

bind 127.0.0.1   # 若是是遠程訪問,修改成公網IP
daemonize yes  # 修改成yes,以守護進程的方式運行
複製代碼

基本設置只有這兩樣,可是我如今只想把Redis作爲緩存,不須要持久化功能,因此我還修改一些別的配置,如下的設置按需設置:安全

loglevel notice  # 日誌等級
logfile "/usr/local/redis/log/redis.log"  # 日誌保存路徑

maxmemory 67108864  # 設置最大佔用內存64M,按需設置

databases 1  # 設置最大數據庫數

requirepass 12345678  # 設置密碼

#save 900 1
#save 300 10
#save 60 10000
save ""  # 關閉RDB持久化

appendonly no  # 關閉AOF持久化
複製代碼

建立日誌目錄/usr/local/redis/log。bash

三、加入系統服務服務器

[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:關閉	1:關閉	2:啓用	3:啓用	4:關閉	5:啓用	6:關閉
複製代碼

chkconfig刪除服務是:chkconfig --del [name],例如chkconfig --del redis。app

四、啓動,中止Redis函數

[root@incisor init.d]# service redis start
[root@incisor init.d]# service redis stop
複製代碼

若是/etc/redis/redis.conf中的bind設置的是公網IP,使用service redis stop是關閉不了的,這個時候我都是查出進程號,直接kill掉。

由於stop命令執行的是/etc/init.d/redis中的stop函數。

其中

$CLIEXEC -p $REDISPORT shutdown
複製代碼

是中止Redis任務,而$CLIEXEC即redis-cli命令,忽略-h參數的話,默認是鏈接127.0.0.1,因此若是/etc/redis/redis.conf中的bind不是127.0.0.1,那麼就須要修改/etc/init.d/redis文件了。 修改以下:

IP=127.0.0.1  # /etc/redis/redis.conf中的bind參數值
REDISPORT=6379
EXEC=/usr/local/redis/bin/redis-server
CLIEXEC=/usr/local/redis/bin/redis-cli

......省略

$CLIEXEC -h $IP -p $REDISPORT shutdown  # 加上-h $IP便可
複製代碼

可是我通常本身測試用的話,都懶得改,直接kill掉。

五、經過命令行客戶端訪問

[root@incisor ~]# /usr/local/redis/bin/redis-cli -h host -p port -a password
複製代碼

Python鏈接Redis

一、安裝redis庫:pip3 install redis

redis提供兩個類Redis和StrictRedis用於實現Redis服務器的命令,Redis是StrictRedis的子類,用於向後兼容舊版本的redis-py。因此經常使用Redis類。

redis鏈接實例是線程安全的,能夠直接將redis鏈接實例設置爲一個全局變量。

二、鏈接Redis服務器

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')))  
複製代碼

須要加上decode_responses=True, 這樣寫入的value是str類型,爲False的話寫入的是字節類型。

三、鏈接池

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(r))
複製代碼

參數max_connections:設置最大鏈接數
這裏有一篇文檔,是分析redis.ConnectionPool()鏈接池源碼的,感興趣的話,能夠看看:www.u3v3.com/ar/1346。

四、將鏈接池設置成單例模式
pool.py文件

import redis

pool = redis.ConnectionPool(max_connections=10, host='127.0.0.1', port=6379, decode_responses=True)
複製代碼

而後,其餘文件,導入pool變量,這樣就能夠實現一個單例的鏈接池了。
test.py文件

import redis
from pool import pool

r = redis.Redis(connection_pool=pool)
r.set('skey', 'svalue')
print(r['skey'])
複製代碼

具體的Redis的數據類型,以及相應的方法,自行查看。

Django中使用Redis,作爲關係型數據庫的緩存

一、安裝django-redis: pip3 install django-redis

二、設置settings.py文件 添加

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": ""
        }
    }
}
複製代碼

其中,"LOCATION"表示鏈接字符串,有三種方式設置:
redis://[:password]@localhost:6379/0
rediss://[:password]@localhost:6379/0
unix://[:password]@/path/to/spcket.sock?db=0
但也有文檔說,某些環境下鏈接密碼放在url是不安全的,這時你能夠選擇忽略密碼或者使用"OPTIONS"設置,因此按需選擇吧。

"CONNECTION_POOL_KWARGS": 鏈接池設置
"max_connections": 最大鏈接數
"decode_responses": 以字符串的形式寫入Redis,爲False的話寫入字節類型。

django-redis使用redis-py的鏈接池接口,redis-py默認不會關閉鏈接,儘量重用鏈接, redis-py實際就是redis庫的Redis中的鏈接池,上一節中說起,說明鏈接池原理是同樣的。

三、Redis存取
有兩種方式:

1)使用django.core.cache.cache類,這個類有巨坑!

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>沒有找到</h1>')
複製代碼

這段代碼運行前,須要將settings.py文件中CACHES中的decode_responses參數設置爲False,具體緣由我沒深究。

運行這段代碼沒任何問題,能寫入能讀取。可是!!!若是這個key-value值是別的客戶端寫入的呢?假如我經過redis-cli命令行工具添加了key-value,那經過cache.get(key)是取不到的,固然這段代碼添加的skey-svalue在客戶端執行get skey也是取不到的。

來,咱們經過命令行工具,查看這段代碼添加的key-value,以下:

[root@incisor ~]# /usr/local/redis/bin/redis-cli -h 127.0.0.1 # 127.0.0.1的話,可忽略-h參數
127.0.0.1:6379> keys *  # 查看所有的鍵
1) ":1:skey"
複製代碼

...原來經過cache.set(key, value),會在key的前面拼接一個字符串":1:",也不知道爲啥。因此我說這個cache是隱形巨坑。

2)經過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>沒有找到</h1>')
複製代碼

執行後,利用redis-cli查看一下key值:

127.0.0.1:6379> keys *
1) "skey"
複製代碼

如今key值不會被拼接字符串了,因此我經常使用這個函數。

使用get_redis_connection()最好把settings.py文件中CACHES中的decode_responses參數設置爲True, 同時conn = get_redis_connection('default')中 的'default'是settings.py文件中CACHES設置的'default'。

相關文章
相關標籤/搜索