redis简介
简介: https://www.cnblogs.com/guotianbao/p/8683037.html
redis是主流的key-value nosql 数据库之一。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
注意:
redis是一个非关系型数据库。
数据库包括非关系型数据库和关系型数据库。
1、关系型数据库:mysql/oracle/sql server/db2/sqlite 数据是存在磁盘上的
2、非关系型数据库:
mongodb/redis 没有表结构,没有sql语句,没什么字段。速度比关系型数据库快,redis数据是存在内存上的,redis本身性能非常,每秒支持30万次读写。缺点是没有办法持久化(重启redis可以备份数据到磁盘里面,启动的时候再次读取磁盘的数据到内存,这种方法可以实现持久化)
数据库比较参考: https://blog.youkuaiyun.com/u014803081/article/details/88808903
redis做缓存
对比memcache参考: https://www.cnblogs.com/wudalang/p/5697470.html
当一个应用的数据量或者用户量上来后,如果每一次的查询都去访问数据库,或造成数据库效率变慢甚至崩溃。
而且在大多数应用中都是读多写少的,就可以将这些经常读的数据放到另外一个地方去(也就是缓存),让系统先从这个地方(缓存)获取,获取不到在查询数据库。这样可以大大的减少数据库的压力。经常与redis做比较的memcache,这里暂不比较它们的区别。
redis特点
- Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
- Redis支持数据的备份,即master-slave模式的数据备份。
Redis 优势
- 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
- 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
- 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
redis安装
**下载地址:**https://github.com/MSOpenTech/redis/releases。
1,下载 Redis-x64-xxx.zip 并解压到redis的文件夹
2,切换目录到 C:\redis 运行 redis-server.exe redis.windows.conf
3, 另启一个cmd窗口,原来的不要关闭,切换到redis目录下运行 redis-cli.exe -h 127.0.0.1 -p 6379 。
4 ,设置键值对 set Key vale 取出键值对 get key
redis保持后台运行
-
进入 DOS窗口
-
在进入Redis的安装目录
-
输入:redis-server --service-install redis.windows.conf --loglevel verbose ( 安装redis服务 )
-
输入:redis-server --service-start ( 启动服务 )
-
输入:redis-server --service-stop (停止服务)
python操作redis
redis连接
普通连接
import redis
r = redis.Redis(host='127.0.0.1', port=6379, decode_responses='utf-8')
声明redis连接池的decode_responses
字段来对键值对进行默认编码
连接池连接
连接池连接参考 https://blog.youkuaiyun.com/yanerhao/article/details/82111468
redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。默认每个Redis实例都会维护一个自己的连接池。所以可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池
import redis # 导入redis模块
pool = redis.ConnectionPool(host='localhost', port=6379,decode_responses=True)
r = redis.Redis(connection_pool=pool)
r.set('key', 'value') # key是"key" value是"value" 将键值对存入redis缓存
print(r.get('key')) # 取出对应的值
管道
参考redis事务 https://www.cnblogs.com/kangoroo/p/7535405.html
redis-py默认在执行每次请求都会创建(连接池申请链接)和断开(归还连接池)一次链接操作。如果想要在一次请求中指定多个命令,则可以使用pipeline实现一次请求指定多个命令
Redis是建立在TCP协议基础上的架构,客户端client对redis server采取请求响应的方式交互。一般来说客户端从提交请求到得到服务器相应,需要传送两个tcp报文。比如要批量的执行一系列redis命令,执行100次get key,这时向redis请求100次+获取响应100次。如果能一次性将100个请求提交给redis server,执行完成之后批量的获取相应,只需要向redis请求1次,然后批量执行完命令,一次性结果,性能会好很多, 节约的时间是客户端client和服务器redis server之间往返网络延迟的时间。
网络延迟高:批量执行,性能提升明显
网络延迟低(本机):批量执行,性能提升不明显
import redis, time
pool = redis.ConnectionPool(host=‘localhost’, port=6379)
r = redis.Redis(connection_pool=pool)
pipe = r.pipeline(transaction=False)
pipe = r.pipeline(transaction=True)
#这样的效果是k1和k2是一起最后执行的
pipe = r.pipiline()
pipe.set(‘k1’, ‘alex’)
time.sleep(2)
pipe.set(‘k2’, ‘sb’)
pipe.execute()
字符串相关操作
-
set(name,value,ex=None,px=None,nx=False,xx=False):设置键值
- name:键
- value:值
- ex:过期时间(秒)
- px:过期时间(毫秒)
- nx:True时,name不存在才会执行set操作
- xx:True时,name存在才会执行set操作
-
get(name):获取键值
- name:键
-
setnx(name,value):设置键值(name不存在则设置,否则不做操作)
- name:键
- value:值
-
setex(name,time,value):设置键值(name存在会覆盖)
- name:键
- value:值
- time:过期时间(秒)
-
psetex(name,time_ms,value):设置键值(name存在会覆盖)
- name:键
- time_ms:过期时间(毫秒)s
- value:值
-
mset(args,kwargs):批量设置键值
-
mget(keys,args):批量获取键值
- keys:键列表
- args:键元组
-
getset(name,value):获取旧值并设置新值
- name:键
- value:新值
-
setrange(name,offset,value):修改键值
- name:键
- offset:起始位置(从此位置开始修改),若name不存在,且offset>0,则在前面补上offset个0x00,再加上value,为name的新值
- value:值
-
getrange(name,start,end):获取值并截取
- name:键
- start:起始位置(字节),包含起始位置
- end:结束位置(字节),包含结束位置
-
setbit(name,offset,value):对name对应的值的二进制位进行操作
setbit函数的功能是对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。
-
getbit(name,offset):对name对应的值的二进制位进行操作
-
strlen(name):获取name对应值的长度
- name:键
-
incr(name,amount):name不存在,则name=amount,name存在,则name对应的值+amount
- name:键
- amount:自增值
-
decr(name,amount):name不存在,则name=amount,name存在,则name对应的值-amount
- name:键
- amount:自减值
-
append(key,value):在key对应的值后面追加value
- name:键
- value:追加的值
-
hset(name,key,value):存储字典
- name:键
- key:字典的key
- value:字典的值
-
hget(name,key):获取name对应的字典中对应key的值
- name:键
- key:字典的key
-
hmset(name,mapping):存储字典
- name:键 不能是数字 包括‘1’
- mapping:字典,如:{“info”:”shenzhen”,”age”:18}
-
hmget(name,keys,args)**:获取字典的值
- name:键 不能是数字 包括‘1’
- keys:字典键,如:hmget(“name”,[“info”,”age”])
- args:字典键,如:hmget(“name”,”info”,”age”)
-
hgetall(name):获取字典(dict格式)
- name:键
-
hlen(name):获取字典的长度
- name:键
-
hkeys(name):获取字典的所有key
- name:键
-
hvals(name):获取字典的所有value
- name:键
-
hexists(name,key):name对应的字典中是否存在键key
- name:键
- key:字典的key
-
hdel(name,args):删除name对应的字典中的键值对
- name:键
- args:字典的key元组
-
hincrby(name,key,amount):name对应的字典中,若key存在,则key对应的值+amount,否则key=amount
- name:键
- key:字典中key
- amount:自增值(整数)
-
hincrbyfloat(name,key,amount):name对应的字典中,若key存在,则key对应的值+amount,否则key=amount
- name:键
- key:字典中key
- amount:自增值(浮点数)
-
hscan(name,cursor=0,match=None,count=None):迭代式获取,对于数据大的数据非常有用,hscan可以实现分片式获取,避免一次性获取完毕,将内存撑爆
- name:键
- cursor:游标
- match:匹配的key,默认None,表示所有的key
- count:每次分片最少获取个数,默认None表示采用Redis默认分片个数
# 第一次
cursor1,data = r.hscan("province",cursor=0)
# 第二次
cursor2,data = r.hscan("province",cursor=cursor1)
...
依次迭代,当返回的游标值为0时表示全部获取完毕,值得注意的是只有当"province"对应的字典中含有大量数据时,redis才会有采取分片操作(大概在513条数据左右)
- hscan_iter(name,match,count):利用yield封装hscan创建生成器,实现分批去redis中获取数据
- name:键
- match:匹配的key,默认None,表示所有的key
- count:每次分片最少获取个数,默认None表示采用Redis默认分片个数
列表相关操作
- *lpush(name,value)**:存储列表(往前(左)插入)
- name:键
- value:值,格式:11,22,33。值越后,在列表中存储的位置越前
- *rpush(name,value)**:存储列表(往后(右)插入)
- name:键
- value:值,格式:11,22,33。值越后,在列表中存储的位置越后
- lpushx(name,value):在name对应的list中添加元素,name不存在不操作
- name:键
- value:值。值添加到列表的最前面
- llen(name):获取name对应的list的长度
- name:键
- linsert(name,where,refvalue,value):在name对应的list中refvalue的前后插入value
- name:键
- where:before或after
- refvalue:list中的某个值,与where配合确定位置后插入value
- value:插入的值
- lset(name,index,value):修改name对应的list中指定位置的值
- name:键
- index:索引位置
- value:值
- lrem(name, count, value):删除name对应的list中的指定值
- name:键
- count:0:删除所有配到的指定值;count为正数时:从匹配到该值的位置时,删除count个;count为负数时:从后往前匹配,从匹配到该值的位置时,删除count个
- value:删除的指定值
- lpop(name):删除name对应的list中的第一个值
- name:键
- lindex(name,index):获取name对应的list中指定位置的值
- index:索引位置
- lrange(name,start,end):获取name对应的list中切片后的值
- name:键
- start:起始位置(包括)
- end:结束位置(包括)
- ltrim(name,start,end):移除name对应的list中,不在start-end之间的值
- name:键
- start:起始位置(包括)
- end:结束位置(包括)
- rpoplpush(src,dst):移除src对应的list中最右边(即最后)的元素,并将其加到dst中对应list的最左边(即最前)
- src:键
- dst:键
- brpoplpush(src,dst,timeout=0):移除src对应的list中最右边(即最后的元素),并将其加到dst中对应list的最左边(即最前)
- src:键
- dst:键
- timeout:当src没有值,阻塞!阻塞时间
集合相关操作
- sadd(name,value):添加集合
- name:键
- value:值
- scard(name):获取集合元素的个数
- name:键
- *sdiff(keys,args)**:获取多个集合的差集
- kyes:键
- args:键
- *sdiffstore(dest,keys,args)**:获取keys对应集合,与args中多个集合的差集,并将其设置为dest对应的集合
- dest:键
- keys:键
- args:键,若args为空,dest对应的集合则为keys对应的集合
- *sinter(keys,args)**:获取多个集合的交集
- keys:键
- args:键
- sinterstore(dest,keys,args):获取keys对应集合,与args中多个集合的交集,并将其设置为dest对应的集合
- dest:键
- keys:键
- args:键,若args为空,dest对应的集合则为keys对应的集合
- sismember(name,value):判断value是否name对应集合中的成员
- name:键
- value:值
- smembers(name):获取name对应的集合
- name:键
- smove(src,dst,value):将src中对应集合中的value移动到dst对应的集合的最左边(即最前面)
- src:键
- dst:键
- value:值
- spop(name):移除name对应集合中最右边(即最后面)的元素
- name:键
- srandmember(name,number=None):获取name对应集合中随机元素
- name:键
- number:获取number个元素,默认取一个元素
- *srem(name,values)**:删除name对应集合中的某些元素
- name:键
- values:值
- *sunion(keys,args)**:获取多个集合的并集
- keys:键
- args:键
有序集合相关操作
- *zadd(name,args,kwargs):在name对应的有序集合中添加元素,分数越小,越靠前
- name:键
- args:键值对,例如:’n1’,1,’n2’,2
- kwargs:键值对,例如:’n1’=1,’n2’=2
- zcard(name):获取name对应的有序集合的元素个数
- name:键
- zcount(name,min,max):获取name对应的有序集合中,min<=分数<=max中的元素个数
- name:键
- min:小值(分数)
- max:大值(分数)
- zincrby(name,value,amount):自增name对应的有序集合中,value对应的分数+amount,若value不存在,则插入value=amount
- name:键
- value:值
- amount:分数自增值
- zrange(name,start,end,desc=False,withscores=False,score_with_func=float):获取name对应的有序集合中,start<=下标<=end的所有数据。
- name:键
- start:起始位置
- end:结束位置
- desc:是否是倒序,默认False
- withscores:是否获取分数,默认False
- score_with_func:分数类型
- zrank(name,value):获取value在name对应的有序集合中的下标
- name:键
- value:值
- *zrem(name,values)**:删除在name对应的有序集合中value对应的分数
- name:键
- values:值,如:values=”n1”,”n2”
- zremrangebyrank(name,min,max):删除在name对应的有序集合中,min<=下标<=max的数据
- name:键
- min:小(下标)
- max:大(下标)
- zremrangebyscore(name,min,max):删除在name对应的有序集合中,min<=分数<=max的数据
- name:键
- min:小(分数)
- max:大(分数)
- zscore(name,value):获取name对应的有序集合中value对应的分数
- name:键
- value:值
- zinterstore(name,keys,aggregate=None):获取name对应的有序集合的交集,并使name指向这个交集
- name:键
- keys:多个有序集合的键的元组,例:keys=(“zlist1”,”zlist2”)
- aggregate:聚合操作,值可以是:”MAX”,”MIN”,”SUM”,当遇到值相同,分数不同时,可以对分数做操作:取大值、取小值或取和值
- zunionstore(name,keys,aggregate=None):获取name对应的有序集合的并集,并使name指向这个并集
- name:键
- keys:多个有序集合的键的元组,例:keys=(“zlist1”,”zlist2”)
- aggregate:聚合操作,值可以是:”MAX”,”MIN”,”SUM”,当遇到值相同,分数不同时,可以对分数做操作:取大值、取小值或取和值
其他常用操作
- *delete(names)**:删除Redis中的任意数据类型
- names:键
- exists(name):判断键是否存在
- name:键
- *keys(pattern=””)**:获取符合规则的所有键
- pattern:通配符,默认获取所有。常见:”h”:h结尾的键;”h”:h开头的键;”hx”:h开头,x结尾的键;”h[ae]x”:获取名为hax或hex的键
- expaire(name,time):设置超时时间
- name:键
- rename(src,dst):修改键名
- src:旧键名
- dst:新键名
- move(name,db):将键移动至其他db
- name:键
- db:db序号
- randomkey():随机获取key
- type(name):获取键对应的数据类型
- name:键
redies其他操作 https://blog.youkuaiyun.com/weixin_40207795/article/details/79848975