本篇文章介紹Python安裝並使用redis模組的方法。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。
【相關推薦:Redis影片教學】
安裝redis模組
pip3 install redis
redis-py提供兩個類別Redis和StrictRedis用於實現Redis的命令,StrictRedis用於實現大部分官方的命令,並使用官方的語法和命令,Redis是StrictRedis的子類,用於向後兼容舊版本的redis-py
import redis conn = redis.Redis(host='127.0.0.1', port=6379) # 可以使用url方式连接到数据库 # conn = Redis.from_url('redis://@localhost:6379/1') conn.set('name', 'LinWOW') print(conn.get('name'))
redis-py使用connection pool來管理對一個redis server的所有連接,避免每次建立、釋放連接的開銷。默認,每個Redis實例都會維護一個自己的連線池。可以直接建立一個連線池,然後作為參數Redis,這樣就可以實作多個Redis實例共用一個連線池
#連線池:redis_pool.py
from redis import ConnectionPool POOL=ConnectionPool(host='127.0.0.1',port=6379,max_connections=100)
使用連線池:test_redis.py
import redis from redis_pool import POOl conn = redis.Redis(connection_pool=POOl) conn.set('name', 'LinWOW') print(conn.get('name'))
建構url方式連接到資料庫,有以下三種模式:
redis://[:password]@host:port/db # TCP连接 rediss://[:password]@host:port/db # Redis TCP+SSL 连接 unix://[:password]@/path/to/socket.sock?db=db # Redis Unix Socket 连接
作用 | 範例 | 範例結果 | |
---|---|---|---|
ex,過期時間(s);px,過期時間(ms); nx,如果設定為True,則只有name不存在時,當前set操作才執行,值存在,就修改不了,執行沒效果;xx,如果設定為True,則只有name存在時,當前set操作才執行,值存在才能修改,值不存在,不會設定新值 | 效果和setex,setnx一致 | ||
給name賦值為value | redis.set('name', 'Bob') | True | |
傳回資料庫中key為name的string的value | redis.get('name') | b'Bob' | |
給資料庫中key為name的string賦予值value並傳回上次的value | redis.getset('name', 'Mike') | b'Bob' | |
傳回多個key對應的value | redis.mget(['name', 'nickname']) | [b'Mike', b'Miker'] | |
如果key不存在才設定value | redis.setnx('newname', 'James') | 第一次執行True,第二次False | |
設定可以對應的值為string類型的value,並指定此鍵值對應的有效期限 | redis .setex('name', 1, 'James') | True | |
設定指定key的value值的子字串 | redis.set('name', 'Hello') redis.setrange('name', 6, 'World') | 11,修改後的字符字串長度 | |
批次賦值 | redis.mset({'name1': 'Durant', 'name2': ' James'}) | True | |
key皆不存在時才批次賦值 | redis.msetnx ({'name3': 'Smith', 'name4': 'Curry'}) | True | |
redis.incr('age', 1) | 1,即修改後的值 | decr(name, amount=1) | |
redis.decr('age', 1) | -1,即修改後的值 | append(key, value) |
方法 | #作用 | 範例 | 範例結果 |
---|---|---|---|
exists(name) | 判斷一個key是否存在 | redis.exists('name') | True |
delete(name) | 刪除一個key | redis.delete('name') | ##1|
判斷key型別 | redis.type('name') | b'string' | |
取得所有符合規則的key | #redis.keys('n*') | [b' name'] | |
取得隨機的一個key | randomkey() | b'name' | |
將key重新命名 | redis.rename('name', 'nickname') | # True | |
取得目前資料庫中key的數目 | dbsize() | #100 | |
設定key的過期時間,單位秒 | redis.expire('name', 2) | True | |
取得key的過期時間,單位秒,-1為永久不過期 | redis.ttl('name ') | -1 | |
將key移到其他資料庫 | move('name ', 2) | True | |
刪除目前選擇資料庫中的所有key | flushdb() | True | |
刪除所有資料庫中的所有key | flushall() | True |
#範例 | 範例結果 | ||
rpush(name, *values) | 在key為name的list尾添加值為value的元素,可以傳多個 | redis.rpush('list', 1, 2, 3) | |
lpush(name, *values) | 在key為name的list頭加值為value的元素,可以傳多個 | redis.lpush('list', 0) | |
llen(name) | #傳回key為name的list的長度 | redis.llen(' list') | |
lrange(name, start, end) | 返回key為name的list中start至end之間的元素 | redis.lrange('list', 1, 3) | |
ltrim(name, start, end) | 截取key為name的list,保留索引為start到end的內容 | ltrim('list', 1, 3) | |
lindex(name, index) | 回傳key為name的list中index位置的元素 | redis.lindex(' list', 1) | |
lset(name, index, value) | 給key為name的list中index位置的元素賦值,越界則報錯 | redis.lset('list', 1, 5) | |
lrem(name, count, value) | 刪除count個key的list中值為value的元素 | redis.lrem('list', 2, 3) | |
lpop(name) | 傳回並刪除key為name的list中的首元素 | redis.lpop('list') | |
rpop(name) | #傳回並刪除key為name的list中的尾元素 | redis .rpop('list') | |
#blpop(keys, timeout=0) | 回傳並刪除名稱為在keys中的list中的首元素,如果list為空,則會一直阻塞等待 | redis.blpop('list') | |
brpop(keys, timeout=0) | 返回並刪除key為name的list中的尾元素,如果list為空,則會一直阻塞等待 | redis .brpop('list') |
应用场景:
blpop实现简单分布式爬虫:
多个url放到列表里,往里不停放URL,程序循环取值,但是只能一台机器运行取值,可以把url放到redis中,多台机器从redis中取值,爬取数据,实现简单分布式
将多个列表排列,按照从左到右去pop对应列表的元素
参数:
keys,redis的name的集合
timeout,超时时间,当元素所有列表的元素获取完之后,阻塞等待列表内有数据的时间(秒), 0 表示永远阻塞
更多:
r.brpop(keys, timeout),从右向左获取数据
自定义增量迭代:
由于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)
方法 | 作用 | 示例 | 示例结果 |
---|---|---|---|
sadd(name, *values) | 向key为name的set中添加元素 | redis.sadd(‘tags’, ‘Book’, ‘Tea’, ‘Coffee’) | 3,即插入的数据个数 |
srem(name, *values) | 从key为name的set中删除元素 | redis.srem(‘tags’, ‘Book’) | 1,即删除的数据个数 |
spop(name) | 随机返回并删除key为name的set中一个元素 | redis.spop(‘tags’) | b’Tea’ |
smove(src, dst, value) | 从src对应的set中移除元素并添加到dst对应的set中 | redis.smove(‘tags’, ‘tags2’, ‘Coffee’) | True |
scard(name) | 返回key为name的set的元素个数 | redis.scard(‘tags’) | 3 |
sismember(name, value) | 测试member是否是key为name的set的元素 | redis.sismember(‘tags’, ‘Book’) | True |
sinter(keys, *args) | 返回所有给定key的set的交集 | redis.sinter([‘tags’, ‘tags2’]) | {b’Coffee’} |
sinterstore(dest, keys, *args) | 求交集并将交集保存到dest的集合 | redis.sinterstore(‘inttag’, [‘tags’, ‘tags2’]) | 1 |
sunion(keys, *args) | 返回所有给定key的set的并集 | redis.sunion([‘tags’, ‘tags2’]) | {b’Coffee’, b’Book’, b’Pen’} |
sunionstore(dest, keys, *args) | 求并集并将并集保存到dest的集合 | redis.sunionstore(‘inttag’, [‘tags’, ‘tags2’]) | 3 |
sdiff(keys, *args) | 返回所有给定key的set的差集 | redis.sdiff([‘tags’, ‘tags2’]) | {b’Book’, b’Pen’} |
sdiffstore(dest, keys, *args) | 求差集并将差集保存到dest的集合 | redis.sdiffstore(‘inttag’, [‘tags’, ‘tags2’]) | 3 |
smembers(name) | 返回key为name的set的所有元素 | redis.smembers(‘tags’) | {b’Pen’, b’Book’, b’Coffee’} |
srandmember(name) | 随机返回key为name的set的一个元素,但不删除元素 | redis.srandmember(‘tags’) |
方法 | 作用 | 範例 | 範例結果 |
---|---|---|---|
zadd(name, args, *kwargs) | 向key為name的zset中新增元素member,score用於排序。如果該元素存在,則更新其順序 | redis.zadd('grade', 100, 'Bob', 98, 'Mike') | 2,即新增的元素個數 |
zrem(name, *values) | 刪除key為name的zset中的元素 | redis.zrem('grade', 'Mike' ) | 1,即刪除的元素個數 |
zincrby(name, value, amount=1) | 如果在key為name的zset中已經存在元素value,則該元素的score增加amount,否則向該集合中添加該元素,其score的值為amount | redis.zincrby('grade', 'Bob', -2) | 98.0,即修改後的值 |
zrank(name, 值) | 傳回key為name的zset中元素的排名(按score從小到大排序)即下標 | redis.zrank('grade', 'Amy') | 1 |
zrevrank(name, 值) | 傳回key為name的zset中元素的倒數排名(按score由大到小排序)即下標 | redis.zrevrank('grade', 'Amy') | 2 |
zrevrange(name, start, end, withscores=False) | 傳回key為name的zset(按score從大到小排序)中的index從start到end的所有元素 | redis.zrevrange('grade', 0, 3) | [b'Bob', b'Mike', b'Amy', b'James'] |
zrangebyscore(name, min, max, start=None, num=None, withscores=False) | 在傳回key為name的zset中score在給定區間的元素 | redis.zrangebyscore('grade', 80, 95) | [b'Amy', b'James'] |
zcount(name, min, max) | 返回key為name的zset中score在給定區間的數量 | redis.zcount('grade', 80, 95) | 2 |
zcard(name) | 傳回key為name的zset的元素數量 | redis.zcard(' grade') | 3 |
zremrangebyrank(name, min, max) | 刪除key為name的zset中排名在給定區間的元素 | redis.zremrangebyrank('grade', 0, 0) | 1,即刪除的元素數量 |
zremrangebyscore(name, min, max) | 刪除key為name的zset中score在給定區間的元素 | redis.zremrangebyscore('grade', 80, 90) | 1,即刪除的元素個數 |
作用 | 範例 | 範例結果 | |
---|---|---|---|
#hset(name, key, 值) | 向key為在name的hash中加入映射 | hset('price', 'cake', 5) | 1,即新增的映射個數 |
hsetnx(name, key, value) | 向key為name的hash中新增映射,如果映射鍵名稱不存在 | hsetnx('price', 'book', 6) | 1,也就是新增的對應數量 |
hget(name, key) | 傳回key為name的hash中field對應的value | redis.hget('price', 'cake') | 5 |
#hmget(name, keys, *args) | #返回key為name的hash中各個鍵對應的value | redis.hmget('price', ['apple', 'orange']) | [b'3', b'7 '] |
hmset(name, mapping) | 向key為name的hash中批次新增映射 | redis.hmset('price', {'banana': 2, 'pear': 6}) | True |
#hincrby(name, key, amount=1) | #將key為name的hash中映射的value增加amount | redis.hincrby('price', 'apple', 3) | 6,修改後的值 |
#hexists(name, key) | key為namehash中是否存在鍵名為key的映射 | redis.hexists('price', 'banana') | True |
hdel(name, *keys) | key為namehash中刪除鍵名為key的對應 | redis.hdel( 'price', 'banana') | True |
hlen(name) | #從key為name的hash中取得映射個數 | redis.hlen('price') | 6 |
#hkeys(name) | 從key為name的hash中取得所有映射鍵名 | redis.hkeys('price') | [b'cake', b'book', b'banana', b'pear'] |
#hvals(name) | 從key為name的hash中取得所有映射鍵值 | redis.hvals('price') | [b '5', b'6', b'2', b'6'] |
#hgetall(name) | 從key為name的hash中取得所有映射鍵值對 | redis.hgetall('price') | {b'cake': b'5', b'book': b'6', b'orange': b'7', b'pear': b'6'} |
注意点:
hscan(name, cursor=0, match=None, count=None):增量式迭代获取,对于数据大的数据非常有用,hscan可以实现分片的获取数据,并非一次性将数据全部获取完,从而放置内存被撑爆
参数: name,redis的name cursor,游标(基于游标分批取获取数据) match,匹配指定key,默认None 表示所有的key count,每次分片最少获取个数,默认None表示采用Redis的默认分片个数 如: 第一次:cursor1, data1 = r.hscan('xx', cursor=0, match=None, count=None) 第二次:cursor2, data1 = r.hscan('xx', cursor=cursor1, match=None, count=None) ... 直到返回值cursor的值为0时,表示数据已经通过分片获取完毕
hscan_iter(name, match=None, count=None): 利用yield封装hscan创建生成器,实现分批去redis中获取数据
参数: match,匹配指定key,默认None 表示所有的key count,每次分片最少获取个数,默认None表示采用Redis的默认分片个数 如: for item in r.hscan_iter('xx'): print item
redis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作。
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', 'linwow') pipe.set('age', '18') pipe.execute()
方式一:
utils文件夹下,建立redis_pool.py
import redis POOL = redis.ConnectionPool(host='127.0.0.1', port=6379,password='1234',max_connections=1000)
视图函数中使用:
import redis from django.shortcuts import render,HttpResponse from redis_pool import POOL def index(request): conn = redis.Redis(connection_pool=POOL) conn.hset('liwow','age',18) return HttpResponse('设置成功') def order(request): conn = redis.Redis(connection_pool=POOL) conn.hget('kkk','age') return HttpResponse('获取成功')
方式二:
安装django-redis模块
pip3 install django-redis
setting里配置:
# redis配置 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", } } }
视图函数:
from django_redis import get_redis_connection conn = get_redis_connection('default') print(conn.hgetall('xxx'))
更多编程相关知识,请访问:编程教学!!
以上是淺談Python安裝並使用redis模組的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!