28 redis介绍和安装+python操作redis和连接池+django使用redis

一、 redis介绍和安装

# redis是:数据库,非关系型数据库,nosql数据库(Not Only SQL)
-key-value形式存储,5大数据类型:字符串,列表,字典(hash),集合,有序集合
   -纯内存,存取都在内存,速度很快  10w qps,6w左右
   -redis特点:
  -可以持久化,可以永久存储,存到硬盘上
-单线程,单进程, 6.x之前是,6.x
   -为什么redis单线程架构还这么快?
  -纯内存操作
       -单线程,单进程架构,不存在线程,进程间切换造成的浪费(6.x没有了)
       -高效的网络模型--》IO多路复用  (IO模型,select和epoll的区别)
-http://liuqingzheng.top/python/Python%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/25-IO%E6%A8%A1%E5%9E%8B/

# redis和Memcached
-都是内存操作,速度都很快,基本都用来做缓存
   -reids支持持久化,Memcached只支持字符串,不支持其他类型

# 安装:
-开源软件,意大利,C写的,初期代码只有1w多行
   -使用了IO多路复用的:epoll模型,epoll不支持win,在win的支持就不好
   -微软官方给支持:https://github.com/MicrosoftArchive/redis/releases
-第三方:https://github.com/tporadowski/redis/releases
    -win一路下一步,做成服务
   -mac和linux都是编译安装
    -端口:6379
       
# redis 启动和停止
-win:启动服务和停止服务即可
   -任意路径敲:redis-server   就可以启动服务
-带配置文件启动:redis-service redis.windows-service.conf
   
# 可执行文件
redis-server:启动服务  类似于 mysqld
   redis-cli:客户端命令  类似于 mysql
   
   
# redis-desktop-manager-0.9.3.817 类似于Navicate
-原来开源免费,后来收费了
   -目前来说,只能用我这个

 

二、 Python操作redis和连接池

1 普通链接



# python 操作redis
# pip install redis

# 第一步:导入 Redis类
from redis import Redis
# 第二步:创建链接(地址和端口,如果不传就是本地的6379)
conn=Redis(host='127.0.0.1',port=6379)

# 取值
res=conn.get('name')
print(res)

conn.close() # 关闭链接

2 连接池

POOL.py

import redis
CONN_POOL= redis.ConnectionPool(host='127.0.0.1',port=6379, max_connections=100)  # 池的大小
import redis

# 设计模式:https://www.cnblogs.com/liuqingzheng/p/10038958.html

import sys

# print(sys.path)

# 初始化出池对象
# 这个池应该做成单例,整个程序中只有这一个对象
# 以模块导入,天然单例
from POOL import CONN_POOL  # 绝对导入



# pool = redis.ConnectionPool(host='127.0.0.1',port=6379, max_connections=100) # 池的大小

# 从连接池取一个链接
conn = redis.Redis(connection_pool=CONN_POOL)
print(conn.get('age'))
conn.close() # 把链接放回到连接池

 

三、 redis字符串操作

# 用的多:常用操作
'''
## 常用操作
1 set(name, value, ex=None, px=None, nx=False, xx=False)
2 setnx(name, value)
3 get(name)
4 mget(keys, *args)
5 getset(name, value)
6 getrange(key, start, end)
7 setrange(name, offset, value)
8 setbit(name, offset, value)
9 getbit(name, offset)
10 bitcount(key, start=None, end=None)
11 bitop(operation, dest, *keys)
12 strlen(name)
13 incr(self, name, amount=1)
14 incrbyfloat(self, name, amount=1.0)
15 decr(self, name, amount=1)
16 append(key, value)
'''

from redis import Redis
conn=Redis()
# 1 set(name, value, ex=None, px=None, nx=False, xx=False)

# conn.set('hobby','篮球',ex=3)
# conn.set('hobby','pp',nx=True) # 没有,放能放进去,如果有,不会修改掉原来的
# conn.set('hobby1','pp',xx=True) # 没有,放能放进去,如果有,不会修改掉原来的

'''
ex,过期时间(秒)
px,过期时间(毫秒)
# 用redis做分布式锁
nx,如果设置为True,则只有name不存在时,当前set操作才执行,值存在,就修改不了,执行没效果
xx,如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值
'''

#2 setnx 就是set 但是nx=True
# conn.setnx('hobby','oooo')

# 3 get(name)   --->bytes格式
# res=conn.get('hobby')


# 4 mget(keys, *args)
# res=conn.mget(keys=['name','age','hobby'])
# res=conn.mget('name','age','hobby')

# 5 getset(name, value)
# res=conn.getset('name','彭于晏')

#6 getrange(key, start, end)   前闭后闭区间 ----》字节还是字符?字节
# res=str(conn.getrange('name',0,3),encoding='utf-8')
# res=conn.getrange('name',0,2).decode('utf-8')




# 7 setrange(name, offset, value)

# conn.setrange('name',1,'lqz')

# 8 setbit(name, offset, value) 不需要
# res=conn.getbit('name',1)
# conn.setbit('name',1,0)
# 9 getbit(name, offset)
# 10 bitcount(key, start=None, end=None)

# 12 strlen(name)   字节长度
# res=conn.strlen('name')



# 13 incr(self, name, amount=1) 自增,统计网站,文章,课程访问量
# conn.incr('age')



# 14 incrbyfloat(self, name, amount=1.0)
# conn.incrbyfloat('age',8.9)

# 15 decr(self, name, amount=1)
# conn.decr('age')


# 16 append(key, value)
conn.append('age','nb')

# print(res)
conn.close()



''''
get
set
strlen
append
'''

 

四、 redis列表操作


'''
1 lpush(name,values)


2 lpushx(name,value)


3 llen(name)

4 linsert(name, where, refvalue, value))

4 lrem(name, value, num)


6 lpop(name)

7 lindex(name, index)

8 lrange(name, start, end)

9 ltrim(name, start, end)

10 rpoplpush(src, dst)

11 blpop(keys, timeout)

12brpoplpush(src, dst, timeout=0)


'''

from redis import Redis
conn=Redis()
# 1 lpush(name,values)   # 从列表左侧插入值
# conn.lpush('list1','小明')
# conn.lpush('list1','小红')
# conn.lpush('list1','小张')

# conn.rpush('list1','小方')

# 2 lpushx(name,value)   # name值存在才能插入,否则无变化
# conn.lpushx('list2','小刚')
# conn.lpushx('list1','小刚')

# 3 llen(name)   # 列表长度

# res=conn.llen('list1')

# 4 linsert(name, where, refvalue, value))
'''
  # name,redis的name
  # where,BEFORE或AFTER(小写也可以)
  # refvalue,标杆值,即:在它前后插入数据(如果存在多个标杆值,以找到的第一个为准)
  # value,要插入的数据
'''
# res=conn.linsert('list1','before','小红','lqz') # 有重复的,左侧开始第一个


# 4 lrem(name, count, value)
'''
num=0,删除列表中所有的指定值;
num=2,从前到后,删除2个;
num=-2,从后向前,删除2个
'''
# res=conn.lrem('list1','-2','小红')

# lset(name, index, value) 该某个位置的值,从0开始
# conn.lset('list1',0,'刘德华')


# 6 lpop(name) # 从左侧弹出
# res=conn.lpop('list1')
# res=conn.rpop('list1')

# 7 lindex(name, index)

# res=conn.lindex('list1',1)

# 8 lrange(name, start, end)
# res=conn.lrange('list1',0,2)   # 前闭后闭

# 9 ltrim(name, start, end)
# res=conn.ltrim('list1',1,10)   # 只留这部分


# 10 rpoplpush(src, dst)
# conn.lpush('list2','lqz')
# conn.rpoplpush('list1','list2')

# 11 blpop(keys, timeout) # 如果列表中没有值,会卡在这等着,直到有值,等待多长时间
res=conn.blpop('list2',50)
print(res)
# 12brpoplpush(src, dst, timeout=0)

# print(res)
conn.close()

'''
lpush
lpop
llen
lset
blpop

'''

 

五、redis字典操作

# hash:冲突后解决方法
-开放定址法
  -线性探测再散列
-再哈希法
  -链地址法
'''
1 hset(name, key, value)
  # hsetnx(name, key, value),当name对应的hash中不存在当前key时则创建(相当于添加)
2 hmset(name, mapping)
3 hget(name,key)
4 hgetall(name)
5 hkeys(name)
6 hvals(name)
7 hexists(name, key)
8 hdel(name,*keys)
9 hincrby(name, key, amount=1)
10 hincrbyfloat(name, key, amount=1.0)
11 hscan(name, cursor=0, match=None, count=None)
12 hscan_iter(name, match=None, count=None)
'''

from redis import Redis

conn = Redis()
# 1 hset(name, key, value)
# conn.hset('wife', 'name', '刘亦菲')
# conn.hset('wife', 'age', 34)
# conn.hset('wife', 'height', 167)


# 2 hmset(name, mapping)
# conn.hmset('userinfo',{'name':'lqz','age':19})

# 3 hget(name,key)
# res=conn.hget('userinfo','age')

# 4 hgetall(name)
# res=type(conn.hgetall('userinfo'))
# res=conn.hgetall('userinfo')[b'age']

# 5 hkeys(name)
# res=conn.hkeys('userinfo')

# 6 hvals(name)
# res=conn.hvals('userinfo')

# 7 hexists(name, key)
# res=conn.hexists('userinfo','age')

# 8 hdel(name,*keys)
# res=conn.hdel('userinfo','wife')
# res=conn.hdel('wife','name','age','xx')

# 9 hincrby(name, key, amount=1)
# res=conn.hincrby('wife','height')

# 10 hincrbyfloat(name, key, amount=1.0)


# 11 hscan(name, cursor=0, match=None, count=None)
# https://www.cnblogs.com/xieqiankun/p/python_dict.html
# for i in range(1000):
#     conn.hset('test1', 'test_%s' % i, '鸡蛋%s号' % i)

# res=conn.hscan('test1',cursor=0,count=11)
# res=conn.hscan('test1',cursor=0,count=22)
# print(res)
# print(len(res[1]))
# res=conn.hscan('test1',cursor=32,count=11)
# print(res)
# print(len(res[1]))


# 12 hscan_iter(name, match=None, count=None)
# 获取所有,hgetall,它是分批获取
# res=conn.hscan_iter('test1',count=100) # generator
# print(res)
# for i in res:
#     print(i)


# print(res)
conn.close()


'''
hset
hget
hmset
hmget
hexists
'''

六、 通用操作

'''
1 delete(*names)

# 根据删除redis中的任意数据类型
2 exists(name)

# 检测redis的name是否存在
3 keys(pattern='*')


4 expire(name ,time)
5 rename(src, dst)
6 move(name, db))

7 randomkey()

8 type(name)


'''

from redis import Redis
conn=Redis()
# 1 delete(*names)
# conn.delete('hobby')
# # 根据删除redis中的任意数据类型
# 2 exists(name)
# res=conn.exists('list1','test1')
# print(res)
# # 检测redis的name是否存在 *表示多个字符 ? 表示一个字符
# 3 keys(pattern='*')
# res=conn.keys(pattern='l*')
# res=conn.keys(pattern='lis?')
# print(res)


# 4 expire(name ,time)
# conn.expire('list1',3)


# 5 rename(src, dst)
# conn.rename('test1','test2')

# 6 move(name, db))
# conn.move('test2',1)


# 7 randomkey() # 随机取一个key值,不删除
# res=conn.randomkey()
# print(res)


# 8 type(name)
res=conn.type('userinfo')
print(res)

七、django 使用redis

依赖
>: pip3 install redis

一、通用操作(跟框架无关)

1. utils/redis_pool.py

# 写一个py文件
import redis
POOL = redis.ConnectionPool(host='127.0.0.1', port=6379, max_connections=100)

2.  导入,使用user/views.py


from utils.redis_pool import POOL
import redis
def home(request):
     conn=redis.Redis(connection_pool=POOL)
     conn.set('name','htt')
     conn.close()
     return render(request,"index.html")

配上路由,此时访问http://127.0.0.1:8000/backend/,到redis查看会发现,redis有一条数据,name 对应这htt

二、使用django-redis

1. 安装  pip install django-redis

2.settings/dev.py配置上配置文件

 redis配置,一旦这样配置,django中的缓存,也可以用redis
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": 100},
            "DECODE_RESPONSES": True,
            # "PASSWORD": "",
        }
    }
   
}

3.使用user/views.py(直接使用conn对象)

from django_redis import get_redis_connection
def home(request):
    conn=get_redis_connection('default')
    conn.set('age','18')
    return render(request,"index.html")

此时,访问http://127.0.0.1:8000/backend/,再查看redis,会多出age 对应18

三、如果以后在django 中使用,建议使用这种方法

需要额外安装django-redis

1.settings/dev.py配置上配置文件,将缓存存储位置配置到redis中

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": 100},
            "DECODE_RESPONSES": True,
            # "PASSWORD": "",
        }
    }
   
}

2.使用user/views.py

# 也会存到redis中,最大的好处,cache.set的value值,可以是python的任意类型对象
from django.core.cache import cache     #结合配置文件实现插拔式
def home(request): cache.
set('hobby',['篮球','足球']) #操作cache模块,直接操作缓存 res=cache.get('hobby')
print(res)
return render(request,'index.html')
# cache帮咱们做了封装,可以缓存任意的python对象 # django缓存的内部,拿到对象转成了二进制(pickle),存到了redis中

 

posted @ 2022-02-28 15:41  甜甜de微笑  阅读(345)  评论(0编辑  收藏  举报