• Redis



    Redis使用

    安装

    Python操作Redis普通连接

    1 pip install redis
    #简单使用
        from redis import Redis
        #获取redis连接
        conn = Redis(host='127.0.0.1',port=6379)
        #key取值
        ret = conn.get('name')
    
        print(ret)#b'alex'
    

    Python操作Redis连接池

    #redis_pool
    edis_pool.py
    
        import redis
        #连接池对象,最大连接数100
        POOL = redis.ConnectionPool(host='127.0.0.1',port=6379,max_connections=100)
    
    #redis_pool
    edis_pool.py  
    
        import redis
        from redis_pool import POOL
        #执行这句话就是从连接池拿出一个连接
        r = redis.Redis(connection_pool=POOL)
    
        ret = r.get('name')
    
        print(ret)#b'alex'
    

    Redis数据类型

    string(字符串)
    list(列表)
    set(集合)
    zset(有序集合)
    hash(哈希)
    
    String(字符串)操作
    string在内存中按照一个name一个value来存储,看图1
    
    #加*表示重点
    set(name, value, ex=None, px=None, nx=False, xx=False)*
    #设置值,不存在则创建,存在则修改,
    参数:
    	ex过期时间秒
        px过期时间毫秒
        nx为True时,key不存在时,才会执行,key存在则不执行操作
        xx为True时,key不存在时,不会执行操作,key存在才会执行
        
    setnx(name, value)
    #设置值,key不存在,才会执行,存在不会执行操作
    
    setex(name, value, time)
    #设置值,参数time过期时间数字秒,或timedelta对象
    
    psetex(name, time_ms, value)
    #设置值,参数time_ms过期时间数字毫秒,或timedelta对象
    
    mset(*args,**kwargs)*
    #批量设置值,如
    	mset(k1='v1',k2='v2')
        mset({'k1':'v1','k2':'v2'})
    
    get(key)*    
    #获取值
    
    mget(keys,*args)*
    #批量获取,如
    	mget('k1','k2')
        mget(['k1','k2'])
    
    getset(name, value)*
    #设置值并获取原来的值
    
    getrange(key, start, end)
    #获取子序列,根据字节获取,非字符,参数:
    	start开始位置的索引(前闭后闭)#汉字占3个字节
        end结束位置的的索引(前闭后闭)
    
    setrange(name, offset, value)
    #修改字符串内容,从指定索引向后修改,新值比原值长则向后添加,参数:
    	0ffset开始修改字符串的索引,汉字占3个字节
        value指要设置的指
    
    setbit(name, offset, value)
    #对key对应的值的二进制(010101001)进行操作,参数:
    	offset开始位的索引,需要将值转成二进制(1字节等于8位二进制)索引
        value值只能是0或1
        
    getbit(name, offset)
    # 获取key对应值开始索引的二进制的值0或1
    
    bitcount(key, start=None, end=None)
    #获取key对应值的二进制的值中的1的个数,参数:
    	strat二进制起始位置
        end二进制结束位置
       
    bitop(operation, dest, *keys)
    #获取多个值,并将值做位运算,将最后的值保存至新的key对应的值,参数:
    	operation可以是AND(并)、OR(或)、NOT(非)、XOR(异或)
    	dest新的key名
        *keys要查找的key
    	如:
        conn.bitop('AND','name_1','name1','name2','name3')
        #获取key,'name1','name2','name3'对应的值,做位运算(并集),然后将结果保存到name_1对应的值中
    
    strlen(name)
    #返回key对应值的字节长度(汉字三个字节)
    
    incr(self, name, amount=1)#incrby(self, name, amount=1)*
    #自增key对应的值,当key不存在时,则创建key对应值是amount的值,否则则自增,参数:
    	amount自增数,必须是整数
    
    incrbyfloat(self, name, amount=1.0)
    #自增key对应的值,key不存在时,则创建key=amount,否则自增,参数:
    	amount自增数,必须是浮点型
    
    decr(self, name, amount=1)*
    #自减key对应的值,key不存在时,则创建key=amount,否则则自减,参数:
    	amount自减数,必须是整数
        
    append(key, value)*
    #在key对应的值后面追加内容,参数:
    	value要追加的字符串
    

    图1

    Hash(哈希)操作
    #Hash在内存中的存储格式,value值必须是字符串类型,看图1
    
    #加*表示重点
    hset(name, key, value)*
    #name对应的hash中设置一个键值对,不存在创建,存在则修改,参数:
    	name指redis存储hash的name
        key指name对应的hash的key
        value指name对应的hash的value
        
    hmset(name, mapping)*
    #在name对应的hash中批量设置键值对,参数:
    	mapping是字典,比如{'k1':'v1','k2','v2'}
        
    hget(name,key)*
    #在name对应的hash中获取根据key获取value值
    
    hmget(name, keys, *args)*
    #在name对应的hash中获取多个key对应的值。参数:
    	keys要获取key的集合,如['k1','k2','k3']
        *args要获取的key,如k1,k2,k3
        实例:
            hmget('name',['k1','k2','k3'])
             hmget('name',k1,k2,k3)
    
    hgetall(name)
    #获取name对应的hash的所有键值
    
    hlen(name)
    #获取name对应的hash的键值对的个数
    
    hkeys(name)
    #获取name对应的hash的所有的key的值
    
    hvals(name)
    #获取name对应的hash的所有的value的值
    
    hexists(name, key)
    #检查name对应的hash是否存在key
    
    hdel(name,*keys)
    #将name对应的hash指定的key的键值对删除
    
    hincrby(name, key, amount=1)*
    #自增name对应的hash中指定的key的值,不存在则创建key=amount,参数:
    	amount自增数,必须是整数
        
        
    hincrbyfloat(name, key, amount=1.0)
    #自增name对应的hash中指定key的值,不存在则创建key=amount,参数:
    	amount自增数,必须是浮点数
        
        
    hscan(name, cursor=0, match=None, count=None)
    #增量式迭代获取,对于数据大的非常有用,hscan可以实现分片式获取数据,并非一次性将数据全部获取,导致内存被撑爆,参数:
    	cursor游标,基于游标分批获取数据
        match匹配指定key,默认None,表示所有的key
        count每次分片最少获取个数,默认None表示采用redis默认分片个数
        
    hscan_iter(name, match=None, count=None)
    #利用yield封装hscan创建生成器,实现分批去redis中获取数据,参数:
    	match匹配指定key,默认Nnoe,表示所有的key
        count每次分片最少获取个数,默认None表示采用redis的默认分片个数
        实例:for item in r.hscan_iter('xx'):
            	print item    
                
    # 区分hgetall和hscan_iter            
    

    List(列表)操作
    #List在内存中按照一个name对应一个List来存储,看图1
    
    #加*表示重点
    lpush(name,values)*
    #在name对应的list中添加元素,每个新的元素都添加到列表的最左边,如:
    	r.lpush('oo', 11,22,33)
        结果为: 33,22,11
        # 扩展:
            rpush(name, values) 表示从右向左操作
    
    lpushx(name,value)
    #在name对应的list中添加元素,只有name存在时,值添加到list最左边
    	扩展:rpushx(name, value) 表示从右向左操作
        
    llen(name)*
    #name对应的list元素的个数
    
    linsert(name, where, refvalue, value))
    #在name对应的list的某一个值前面或后面插入一个值,参数:
    	where可以式BEFORE或AFTER(小写也可以)
        refvalue标杆值,在它前后插入数据,如果存在多个标杆值,以找到的第一个为准
        value要插入的值
        
    r.lset(name, index, value)
    #对name对应的list的某一个索引位置重新赋值,参数:
    	index指需要重新赋值的索引位置
        value要设置的值
        
    r.lrem(name, value, num)
    #在name对应的list中删除指定的值,参数:
    	value要删除的值
        num:
        	num=0表示删除该list中所有指定值
            num=2表示从前到后删除两个
            num=-2表示从后到前删除两个
            
    lpop(name)*
    #在name对应的list左侧获取第一个元素并在list中移除,返回值则是该元素
    	扩展:rpop(name) 表示从右向左操作
        
    lindex(name, index)
    #在name对应的list中根据索引获取list元素
    
    lrange(name, start, end)*
    #在name对应的list分片获取数据,参数:
    	start开始的索引位置
        end结束的索引位置
        
    ltrim(name, start, end)
    #在name对应的list中移除没有在start-end索引之间的值,参数:
    	start开始的索引位置
        end结束的索引位置
        
    rpoplpush(src, dst)
    #从一个列表取出最右边的元素,提示添加到另一个list的最左边,参数:
    	src要获取数据的list的name
        dst要添加数据的list的name
        
    blpop(keys, timeout)*
    #将多个list排列,按照从左到右去pop对应list的元素,参数:
    	keys是个集合,要pop元素的集合
        timeout超时时间,当元素所有list的元素获取玩之后,阻塞等待list内数据局的时间秒,0表示医院阻塞,
        扩展:r.brpop(keys, timeout),从右向左获取数据,应用场景:爬虫实现简单分布式:多个url放到列表里,往里不停放URL,程序循环取值,但是只能一台机器运行取值,可以把url放到redis中,多台机器从redis中取值,爬取数据,实现简单分布式
    
    brpoplpush(src, dst, timeout=0)    
    #从一个列表的右侧移除一个元素,并将其添加到另一个list的左侧,参数:
    	src取出并要移除元素的list的name
        dst要插入元素的list的name
        timeout当src对应的list中没有数据时,阻塞等待其有数据的超时时间秒,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)
    

    Set(集合)操作
    其他操作
    delete(*names)
    #删除redis中任意数据类型
    
    exists(name)
    #检查redis的name是否存在
    
    keys(pattern='*')
    #根据模型获取redis的name,其他参数:
    	KEYS * 匹配数据库中所有 key 。
        KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
        KEYS h*llo 匹配 hllo 和 heeeeello 等。
        KEYS h[ae]llo 匹配 hello 和 hallo ,不匹配 hillo 
    	
    expire(name ,time)
    #为某个redis的某个name设置超时时间
    
    rename(src, dst)
    #对redis的name重命名
    
    move(name, db)
    #将redis的某个值移动到指定的db下
    
    randomkey()
    #随机获取一个redis的name,不删除
    
    type(name)
    #获取nmae对应值的类型
    
    scan(cursor=0, match=None, count=None)
    scan_iter(match=None, count=None)
    #同字符串操作,用于增量迭代获取key
    

    管道

    如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作。#redis默认在执行每次请求都会创建(连接申请连接池)和断开(归还连接池)一次性操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作(要么全部成功,要么全部失败)。
    
    #test.py
        import redis
    
        pool = redis.ConnectionPool(host='10.211.55.4', port=6379)
    
        r = redis.Redis(connection_pool=pool)
    
        # pipe = r.pipeline(transaction=False)
        pipe = r.pipeline(transaction=True)
        pipe.multi()
        pipe.set('name', 'alex')
        pipe.set('role', 'sb')
    
        pipe.execute()
    

    Django使用Redis

    #方式一,通用方式
        #utils
    edis_pool.py
        
    		import redis
            #POOL连接池,max_connections=100指最大连接数是100
            POOL = redis.ConnectionPool(host='127.0.0.1',port=6379,max_connections=100)
            
    	#app01views.py
        
            import redis
            from utils.redis_pool import POOL
            from django.shortcuts import render, HttpResponse
            def index(request):
                conn = redis.Redis(connection_pool=POOL)
                conn.set('hobby','sleep')
                return HttpResponse('设置成功')
    
            def order(request):
                conn = redis.Redis(connection_pool=POOL)
                ret = conn.get('hobby')
                print(ret)
                return HttpResponse('获取成功')
            
    #方式二,安装django-redis模块
    	pip install django-redis
        
        #settings.py配置
        
            CACHES = {
            "default": {
                "BACKEND": "django_redis.cache.RedisCache",
                "LOCATION": "redis://127.0.0.1:6379",
                "OPTIONS": {
                    "CLIENT_CLASS": "django_redis.client.DefaultClient",
                    "CONNECTION_POOL_KWARGS": {"max_connections": 100}
                    # "PASSWORD": "123",
                }
            }
        }
    	#views.py
        from django_redis import get_redis_connection
        conn = get_redis_connection('default')
        print(conn.hgetall('xxx'))
    

    接口缓存

    #luffyapiappshomeviews.py,BannerView类内    
        def banner_list(self,request,*args,**kwargs):
            banner_list = cache.get('banner_list')
            if not banner_list:
                #缓存没有去数据拿
                response = super().list(request,*args,**kwargs)
                #加到缓存
                cache.set('banner_list',response.data,60*60*24)#banner_list一天过期
            return Response(data=banner_list)	
    
    作者:linqiaobao
    本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    SqlHelper处理类
    你必须知道的ADO.NET(五) 细说数据库连接池
    你必须知道的ADO.NET(三) 连接字符串,你小觑了吗?
    从零开始学习ASP.NET MVC 入门
    ASP.NET MVC3 系列教程 目录
    .NET获取英文月份缩写名(可获取其他国家)
    你必须知道的ADO.NET(二)了解.NET数据提供程序
    良好的C#编程习惯
    你必须知道的ADO.NET(一) 初识ADO.NET
    mvc中使用一个action对多个不同名字段做remote验证
  • 原文地址:https://www.cnblogs.com/linqiaobao/p/13680786.html
Copyright © 2020-2023  润新知