首页 > 数据库 >redis使用

redis使用

时间:2023-03-08 20:45:16浏览次数:46  
标签:name res redis 使用 print Redis conn

Redis介绍与安装

redis:缓存数据库 非关系型数据库

什么是 NoSQL ?

NoSQL(NoSQL = Not Only SQL ),意即“不仅仅是SQL”,泛指非关系型的数据库。

Redis的应用场景

  • 缓存
  • 任务队列
  • 网站访问统计
  • 应用排行榜
  • 数据过期处理
  • 分布式集群架构中的 session 分离

优点:

  • 易扩展
  • 灵活的数据模型
  • 大数据量,高性能
  • 高可用
下载 官网下载即可 https://redis.io/download/
已mac为例 

下载好后解压 然后把解压好的包 放到/usr/local/文件夹下

# 进入到redis目录
cd /usr/local/redis-7.0.9 

# 编译测试
sudo make test

# 安装
sudo make install

# 启动服务端
redis-server 指定配置文件  如果不指定,会默认


# 客户端连接redis
	1 方式一
	redis-cli   #默认连接本地的6379端口
    2 方式二:
  redis-cli -h 地址 -p 端口

redis图形化操作软件

Redis Desktop Manager 
直接下载安装即可  

Redis普通连接和连接池

# python  相当于客户端,操作redis
# 安装模块:pip install redis


#补充: django 中操作mysql,没有连接池的,一个请求就是一个mysql连接
	-可能会有问题,并发数过高,导致mysql连接数过高,影响mysql性能
    -使用django连接池:htt .51cto.com/liangdongchang/5140039
    

python普通链接Redis

# 安装redis 模块:pip install redis

# 1 导入模块的Redis类
from redis import Redis

conn = Redis()
# 可以点击Redis查看可配置的参数 链接地址 端口号 链接的库等
# host="localhost",port=6379,db=0,

# 添加值 KV键值对形式
conn.set('name','moon')

# 获取值get KEY得到value
print(conn.get('name'))

连接池链接

###pool.py
import redis
POOL = redis.ConnectionPool(max_connections=10, host='127.0.0.1', port=6379)  # 创建一个大小为10的redis连接池


### 测试代码
import redis
from threading import Thread
from pool import POOL
def task():
    # 做成模块后,导入,无论导入多少次,导入的都那一个POOL对象
    conn = redis.Redis(connection_pool=POOL)  # 报错的原因是拿连接,池里不够了,没有等待,线程报错  设置等待,参数
    print(conn.get('name'))


for i in range(1000):
    t = Thread(target=task)  # 每次都是一个新的连接,会导致 的连接数过多
    t.start()
    
    
    
    
    
# 单例模式:设计模式  23 中设计模式
	-全局只有一个 这个对象 
    p1=Person()  # p1 对象
    p2=Person()  # p2 新对象
    
    -单例模式的6种方式
    	-1 模块导入方式
        -2 。。。
    

Redis value数据类型

# redis 是key-value形式存储
# redis 数据放在内存中,如果断电,数据丢失---》需要有持久化的方案

# 5 种数据类型,value类型
	  -字符串:用的最多,做缓存;做计数器
    -列表: 简单的消息队列
    -字典(hash):缓存
    -集合:去重
    -有序集合:排行榜

Redis 字符串类型操作

conn = Redis()
# 可以点击Redis查看可配置的参数 链接地址 端口号 链接的库等
#  默认为 host="localhost",port=6379,db=0,

# 添加值 KV键值对形式  ex=过期时间(秒)
conn.set('name','moon',ex=30)
conn.set('name','moon111',nx=True)
conn.set('age','moon222',xx=True)
conn.setnx('name','张无忌')
# 相当于 conn.set(nx=True)  只要name有值就不会再更改


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



conn.mset({'k1':'v1','k2':'v2'})
# 批量设置值


# 获取值get KEY得到value
print(conn.get('name'))


conn.mget(['k1', 'k2'])
# 批量获取
如:
    mget('k1', 'k2')
    或
    mget(['k3', 'k4'])

conn.close()


# getset(name, value)
res = conn.getset('k1','v11')
# 设置新值并获取原来的值
print(res) # v1


类似切片取值
# getrange(key, start, end)
res = conn.getrange('k1', 0, 1)
# 取出k1的值 并只要值的 0到1 2个字节
print(res)


获取值的字节长度
# strlen(name)
# 返回name对应值的字节长度(一个汉字3个字节)
res = conn.strlen('k1')
# 一个中文算3个字节 英文和数字都是一个字节
print(res)


conn.close()

整型值的 自增 自减 加减

# 自增 name对应的值,
# 自增数(必须是整数)
# incr(self, name, amount=1)
conn.incr('k3',amount=2)
# 对K3的值 自增2
print(conn.get('k3'))


# 自减,只能是整数,自身也必须是整数
conn.decr('k3',amount=1)
# 对K3的值 自减1
print(conn.get('k3'))


# 自增或自减可以是小数 或整数都可以
# incrbyfloat(self, name, amount=1.0)
conn.incrbyfloat('k3',amount=2.2)
conn.incrbyfloat('k3',amount=-20)
# 对K3的值 自增2
print(conn.get('k3'))


append(key, value)

在redis name对应的值后面追加内容

# 追加,在redis name对应的值后面追加内容
conn.append('k3','ok')
# 对K3的值 字符串后面追加ok eg:张无忌ok
print(conn.get('k3'))

Redis 列表类型操作

List操作,redis中的List在在内存中按照一个name对应一个List来存储。如图

lpush 插入数据 lrange获取数据

conn = Redis()

lpush(name,values)
conn.('l1',1,2,3,4)
# 创建一个键为 l1  值为 一个列表,列表中 依次添加 1,2,3,4
# 如果键不存在则创建,如果键存在 则 对值 头部追加 从左插入
# rpush 则对值进行尾部插入 从右插入 



lpushx(name,values)
# 只有name存在 才可以加入数据,不存在则不生效 



conn.llen('l1')
# 获取列表值 个数


#在列表中 某个数据前或者后插入数值
linsert(name, where, refvalue, value)
#      key   前或者后  标杆  插入的数据
# 如果标杆不存在 则无法插入数据
conn.linsert('l2','after','22','33')
conn.linsert('l1','before','22','11')



# 对l1对应的list中的某一个索引位置重新赋值
conn.lset('l1',0,'9')
# l1的值 的索引0位置 重新赋值为 数据 9


# 在对应的list中删除指定的值
# 删除了l1 列表中的xxx 删除一个,
conn.lrem('l1',1,'xxx')
conn.lrem('l1',-1,'xxx')
# 从右开始删除一个xxx
conn.lrem('l1',0,'xxx')
# 0代表删除列表中所有的xxx



# 从左侧弹出 从头部
res = conn.lpop('l1')
# 从右侧弹出 从尾部
print(res)
res = conn.rpop('l1')
print(res)



# 按照索引位置取值 从0开始
res = conn.lindex('l1',1)
print(res)


# 按照索引位置取值 从0开始
res = conn.lrange('l1',0,1)
print(res)


获取列表内所有的值
res = conn.lrange('l1',0,conn.llen('l1'))
# 从开头到结束


conn.ltrim('l1',2,4)
# 只保留列表中 从索引位置 2 到 4 的数据					

blpop

可以做简单的消息队列使用

res = conn.blpop('l1')
# 从列表左侧弹出一个数据,如果列表空了 代码就会一直等待接收


这样就可以 实现消息队列,等待存入数据,存入数据后 因为在blpop等待中
所以会立即取出


自定义增量迭代

如果列表内数据巨大,那就有必要增量迭代的功能

import redis
conn=redis.Redis(host='127.0.0.1',port=6379)
# conn.lpush('test',*[1,2,3,4,45,5,6,7,7,8,43,5,6,768,89,9,65,4,23,54,6757,8,68])
# conn.flushall()
def scan_list(name,count=2):
    index=0
    while True:
        data_list=conn.lrange(name,index,count+index-1)
        if not data_list:
            return
        index+=count
        for item in data_list:
            yield item
print(conn.lrange('test',0,100))
for item in scan_list('test',5):
    print('---')
    print(item)

Redis Hash类型操作

存储操作

conn = Redis()

conn.hset('d1', mapping={'name':'moon','age':18})
# key = d1  value = {'name':'moon','age':18}

取值操作

print(conn.hget('d1','age'))
# 取单个 返回单个数据
print(conn.hmget('d1','name','age'))
# 取更多 返回是列表


print(conn.hgetall('d1'))
# 取出所有的键值对

print(conn.hlen('d1'))
# Hash中key的个数

print(conn.hkeys('d1'))
# 取出所有的Kye
print(conn.hvals('d1'))
# 取出所有的value


查询/修改操作

print(conn.hexists('d1','hobby'))
# 查询是否有这个key 返回 True 或者 false

conn.hset('d1','hobby','篮球')
# 对字典新增键值对
conn.hdel('d1','hobby')
# 删除某个key

conn.hincrby('d1','age',amount=2)
# 对字典中的某个值 自增或自减  前提数据必须为整数
conn.hincrby('d1','age',amount=-1)


conn.hset('d1','hobby','足球')
# d1 有 bobby 则修改值 无则新增键值对

Redis数据通用方法


''' 通用操作,不指定类型,所有类型都支持
1 delete(*names)
2 exists(name)
3 keys(pattern='*')
4 expire(name ,time)
5 rename(src, dst)
6 move(name, db))
# 移动数据库
7 randomkey()
8 type(name)
'''

import redis

conn = redis.Redis()
# 1 delete(*names)
# conn.delete('name', 'userinfo2')
# conn.delete(['name', 'userinfo2'])  # 不能用它
# conn.delete(*['name', 'userinfo2'])  # 可以用它


# 2 exists(name)
# res=conn.exists('userinfo')
# print(res)


# 3 keys(pattern='*')
# res=conn.keys('w?e')  #  ?表示一个字符,   * 表示多个字符
# print(res)


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

# 5 rename(src, dst)
# conn.rename('hobby','hobby111')

# 6 move(name, db))
# conn.move('hobby111',8)
# 7 randomkey()
# res=conn.randomkey()
# print(res)
# 8 type(name)
# print(conn.type('girls'))
print(conn.type('age'))
conn.close()


redis管道的使用

类似mysql中的事务,例如 银行转账 a对b转账100元

# redis支持事务吗   单实例才支持所谓的事物,支持事务是基于管道的
	-执行命令  一条一条执行
    	-张三 金额 -100    conn.decr('zhangsan_je',100)
        挂了
        -你   金额 100     conn.incr('李四_je',100)
        
        
   - 把这两条命令,放到一个管道中,先不执行,执行excute,一次性都执行完成
	conn.decr('zhangsan_je',100)   conn.incr('李四_je',100)
  
  
 # 如何使用
import redis
conn = redis.Redis()
p=conn.pipeline(transaction=True)
# 开启一条管道 
p.multi()
# 开启批量处理

p.decr('zhangsan_je', 100)
# 在管道中放入操作 
p.incr('lisi_je', 100)
# 在管道中放入操作 

p.execute()
# 一次性执行管道中的所有操作 



# 这样就可以保证 一致性 要不代码都成功 要不都不成功

在django中使用redis

方式一:自定义包方案(通用的,不针对与框架,所有框架都可以用)

eg:统计某个接口的访问次数 

第一步:在utils文件夹内 创建redis_pool文件

import redis

POOL = redis.ConnectionPool(max_connections=20)
# 现在redis_pool.py中 创建一个链接池



第二步:
在需要用的接口 导入这个POOL用
在views.py中
from LufeiApi.utils.redis_pool import POOL
import redis

    @action(methods=['GET'],detail=False)
    def text(self,request):
        conn = redis.Redis(connection_pool=POOL)
        # 生成一个redis对象
        conn.incr('n1',amount=1)
        # 对redis中的 ni key的值 进行自增1
        res = conn.get('n1')
        # 获取对应的值
        return MyResponse({'次数':res})

方式二:django内置缓存更换为redis (推荐django使用)可以存对象

安装  django_redis 模块


在配置文件中添加配置代码
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379",
         # redis的链接地址
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {"max_connections": 100}
            # 自带链接池
            # "PASSWORD": "123",
        }
    }
}



然后在需要用的地方 直接导入 
from django.core.cache import cache
 cache.set('n1',1)
 cache.get('n1')

# 这样就替换了django自带的内容,存的数据都存到了redis中  直接可以通过这种方式存取

    def text(self,request):
        user = User.objects.filter(username='moon').first()
        cache.set(user.username,user)
        # 直接存对象进去 key=对象的名字 value=对象
        res = cache.get('moon')
        # 取出来还是个对象可以直接.数据
        return MyResponse({'phone':res.phone})


方法三:正常连接redis使用

    -方案二:第三方:django-redis模块
    	from django_redis import get_redis_connection
        def test_redis(request):
            conn=get_redis_connection()
            print(conn.get('count'))
            return JsonResponse({'count': '今天这个接口被访问的次数为:%s'}, json_dumps_params={'ensure_ascii': False})


标签:name,res,redis,使用,print,Redis,conn
From: https://www.cnblogs.com/moongodnnn/p/17196190.html

相关文章