一、缓存的原理

1、redis部署

mkdir /apps/demo/redis/{conf,data} -p
cd /apps/demo/redis


#拉取镜像
docker pull redis:6.2.7

  vi conf/redis.conf

bind 0.0.0.0


maxmemory 4GB
maxmemory-policy allkeys-lru
maxmemory-samples 10

tcp-backlog 511


aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
rdbcompression yes
rdbchecksum yes


aof-rewrite-incremental-fsync yes

requirepass 123456
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command CONFIG ""


activerehashing yes
dynamic-hz yes
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64

配置说明

bind 0.0.0.0     #允许外部访问

## 内存优化
maxmemory 4GB                                   # 设置Redis实例的最大内存限制
maxmemory-policy allkeys-lru                    # 设置在达到最大内存限制时所采取的淘汰策略为LRU(最近最少使用)
maxmemory-samples 10                            # 指定在key的过期删除策略中随机抽取的样本数目

## 网络优化
tcp-backlog 511                                 # 设置内核中由Redis监听的TCP连接的最大长度

## 持久化优化
aof-rewrite-incremental-fsync yes               # 启用AOF(Append Only File)增量式文件同步
rdb-save-incremental-fsync yes                  # 使用增量传输来持久化RDB文件
rdbcompression yes                              # 开启RDB文件的压缩
rdbchecksum yes                                 # 启用RDB文件的校验和

## AOF压缩
aof-rewrite-incremental-fsync yes               # 启用AOF(Append Only File)增量式文件同步

## 安全
requirepass yourpassword                        # 设置Redis服务器连接密码
rename-command FLUSHDB ""                       # 重命名FLUSHDB命令
rename-command FLUSHALL ""                      # 重命名FLUSHALL命令
rename-command CONFIG ""                         # 重命名CONFIG命令

## 性能优化
activerehashing yes                             # 启用集群环境的rehashing(对已有的键表重新分布)
dynamic-hz yes                                 
hash-max-ziplist-entries 512                    # 设置hash结构的压缩阈值
hash-max-ziplist-value 64                       # 设置hash结构的压缩阈值
list-max-ziplist-entries 512                    # 设置list结构的压缩阈值
list-max-ziplist-value 64                       # 设置list结构的压缩阈值
set-max-intset-entries 512                      # 设置intset编码的集合的最大元素数量
zset-max-ziplist-entries 128                    # 设置zset结构的压缩阈值
zset-max-ziplist-value 64                       # 设置zset结构的压缩阈值

2、启动服务

vi ./run.sh

 docker run -p 36379:6379 --name redis \
 -v ./data:/data \
 -v ./conf/redis.conf:/etc/redis/redis.conf \
 -d redis:6.2.7 \
 redis-server /etc/redis/redis.conf

运行

sh run.sh

二、Redis使用

 Python 框架学习 Django篇 (十) Redis 缓存-LMLPHP

https://blog.csdn.net/qq_43745578/article/details/128569060

 1、登录redis

#登录redis容器
docker exec -it redis bash

#通过redis客户端登录数据库
redis-cli -h 127.0.0.1

#认证用户
auth 123456

 Python 框架学习 Django篇 (十) Redis 缓存-LMLPHP

2、redis数据库切换

select 1

 Python 框架学习 Django篇 (十) Redis 缓存-LMLPHP

3、添加数据

127.0.0.1:6379[1]> set zhangsan:1 ynby
OK

127.0.0.1:6379[1]> get zhangsan:1
"ynby"

4、查询所有的key

127.0.0.1:6379[1]> keys zha*
1) "zhangsan:1"
127.0.0.1:6379[1]>

5、删除数据

127.0.0.1:6379[1]> del zhangsan:1
(integer) 1
127.0.0.1:6379[1]> keys *
(empty array)

6、添加哈希值

#添加hash值
127.0.0.1:6379[1]> hmset user:2001 level 10 coin 1977 name 你好
OK

#获取单个字段的值hget
127.0.0.1:6379[1]> hget user:2001 coin
"1977"


#获取所有字段的值hgetall
127.0.0.1:6379[1]> hgetall user:2001
1) "level"
2) "10"
3) "coin"
4) "1977"
5) "name"
6) "\xe4\xbd\xa0\xe5\xa5\xbd"

7、定义哈希表

#添加表数据
hmset usertable u2001  id:2001|level:10|coin:1977|name:张三
hmset usertable u2002  id:2002|level:13|coin:1927|name:李四

#查询表数据
127.0.0.1:6379[1]> hget usertable u2002
"id:2002|level:13|coin:1927|name:\xe6\x9d\x8e\xe5\x9b\x9b"

三、Django项目缓存配置

1、安装redis库

pip install django-redis

2、配置django全局缓存

Django_demo/Django_demo/settings.py

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://101.43.156.78:36379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            # 密码
            'PASSWORD': '123456',  #没有密码就去掉这行
        }
    }
}

3、使用缓存配置

举个例子

 Django_demo/Django_demo/settings.py

# 记录全局的缓存key,防止重复
class CK:
    # 列出药品 的 缓存 key
    MedineList   = 'list_medicine'
    # 列出客户 的 缓存 key
    CustomerList = 'list_customer'

4、修改查询数据的缓存配置

Django_demo/mgr/medicine.py

#添加
from Django_demo import settings
import json
import traceback
from django.core.paginator import Paginator, EmptyPage
from django.db.models import Q
from django_redis import get_redis_connection

# 获取一个和Redis服务的连接
rconn = get_redis_connection("default")

def listmedicine(request):
    try:
        # 查看是否有 关键字 搜索 参数
        keywords = request.params.get('keywords',None)
        # 要获取的第几页
        pagenum = request.params['pagenum']
        # 每页要显示多少条记录
        pagesize = request.params['pagesize']

        # 先看看缓存中是否有
        cacheField = f"{pagesize}|{pagenum}|{keywords}" # 缓存 field

        cacheObj = rconn.hget(settings.CK.MedineList,
                              cacheField)


        # 缓存中有,需要反序列化
        if cacheObj:
            print('缓存命中')
            retObj = json.loads(cacheObj)


        # 如果缓存中没有,再去数据库中查询
        else:
            print('缓存中没有')

            # 返回一个 QuerySet 对象 ,包含所有的表记录
            qs = Medicine.objects.values().order_by('-id')

            if keywords:
                conditions = [Q(name__contains=one) for one in keywords.split(' ') if one]
                query = Q()
                for condition in conditions:
                    query &= condition
                qs = qs.filter(query)


            # 使用分页对象,设定每页多少条记录
            pgnt = Paginator(qs, pagesize)

            # 从数据库中读取数据,指定读取其中第几页
            page = pgnt.page(pagenum)

            # 将 QuerySet 对象 转化为 list 类型
            retlist = list(page)

            retObj = {'ret': 0, 'retlist': retlist,'total': pgnt.count}

            # 存入缓存
            rconn.hset(settings.CK.MedineList,
                       cacheField,
                       json.dumps(retObj))

        # total指定了 一共有多少数据
        return JsonResponse(retObj)

    except EmptyPage:
        return JsonResponse({'ret': 0, 'retlist': [], 'total': 0})

    except:
        print(traceback.format_exc())
        return JsonResponse({'ret': 2,  'msg': f'未知错误\n{traceback.format_exc()}'})

5、添加缓存数据更新

def addmedicine(request):

    info    = request.params['data']

    # 从请求消息中 获取要添加客户的信息
    # 并且插入到数据库中
    medicine = Medicine.objects.create(name=info['name'] ,
                            sn=info['sn'] ,
                            desc=info['desc'])


    # 同时删除整个 medicine 缓存数据
    # 因为不知道这个添加的药品会影响到哪些列出的结果
    # 只能全部删除
    rconn.delete(settings.CK.MedineList)

    return JsonResponse({'ret': 0, 'id':medicine.id})


def modifymedicine(request):

    # 从请求消息中 获取修改客户的信息
    # 找到该客户,并且进行修改操作

    medicineid = request.params['id']
    newdata    = request.params['newdata']

    try:
        # 根据 id 从数据库中找到相应的客户记录
        medicine = Medicine.objects.get(id=medicineid)
    except Medicine.DoesNotExist:
        return  {
                'ret': 1,
                'msg': f'id 为`{medicineid}`的药品不存在'
        }


    if 'name' in  newdata:
        medicine.name = newdata['name']
    if 'sn' in  newdata:
        medicine.sn = newdata['sn']
    if 'desc' in  newdata:
        medicine.desc = newdata['desc']

    # 注意,一定要执行save才能将修改信息保存到数据库
    medicine.save()

    # 同时删除整个 medicine 缓存数据
    # 因为不知道这个修改的药品会影响到哪些列出的结果
    # 只能全部删除
    rconn.delete(settings.CK.MedineList)

    return JsonResponse({'ret': 0})


def deletemedicine(request):

    medicineid = request.params['id']

    try:
        # 根据 id 从数据库中找到相应的药品记录
        medicine = Medicine.objects.get(id=medicineid)
    except Medicine.DoesNotExist:
        return  {
                'ret': 1,
                'msg': f'id 为`{medicineid}`的客户不存在'
        }

    # delete 方法就将该记录从数据库中删除了
    medicine.delete()

    # 同时删除整个 medicine 缓存数据
    # 因为不知道这个删除的药品会影响到哪些列出的结果
    # 只能全部删除
    rconn.delete(settings.CK.MedineList)

    return JsonResponse({'ret': 0})

6、测试访问药品表

vi main.py

import  requests,pprint

#添加认证
payload = {
    'username': 'root',
    'password': '12345678'
}
#发送登录请求
response = requests.post('http://127.0.0.1:8000/api/mgr/signin',data=payload)
#拿到请求中的认证信息进行访问
set_cookie = response.headers.get('Set-Cookie')




# 构建添加 客户信息的 消息体,是json格式
payload = {
    'action': 'list_medicine',
    'pagenum': 1,
    'pagesize' : 3
}

url='http://127.0.0.1:8000/api/mgr/medicines/'

if set_cookie:
    # 将Set-Cookie字段的值添加到请求头中
    headers = {'Cookie': set_cookie}

    # 发送请求给web服务
    response = requests.post(url,json=payload,headers=headers)
    pprint.pprint(response.json())

返回

{'ret': 0,
 'retlist': [{'desc': 'gmkl', 'id': 6, 'name': 'gmkl', 'sn': '111'}],
 'total': 1}
127.0.0.1:6379[1]> hgetall list_medicine
1) "3|1|None"
2) "{\"ret\": 0, \"retlist\": [{\"id\": 6, \"name\": \"gmkl\", \"sn\": \"111\", \"desc\": \"gmkl\"}], \"total\": 1}"

7、测试添加药品表

vi main1.py

import  requests,pprint

#添加认证
payload = {
    'username': 'root',
    'password': '12345678'
}
#发送登录请求
response = requests.post('http://127.0.0.1:8000/api/mgr/signin',data=payload)
#拿到请求中的认证信息进行访问
set_cookie = response.headers.get('Set-Cookie')




# 构建添加 客户信息的 消息体,是json格式
payload = {
    "action":"add_medicine",
    "data":{
        "name":"lhms",
        "sn":"test",
        "desc":"test",

    }
}


url='http://127.0.0.1:8000/api/mgr/medicines/'

if set_cookie:
    # 将Set-Cookie字段的值添加到请求头中
    headers = {'Cookie': set_cookie}

    # 发送请求给web服务
    response = requests.post(url,json=payload,headers=headers)
    pprint.pprint(response.json())

返回

{'id': 7, 'ret': 0}

 Python 框架学习 Django篇 (十) Redis 缓存-LMLPHP

127.0.0.1:6379[1]> hgetall list_medicine
1) "3|1|None"
2) "{\"ret\": 0, \"retlist\": [{\"id\": 7, \"name\": \"lhms\", \"sn\": \"test\", \"desc\": \"test\"}, {\"id\": 6, \"name\": \"gmkl\", \"sn\": \"111\", \"desc\": \"gmkl\"}], \"total\": 2}"

 Python 框架学习 Django篇 (十) Redis 缓存-LMLPHP

 缓存成功~

11-14 07:04