Redis字符串、hash、列表方法使用以及Redis管道与Django集成Redis

news2025/7/11 2:08:04

目录标题

  • 一、Redis字符串操作
  • 二、Redis-hash操作
  • 三、Redis列表操作
  • 四、Redis管道
  • 五、Redis其他操作
  • 六、Django中集成Redis
  • 七、Celery介绍

一、Redis字符串操作

名称属性
setex:过期时间(秒)

px:过期时间(毫秒)

nx:如果设置为True,则只有name不存在时,当前set操作才执行,值存在,就修改不了,执行没效果

xx:如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值

setnxname,value 设置值 只有name不存在时执行设置操作(添加),如果存在不会修改
psetexname,time_ms,value time_ms过期时间(数字毫秒或timedelta对象)
mset*args,**kwargs 批量设置值 mset(k1=‘v1’, k2=‘v2’)

或mget({‘k1’: ‘v1’, ‘k2’: ‘v2’})

getvalue 获取值
mgetkeys,*args 批量获取 mget(‘k1’, ‘k2’)
getsetname value 设置新值并获取原来的值
getrangekey, start, end获取子序列(根据字节获取,非字符)name,Redis 的 name,start,起始位置(字节)end,结束位置(字节)

如:“彭于晏”, 0-3表示“彭”

setrangename, offset, value修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加)

offset:字符串的索引,字节(一个汉字三个字节)value:要设置的值

setbitname, offset, value对name对应值的二进制表示的位进行操作

name:redis的name offset:位的索引(将值变换成二进制后再进行索引)value:值只能是 1 或 0

如果在Redis中有一个对应: n1 = “foo”,那么字符串foo的二进制表示为:01100110 01101111 01101111

所以,如果执行 setbit(‘n1’, 7, 1),则就会将第7位设置为1,那么最终二进制则变成 01100111 01101111 01101111,即:“goo”

getbitname offset获取name对应的值的二进制表示中的某位的值 (0或1)
bitcountkey, start=None, end=None获取name对应的值的二进制表示中 1 的个数key,Redis的name,start位起始位置,end结束位置
strlenname返回name对应值的字节长度(一个汉字3个字节)
incrself, name, amount=1自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。
incrbyfloatself, name, amount=1.0自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。
decrself, name, amount=1自减 name对应的值,当name不存在时,则创建name=amount,否则,则自减。
appendkey, value在redis name对应的值后面追加内容key, redis的name,value, 要追加的字符串

import redis

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

# conn.set('name','lqz') # value 只能是字符串或byte格式
# conn.set('name','lqz',ex=3) # ex 是过期时间,到3s过期,数据就没了
# conn.set('name','lqz',px=3000) # px 是过期时间,到3s过期,数据就没了
# conn.set('age',25,nx=True) # redis 实现分布式锁:https://zhuanlan.zhihu.com/p/489305763
# conn.set('hobby', '足球', xx=False)


# 2 setnx(name, value)   就是:set nx=True
# conn.setnx('hobby1','橄榄球')


# 3 psetex(name, time_ms, value)  本质就是 set px设置时间
# conn.psetex('name',3000,'lqz')

# 4 mset(*args, **kwargs)  传字典批量设置
# conn.mset({'name':'xxx','age':19})


# 5 get(name)  获取值,取到是bytes格式   ,指定:decode_responses=True,就完成转换
# print(conn.get('name'))
# print(str(conn.get('name')[:3],encoding='utf-8'))

# 5 mget(keys, *args)  #批量获取
# res=conn.mget('name','age')
# res=conn.mget(['name','age'])
# print(res)

# 6 getset(name, value)  # 先获取,再设置
# res=conn.getset('name','lqz')
# print(res)


# 7 getrange(key, start, end) # 取的是字节,前闭后闭区间
# res=conn.getrange('name',0,1)
# print(res)

# 8 setrange(name, offset, value)  # 从某个起始位置开始替换字符串
# conn.setrange('name', 1, 'xxx')

# 9 setbit(name, offset, value)
# conn.setbit('name',1,0)   #lqz  00000000   00000000   00000000
# res=conn.get('name')
# print(res)


# 10 getbit(name, offset)
# res=conn.getbit('name',1)
# print(res)


# 11 bitcount(key, start=None, end=None)
# print(conn.bitcount('name',0,3))  # 3 指的是3个字符

# 12 strlen(name)  # 统计字节长度
# print(conn.strlen('name'))
# print(len('lqz政'))  # len 统计字符长度

# 13 incr(self, name, amount=1)  # 计数器
# conn.incr('age',amount=3)


# 14 incrbyfloat(self, name, amount=1.0)

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

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

二、Redis-hash操作

名称属性
hsetname, key, value,name对应的hash中设置一个键值对(不存在,则创建;否则,修改)

name,redis的name,key,name对应的hash中的key,value,name对应的hash中的value

hmsetname, mapping,在name对应的hash中批量设置键值对,如:r.hmset(‘xx’, {‘k1’:‘v1’, ‘k2’: ‘v2’})
hgetname,key 在name对应的hash中获取根据key获取value
hgetallname获取name对应hash的所有键值 如:print(re.hgetall(‘xxx’).get(b’name’))
hlenname 获取name对应的hash中键值对的个数
hkeysname 获取name对应的hash中所有的key的值
hvalsname 获取name对应的hash中所有的value的值
hexistsname key 检查name对应的hash是否存在当前传入的key
hdelname *key 将name对应的hash中指定key的键值对删除 如:print(re.hdel(‘xxx’,‘sex’,‘name’))
hincrbyname key amount=1 自增name对应的hash中的指定key的值,不存在则创建key=amount
hincrbyfloatname, key, amount=1.0 自增name对应的hash中的指定key的值,不存在则创建key=amount
hscanname, cursor=0, match=None, count=None增量式迭代获取,对于数据大的数据非常有用,hscan

可以实现分片的获取数据,并非一次性将数据全部获取完,从而放置内存被撑爆

cursor:游标(基于游标分批取获取数据),match:匹配指定key,默认None 表示所有的key,count:每次分片最少获取个数,默认None表示采用Redis的默认分片个数,直到返回值cursor的值为0时,表示数据已经通过分片获取完毕

hscan_itername, match=None, count=None,利用yield封装hscan创建生成器,实现分批去redis中获取数据

match:匹配指定key,默认None 表示所有的key,count:每次分片最少获取个数,默认None表示采用Redis的默认分片个数

如:for item in r.hscan_iter(‘xx’):print(item)

### redis 只支持一层的5大数据类型
import redis
conn = redis.Redis(decode_responses=True)
# 1 hset(name, key, value)
# conn.hset('userinfo', 'name', '彭于晏')
# conn.hset('userinfo', 'age', '32')
# conn.hset('xx',mapping={'name':'xxx','hobby':'篮球'})


# 2 hmset(name, mapping)   弃用了
# conn.hmset('yy',{'a':'a','b':'b'})


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

# 4 hmget(name, keys, *args)
# res=conn.hmget('userinfo',['name','age'])
# print(res)

# 5 hgetall(name)    慎用,可能会造成 阻塞 尽量不要在生产代码中执行它
# res=conn.hgetall('userinfo')
# print(res)


# 6 hlen(name)
# res=conn.hlen('userinfo')
# print(res)


# 7 hkeys(name)
# res=conn.hkeys('userinfo')
# print(res)
# 8 hvals(name)
# res=conn.hvals('userinfo')
# print(res)

# 9 hexists(name, key)
# res=conn.hexists('userinfo','name')
# print(res)

# 10 hdel(name,*keys)
# conn.hdel('userinfo','age')


# 11 hincrby(name, key, amount=1)
# conn.hincrby('userinfo','age')

# 12 hincrbyfloat(name, key, amount=1.0)
# conn.hincrbyfloat('userinfo','age',5.44)

## 联合起来讲:不建议使用hgetall,分片取值
# 分批获取               生成器应用在哪了?
# 13 hscan(name, cursor=0, match=None, count=None)
# hash类型没有顺序---》python字典 之前没有顺序,3.6后有序了    python字段的底层实现
# for i in range(1000):
#     conn.hset('test_hash','key_%s'%i,'鸡蛋%s号'%i)

# count 是要取的条数,但是不准确,有点上下浮动
# 它一般步单独用
# res=conn.hscan('test_hash',cursor=0,count=19)
# print(res)
# print(res[0])
# print(res[1])
# print(len(res[1]))
# res=conn.hscan('test_hash',cursor=res[0],count=19)
# print(res)
# print(res[0])
# print(res[1])
# print(len(res[1]))


# 咱么用它比较多,它内部封装了hscan,做成了生成器,分批取hash类型所有数据
# 14 hscan_iter(name, match=None, count=None)  获取所有hash的数据
res = conn.hscan_iter('test_hash',count=100)
print(res)  # 生成器
for item in res:
    print(item)

conn.close()

三、Redis列表操作

名称属性
lpushname,values,在name对应的list中添加元素,每个新的元素都添加到列表的最左边

如:r.lpush(‘oo’, 11,22,33)保存顺序是33,22,11

lpushxname,value,在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边
rpushxname,value,在name对应的list中添加元素,只有name已经存在时,值添加到列表的最右边
llenname, name对应的list元素的个数
linsertname,where,refvalue,value在name对应的列表的某一个值前或后插入一个新值

name>redis的name,where>BEFORE或AFTER(小写也可以),refvalue>标杆值,即:在它前后插入数据(如果存在多个标杆值,以找到的第一个为准),value>要插入的数据

lsetname, index, value对name对应的list中的某一个索引位置重新赋值

name>redis的name,index>list的索引位置,value>要设置的值

lremname,value,num在name对应的list中删除指定值

name>redis的name,value>要删除的值,num0表示所有,2表示从前往后删除2个,-2表示从后往前删除2个

lpopname在name对应的列表的左侧获取第一个元素并在列表中移除,返回值则是第一个元素
lindexname,index在name对应的列表中根据索引获取列表元素
lrangename,start,end在name对应的列表分片获取数据如:print(re.lrange(‘aa’,0,re.llen(‘aa’)))
ltrimname,start,end在name对应的列表中移除没有在start-end索引之间的值
rpoplpushsrc,dst,从一个列表取出最右边的元素,同时将其添加至另一个列表的最左边
blpopkeys,timeout将多个列表排列,按照从左到右去pop对应列表的元素,kews表示redis中name的集合

timeout,超时时间,当元素所有列表的元素获取完之后,阻塞等待列表内有数据的时间(秒), 0 表示永远阻塞

brpoplpushsrc,dst,timeout=0从一个列表的右侧移除一个元素并将其添加到另一个列表的左侧

自定义增量迭代


由于redis类库中没有提供对列表元素的增量迭代,如果想要循环name对应的列表的所有元素,那么就需要:

  1. 获取name对应的所有列表
  2. 循环列表
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管道

关于管道在市面上有问多问题例如:Redis数据库,是否支持事务?

Redis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作。

Redis事务机制可以保证一致性和隔离性,无法保证持久性,但是对于redis而言,本身是内存数据库,所以持久化不是必须属性。原子性需要自己进行检查,尽可能保证
Redis 不像mysql一样,支持强事务,事务的四大特性不能全部满足,但是能满足一部分,通过redis的管道实现的(redis本身不支持事务,但是可以通过管道,实现部分事务)

Redis 通过管道,来保证命令要么都成功,要么都失败,完成事务的一致性,但是管道只能用在单实例,集群环境中,不支持pipline

import redis

conn = redis.Redis()
pipline = conn.pipeline(transaction=True)
pipline.decr('a', 2)  # a减2
raise Exception('我崩了')
pipline.incr('b', 2)  # b加2
pipline.execute()      # 保持了事物的一致性 a-2 b没成功!所以都没修改
conn.close()

五、Redis其他操作

名称属性
deletename根据删除redis中的任意数据类型
existsname检测redis中的name是否存在
keyspattern=* 根据模型获取redis的name
expirename,time为某个redis的某个name设置超时时间
renamesrc,dst, 对redis的name重命名为
movename,db,将redis的某个值移动到指定的db下
randomkey随机获取一个redis的name(不删除)
typename获取name对应值的类型
# 集合,有序集合 --- redis模块提供的方法API
# 通用操作:无论是5大类型的那种,都支持

import redis

conn = redis.Redis()
# 1 delete(*names)
# conn.delete('age', 'name')

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


# 3 keys(pattern='*')
# res=conn.keys('*o*')
# res=conn.keys('?o*')
# print(res)

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


# 5  rename(src, dst) # 对redis的name重命名为
# conn.rename('xx','xxx')


# 6 move(name, db) # 将redis的某个值移动到指定的db下
# 默认操作都是0 库,总共默认有16个库
# conn.move('xxx',2)


# 7  randomkey()  随机获取一个redis的name(不删除)
# res=conn.randomkey()
# print(res)

# 8 type(name)  查看类型
# res = conn.type('aa')  # list  hash set
# print(res)

conn.close()

六、Django中集成Redis

方式一:直接使用

from script.POOL import pool
import redis

def index(request):
    conn = redis.Redis(connection_pool=pool)
    conn.incr('page_view')
    res = conn.get('page_view')
    return HttpResponse('被你Look Me %s次了' % res)

pool = redis.ConnectionPool(max_connections=100, host='127.0.0.1', port=6379)

方式二:使用第三方模块: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}
                # "PASSWORD": "123",
            }
        }
    }

from django_redis import get_redis_connection
    def index(request):
        conn = get_redis_connection(alias="default") # 每次从池中取一个链接
        conn.incr('page_view')
        res = conn.get('page_view')
        return HttpResponse('被你看了%s次' % res)

方式三:借助于django的缓存使用redis

	-如果配置文件中配置了 CACHES  ,以后django的缓存,数据直接放在redis中
    -以后直接使用cache.set 设置值,可以传过期时间
    -使用cache.get 获取值
    -强大之处在于,可以直接缓存任意的python对象,底层使用pickle实现的

在这里插入图片描述

七、Celery介绍

Celery翻译过来叫芹菜 它是一个分布式的异步任务 框架
Celery有什么用?

  1. 完成异步任务:可以提高项目的并发量,之前开启线程做,现在使用celery做
  2. 完成延迟任务
  3. 完成定时任务

架构

  • 消息中间件:broker 提交的任务(函数)都放在这里,celery本身不提供消息中间件,需要借助于第三方:redis,rabbitmq
  • 任务执行单元:worker,真正执行任务的地方,一个个进程,执行函数
  • 结果存储:backend,函数return的结果存储在这里,celery本身不提供结果存储,借助于第三方:redis,数据库,rabbitmq

在这里插入图片描述

技术小白记录学习过程,有错误或不解的地方请指出,如果这篇文章对你有所帮助请点点赞收藏+关注谢谢支持 !!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/6778.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

毕业设计:SpringBoot+Vue+Element的校内跑腿平台

作者主页:编程指南针 作者简介:Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容:Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助 文末获取源码 项目编号:BS-XX-…

MySQL基础总结

一.sql数据及语言基本类型: 1.语言的分类 DDL:数据定义语言,用来定义数据库对象:数据库,表,列等。关键字:create,alter,drop等 DML:数据操作语言,用来对数据库中表的记录进行操作。关键字:insert,delete,update等 DQL:数据库查询语言,用来查询数据库中表的记录。关键字:select,…

PIX2SEQ: A LANGUAGE MODELING FRAMEWORK FOR OBJECT DETECTION

文章目录ABSTRACT1 INTRODUCTION2 pix2seq框架2.1SEQUENCE CONSTRUCTION FROM OBJECT DESCRIPTIONS2.2 ARCHITECTURE, OBJECTIVE AND INFERENCE2.3 SEQUENCE AUGMENTATION TO INTEGRATE TASK PRIORS3 EXPERIMENTS3.1 EXPERIMENTAL SETUP3.2 MAIN COMPARISONS3.3 ABLATION ON SE…

2022年都在说软件测试饱和了?都在担心面试不上。

今年开始,小编听到最多的问题就是 软件测试行业是不是饱和了? 软件测试行业还有前景吗? 无非是因为投出去的简历回复的越来越少了 据中华英才网统计,目前软件测试人才的缺口在100万人以上,并以每年20%的速度递增&am…

2.5 自定义srv C++

功能介绍 以自定义数据类型为基础,完成一个节点作为服务器,另一个节点接收传送两个数字到服务端,服务端计算后反馈到客户端进行打印输出 1、工作空间 1.1 创建工作空间lee_ws mkdir -p ~/lee_ws/src cd ~/lee_ws/src/ catkin_init_worksp…

Unity 旋转大总结和项目操作

操作演示 旋转 (online-video-cutter.com)旋转方法都放在了按钮上,第一个是初始化按钮,将cube恢复到(0,0,0),但是位置不会变成(0,0,0) 这个是参…

clickhouse中的sql操作

DDL操作 create操作 create table t_order_mt2(id UInt32,sku_id String,total_amount Decimal(16,2),create_time Datetime,INDEX a total_amount TYPE minmax GRANULARITY 5 ) engine MergeTree partition by toYYYYMMDD(create_time) order by (id, sku_id) primary key …

【工具】工具小集

Gif录制工具 LICEcap一款轻量级屏幕录制工具,可以导出GIF动画图片格式,支持导出GIF 动画图片格式,可灵活调整录制窗口大小。 https://www.cockos.com/licecap/ 浏览器插件(工具箱) FeHelper插件支持Chrome、Firefox…

创建个人中心页面(下)

目录 布局规划前端页面 获取头像获取Bot列表 对接获取Bot信息渲染到前端 实现创建一个Bot 前端进行对接插入Bot 实现创建成功关闭和清空 修改时间 实现删除按钮 安装依赖:vue3-ace-editor 布局规划前端页面 使用 bootstrap 的 grids system 进行布局 在 bo…

windows常见的命令操作大全

目录 一、目录文件操作 cd命令 dir命令 md命令 rd命令 move命令 copy命令 del命令 二、文本相关操作 type命令 >命令 findstr命令 |命令 三、网络相关操作 小建议:跟着文章亲手敲一遍是避免忘记的有效方法 一、目录文件操作 cd命令 功能&#xf…

你真的会解决android ANR 问题吗?

前言 ​ 还记得之前写过一篇关于ANR 的介绍,现在看来,那个只是皮毛。现实中遇到应用或系统ANR 的问题,是很难解决的。下面进入正题,来详细了解下如何解决。 一.ANR 关键字 1. event log 中“am_ANR” 关键字,main-l…

27岁Python程序员做独立开发年收入超900万,家中有屋又有田,生活乐无边

他是谁 他叫赖利蔡斯,27岁的Python程序员。现在拥有一家自己的小型软件公司。 他现在的生活 躺赚 每天躺着就可以赚到钱,睡觉时从来不会被闹钟吵醒。 每天干自己的喜欢的事情,读书、编程、讨论公司业务、研究自己感兴趣的事情&#xff0…

Java#4(各类语句和一点小练习)

目录 一.分支语句 1.if语句:和C语言中的没有什么区别 2.switch语句:可以使用C语言的写法,但新增了一种更加简便的写法 二. 循环语句 1.for循环:和C语言没有什么太大区别 2.while循环:和C语言没有什么太大区别 练习:回文数的判断 3.do while(先运行一次再判断):和C语言没…

项目经理如何进行项目汇报才能让项目顺利进行,让领导一看就喜欢?

项目经理如何进行项目工作汇报才能让项目顺利进行,让领导一看就喜欢?领导听工作汇报,就是想知道项目干得怎么样。因此,项目经理事先一定要思考,这次工作汇报应该达到什么目的。 工作汇报要注意这三个问题 简单描述项目…

有关Git(小白一看就懂)入门版

git的使用是在工作中必备的技能,本系列重写自己曾经学习git的过程,按照从创建git仓库开始操作,赋每一步的演示图,让小白跟着文章操作,一步一步入门 目录 git基本概念 git使用基本流程 文件的四种状态 git的使用和基…

Vue3 - this 概念及使用方法(详细教程)

前言 对比 Vue2 ,引出并展开 Vue3 。 本文讲述了 this 概念及应用场景,以及使用方法和代码示例详细讲解。 回忆 Vue2 我们在 Vue2 项目中,可能写得最多的单词就是 this 了,咱们无论是拿数据还是调方法,一律 this。 先…

前端学习路线(一)

很多人问我前端学习的路线是怎么样的,css要学多久,js高级要不要学,先学node.js还是先学vue,所以想通过一篇博文来讲一下这个事情 要不要学前端三剑客 这个问题是很多想快速上手前端的同学问的最多的一个问题,因为有很…

同样做软件测试,为什么有人月入3k-5k,有人能拿到17-20k?

同样做软件测试,为什么有人月入3k-5k,有人能拿到17-20k? 虽然各大培训机构一直鼓吹软件测试行业薪资高,但是依旧有一些拿着3-5k薪资,甚至找不到软件测试工作的人。 先来看一些例子: 1、小A在一家培训机构…

微信小程序开发教程一--注册小程序、下载开发工具及新建工程

从本章开始,我们将讲解微信小程序的简单开发流程,我将尽量使用简洁的语言,逐个步骤详细讲解,让大家都能跟得上,也希望和大家交流学习。 注册 首先,开发小程序需要先在微信注册。 打开网页:https://mp.weixin.qq.com/ 在下面找到小程序: 将鼠标移上去之后,就能看到“…

mysql的监控大屏

前言: 一款方便的mysql的监控大屏,使用开源项目实现MySQL的监控,对于想要进行mysql的时候情况监控来说比较重要,并且这款工具是不需要与代码进行结合的,直接运行打开就行了。 具体方式如下: 第一款&…