python学习笔记-redis缓存数据库
一、缓存数据库介绍
NoSQL (not only sql)
redis是业界主流的Key-value nosql数据库之一,和memcached类似
redis优点:
- 速度快,每秒可执行大约110000设置操作,81000个/每秒的读取操作
- 支持丰富的数据类型,列表,结合,可排序集合,哈希等
- 操作是原子的
二、redis操作
安装redis
ubuntu安装
$ sudo apt-get install redis-server
启动
$ redis-server
连接
$ redis-cli
1、字符串操作
#设置 set (key ,value,ex=None,px=None,nx=false,xx=False) set name "steven" set age 22 keys * #查看所有值 #获取 get age #设置超时时间 set sex "male" ex 3 #超时时间3秒【ex:秒,px:毫秒】 #不存在时才设置值 set name2 "Alex li" NX #存在时才设置值 set name2 "Alex li" XX #其他简写命令 setnx(name,value) #设置值,只有name不存在时才设置 setex(name,value,time) #设置值,和过期时间 psetex(name,time_ms,value) #设置值,和超时时间(毫秒) mset key value [key value ...] #批量设置 mget key [key ...] #批量获取 getset(name,value) #设置新值并获取原来的值 getrange key start end #获取对应value子串 setrange key offset value #修改字符串,从指定位置开始向后添加 setbit key offset value #修改对应二进制位的值 getbit key offset #获取二进制位对应的值 bitcount name #二进制格式 1 的数量 #应用场景:大量用户访问网站时,记录访问的用户数和哪些用户在线,优化存储。 strlen(name) #返回对应值的字节长度 incr(name,amount=1) #自增name对应的值 incrbyfloat #自增(浮点型) decr #自减 append #(key,value) 追加
2、hash操作
hash表现形式上象python中的dict,可以存储一组关联性较强的数据
HSET (name,key,value) #name对应的hash中设置一个键值对(不存在则创建,否则,修改) hget(name,key) #获取 hmset (name ,mapping) #在name对应的hash中批量设置键值对 hmget(name,keys) hgetall(name) #获取name对应hash所有键值 hlen() #键值对个数 hkeys #name对应hash所有key hvals #name对应hash所有value hdel(name,*keys) #删除指定键值 hincrby(name,key,amount=1) #自增 hincrbyfloat #自增,字符浮点数 hscan(name,cursor=0,match=None,count=None) #分片获取 # name,redis的name # cursor,游标(基于游标分批取获取数据) # match,匹配指定key,默认None 表示所有的key # count,每次分片最少获取个数,默认None表示采用Redis的默认分片个数
3、list操作
lpush(name,values) #从左边存,在name对应的list中添加元素, rpush lpushx #name存在时才存储 llen (key) # name对应的list元素的个数 linsert (key before|after pivot element) # 在name对应的列表的某一个值前或后插入一个新值 lset (key index element) # 对name对应的list中的某一个索引位置重新赋值 lrem (key count element) # 在name对应的list中删除指定的值 lpop (key) #从左删除第一个值 lindex (key index) #根据索引获取列表元素 lrange (key start end) #分片获取数据 ltrim (key start stop) #移除没有在start-end索引之间的值 rpoppush # 从一个列表取出最右边的元素,将其添加至另一个列表的最左边 blpop (key [key...] timeout) # 将多个列表排列,按照从左到右去pop对应列表的元素 brpoplpush (source destination timeout) # 从一个列表的右侧移除一个元素并将其添加到另一个列表的左侧
4、set操作
》集合
sadd (key member [member...]) #对应的集合中添加元素 scard (key) #获取集合元素个数 sdiff (key [key ...]) #取差集 smembers (key) #获取集合元素 sdiffstore (dest key [key...]) #将两个集合的差集,存储到另一个集合dest sinter (key [key ...]) #取交集 sinterstore (dest key [key...]) #将两个集合的交集,存储到另一个集合dest sismember #是否是集合的元素 smove(source destination member) #将元素从一个集合移动到另一个结合 spop (key [count]) #从尾部删除一个元素,并返回 srandmember(key [count]) #随机取出元素 srem (key member [member...]) #删除元素 sunion #取并集 sscan (key cousor [MATCH pattern] [COUNT count]) #从指定游标处搜索元素
》有序集合
在集合的基础上,为每元素排序;元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。
zadd (key socre member [score member]) #添加元素 zcard #获取集合元素个数 zrange (key start stop [WITHSCORES]) #显示元素并按分数排序,withscores是否显示分数 zcount #获取有序集合中分数 在 [min,max] 之间的个数 zrangebyscore #取得分在某区间的元素 zrevrange #显示元素,按分数倒序排 zrank (key member) #获取元素的排行(从0开始) zrem #删除元素 zremrangebyrank #按排行范围删除 zscore #取集合某个元素的分数 zinterstore (destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]) #获取两个有序集合的交集,如果遇到相同值不同分数,则按照aggregate进行操作 zunionstore zscan
5、其他常用命令
del #删除key exists #检查是否存在 expire #设置超时时间 keys #获取key,可跟表达式* ? rename (key newkey) #改名 move (key db) #将某个值移动到指定db #(redis里可以看作有多个分区(db),0-15,最大支持16个,select 1是切换到1的db,目标db没有这个key时能移动成功) randomkey() #随机获取一个key type #返回类型 scan
三、管道
redis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指 定多个命令,则可以使用pipline实现一次请求指定多个命令
》通过pyth连接
需先进行配置,未配置会显示拒绝,修改redis配置文件(密码和绑定ip),修改后重启
涉及的修改项
应用后查看服务和端口
py文件
import redis r=redis.Redis(host='192.168.48.128',port=6379,db=0,password='steven') r.set('test','redis') print(r.get('test'))
运行结果
》运用连接池方式
使用ConnectionPool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。
import redis pool=redis.ConnectionPool(host='192.168.48.128',port=6379,db=0,password='steven') r=redis.Redis(connection_pool=pool) pipe=r.pipeline(transaction=True) pipe.set('wuwang','shunquan') pipe.set("dadudu",'zhouyu') pipe.execute()
执行后查看redis
四、redis发布和订阅
示例:模拟收音机订阅频道
用到pubsub和publish方法,功能封装
import redis class RedisHelper: def __init__(self): pool = redis.ConnectionPool(host='192.168.48.128', port=6379, db=0, password='steven') self.__conn = redis.Redis(connection_pool=pool) self.chan_sub = 'fm104.5' self.chan_pub = 'fm104.5' def public(self, msg): self.__conn.publish(self.chan_pub, msg) return True def subscribe(self): pub = self.__conn.pubsub()#打开收音机 pub.subscribe(self.chan_sub)#调整频道 pub.parse_response()#准备监听 return pub
订阅方:
from redis_helper import RedisHelper obj = RedisHelper() redis_sub = obj.subscribe() while True: msg = redis_sub.parse_response()#阻塞 print("recv:",msg)
发布方:
from redis_helper import RedisHelper obj = RedisHelper() obj.public('hello')
执行结果:
*可启动多个订阅方,验证接收
补充:持久化配置,修改配置文件此位置