缓存数据库Redis(基于python api)
缓存数据库介绍
NoSQL
缓存数据库也叫NoSQL(NoSQL = Not Only SQL ),意即“不仅仅是SQL”,泛指非关系型的数据库。
之所以叫缓存数据库是因为数据是储存在缓存里和非硬盘上的,所以访问速度非常快。故缓存数据库的作用就是为了提高访问速度!
关系型数据库和非关系型数据库的区别
- 关系型数据库:强调的是表与表之间有各种关系。是储存在硬盘上的。它一般存储的是一些有关系有严格规则的数据(存储数据类型是事先严格规定好的)
- 非关系型数据库:是存储在缓存里的。可以存储不一致不规则的数据。像是社交网络数据(如微博微信等数据都是用户自己生成的数据),我们没法确定用户会生成什么数据,可能是发表了一篇文章,一首歌,一段视频。那么这些不确定类型的数据使用关系型数据库来存储就显得力不从心。NOSQL数据库为了解决这类多重数据类型的大规模数据带来的存储问题。
NoSQL数据库的四大分类:
键值(Key-Value)存储数据库
像是python中的字典的存储方式,只要创建一个Key后面对应一个value,取值的时候通过key取。
这一类数据库主要会使用到一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来说的优势在于简单、易部署。但是如果DBA只对部分值进行查询或更新的时候,Key/value就显得效率低下了。[3] 举例如:Redis,Tokyo Cabinet/Tyrant, Voldemort, Oracle BDB.
列存储数据库
这部分数据库通常是用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列。这些列是由列家族来安排的,查询海量数据的速度是相当的快。如:Cassandra, HBase, Riak.
文档型数据库
文档型数据库的灵感是来自于Lotus Notes办公软件的,而且它同第一种键值存储相类似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可以看作是键值数据库的升级版,允许之间嵌套键值。而且文档型数据库比键值数据库的查询效率更高。如:CouchDB, MongoDb. 国内也有文档型数据库SequoiaDB,已经开源。
图形(Graph)数据库
图形结构的数据库同其他行列以及刚性结构的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。NoSQL数据库没有标准的查询语言(SQL),因此进行数据库查询需要制定数据模型。许多NoSQL数据库都有REST式的数据接口或者查询API。[2] 如:Neo4J, InfoGrid, Infinite Graph.
总结NoSQL数据库在以下的这几种情况下比较适用:
1、数据模型比较简单;
2、需要灵活性更强的IT系统;
3、对数据库性能要求较高;
4、不需要高度的数据一致性;
5、对于给定key,比较容易映射复杂值的环境。
是因为我们的服务器可能并不单单只有Django提供服务,还有可能是java的web框架一块提供服务,这两个进程无法访问彼此的内存空间,就没法取到彼此想要的数据。把数据存到redis里面,大家就都可以从里面拿数据实现了数据的共享。
优点
-
异常快速 : Redis是非常快的,每秒可以执行大约110000设置操作(mysql可能每秒1000条数据都插入不进去,你说是有多么快),81000个/每秒的读取操作。
-
支持丰富的数据类型 : Redis支持最大多数开发人员已经知道如列表,集合,可排序集合,哈希等数据类型。
这使得在应用中很容易解决的各种问题,因为我们知道哪些问题处理使用哪种数据类型更好解决。
-
操作都是原子的 : 所有 Redis 的操作都是原子(保证数据安全),从而确保当两个客户同时访问 Redis 服务器得到的是更新后的值(最新值)。
-
MultiUtility工具:Redis是一个多功能实用工具,可以在很多如:缓存,消息传递队列中使用(自己可以当消息队列:Redis原生支持发布/订阅),在应用程序中,如:Web应用程序会话,网站页面点击数等任何短暂的数据;
安装
安装Redis环境
要在 Ubuntu 上安装 Redis,打开终端,然后输入以下命令:
$sudo apt-get update #更新下载软件包库
$sudo apt-get install redis-server
这将在您的计算机上安装Redis
启动 Redis
$redis-server
打开新的终端连接redis来查看 redis 是否还在运行
$redis-cli #连接redis
这将打开一个 Redis 提示符,如下图所示:
redis 127.0.0.1:6379>
在上面的提示信息中:127.0.0.1 是本机的IP地址,6379是 Redis 服务器运行的端口。现在输入 PING 命令,如下图所示:
redis 127.0.0.1:6379> ping
PONG
这说明现在你已经成功地在计算机上安装了 Redis。
在Ubuntu上安装Redis桌面管理器
要在Ubuntu 上安装 Redis桌面管理,可以从 http://redisdesktop.com/download 下载包并安装它。
Redis 桌面管理器会给你用户界面来管理 Redis 键和数据。
python环境操作Redis:
下载redis-py模块:pip install redis
接下来学习怎么用python去操作Redis,实际上就是去学习redis-py模块提供给我们的API的使用
Redis的使用
整个Redis是一个key-value的结构,所以我们存数据的时候要设定Key,取值的时候要使用Key
redis-py 的API的使用可以分类为:
- 连接方式
- 连接池
- 操作
- String 操作
- Hash 操作
- List 操作
- Set 操作
- Sort Set 操作
- 管道
- 发布订阅
连接方式
PS:要远程连接redis,需要给redis设置密码验证并且给bind改成0.0.0.0:
打开redis的配置文件
vim /etc/redis.conf
找到
#requirepass foobared
bind 127.0.0.1 #默认是中这个表示只接收本机的链接
去掉行前的注释,并修改密码为所需的密码
requirepass woshimima
改成0.0.0.0表示允许所有地址访问,保存
bind 0.0.0.0
重启redis
sudo service redis restart
或
/etc/init.d/redis-server restart #重启的服务放在了inid.d中
设置了redis验证密码后,连接使用就需要密码了,在原生redis中使用命令auth去验证密码,如:
redis-cli 连接redis
auth woshimima 验证密码
1、操作模式:
redis-py提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令,Redis是StrictRedis的子类,用于向后兼容旧版本的redis-py。
import redis
r = redis.Redis(host='10.211.55.4', port=6379,db=0,password='woshimima')
r.set('foo', 'Bar') #设值
print r.get('foo') #获取值
2、连接池:
redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池。
import redis
pool = redis.ConnectionPool(host='10.211.55.4', port=6379)
r = redis.Redis(connection_pool=pool)
PS:redis-py每执行一条命令如:r.set。都会向redis连接一次,使用连接池虽然可以在一定程度上节省资源开销,但是也不是最高效的办法。redis提供了管道功能来让我们在一次连接中执行多条命令!管道的使用我们下面了解完redis的数据类型常用命令后再做介绍!
操作
string操作
redis中的String在在内存中按照一个name对应一个value来存储。如图:
原生redis的String操作命令:
-
set key vlaue [EX] [PX] [NX XX]
在Redis中设置值,默认是不存在则创建,存在则修改
EX设置超时时间:set name value ex 3 :给键值对设置3秒超时时间,超时后删除key-value
PX也是设置超时时间,但是单位是毫秒
NX:set key value NX:键值对不存在则创建,存在则不执行set(不设置NX和XX的情况下默认是修改)
XX:set key value XX:与NX相反,存在的时候修改,不存在的时候不执行set -
setnx key seconds value
在Redis设置值,就等于`set name value NX -
setex key seconds value
和psetex key time_ms value
在Redis设置值附带过期时间,前者是s后者是ms后失效。就等于set name value ex 3
和set name value px 3
-
mset key1 value1 key2 value2 key3 value3
批量设置 -
keys *
查看所有在redis已经存在的key -
get key
根据key取值 -
mget key1 key2 key3
批量获取 -
getset key value
在redis设置新值并获取它,即先set再get二合一美滋滋 -
getrange key start end
获取切片值(根据字节获取,非字符),就是切片操作但是切的是字节!允许反向取(负数切)
如"大黄"中文字符在Utf8占3个字节,故getrange name 0 3取到"大" -
setrange key offset value
修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后覆盖)
参数:
offset,字符串的索引,字节(一个汉字三个字节)
value,要设置的值 -
setbit key offet value
对key对应值的二进制表示(0或1)的位进行操作,如果新值太长,则往后覆盖
参数:
offet不是字符索引而是位索引,而是把字符串变成字节后的第几位!
value:只能是二进制(0或1) -
getbit key offet
获取key对应的值的二进制表示中的offet位的值 (0或1) -
bitcount key [start] [end]
获取name对应的值的二进制表示中 1 的个数
参数:
key,Redis的name
start,位起始位置
end,位结束位置
位操作可以最大程度的节省内存空间,最常用的例子就是统计在线的用户人数
-
strlen key
返回key 对应值的字节长度(一个汉字三个长度) -
incr key
自增 key对应的值(只能自增1) -
incrbyfloat key amount
自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。
参数:
name,Redis的name
amount,自增数(浮点型) -
decr name
自减 key对应的值(只能减1,并且不能值是浮点数) -
apend key value
在key对应的值后面追加字符串
redis-py中String的API:
-
set(name, value, ex=None, px=None, nx=False, xx=False)
在Redis中设置值,默认,不存在则创建,存在则修改
参数:
ex,过期时间(秒)
px,过期时间(毫秒)
nx,如果设置为True,则只有name不存在时,当前set操作才执行
xx,如果设置为True,则只有name存在时,当前set操作才执行 -
setnx(name, value)
设置值,只有name不存在时,执行设置操作(添加) -
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(name)
获取值 -
mget(keys, *args)
批量获取
如:
mget('name', 'age')
或
r.mget(['name', 'age']) -
getset(name, value)
设置新值并获取原来的值 -
getrange(key, start, end)
获取子序列(根据字节获取,非字符)
参数:
name,Redis 的 name
start,起始位置(字节)
end,结束位置(字节)
如: "大黄" ,0-3表示 "大" -
setrange(name, offset, value)
修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加)
参数:
offset,字符串的索引,字节(一个汉字三个字节)
value,要设置的值 -
setbit(name, 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" # 扩展,转换二进制表示: # source = "大帅黄" source = "foo" for i in source: num = ord(i) print bin(num).replace('b','') 特别的,如果source是汉字 "大帅黄"怎么办? 答:对于utf-8,每一个汉字占 3 个字节,那么 "大帅黄" 则有 9个字节 对于汉字,for循环时候会按照“字节”迭代,那么在迭代时,将每一个字节转换十进制数,然后再将十进制数转换成二进制 11100101 10100100 10100111 11100101 10111000 10000101 11101001 10111011 10000100 -------------------------- -------------------------- ----------------------------- 大 帅 黄
*用途举例,用最省空间的方式,存储在线用户数及分别是哪些用户在线
-
getbit(name, offset)
获取name对应的值的二进制表示中的某位的值 (0或1) -
bitcount(key, start=None, end=None)
获取name对应的值的二进制表示中 1 的个数
参数:
key,Redis的name
start,位起始位置
end,位结束位置 -
strlen(name)
返回name对应值的字节长度(一个汉字3个字节) -
incr(self, name, amount=1)
自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。
参数:
name,Redis的name
amount,自增数(必须是整数)
ps:同incrby -
incrbyfloat(self, name, amount=1.0)
自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。
参数:
name,Redis的name
amount,自增数(浮点型) -
decr(self, name, amount=1)
自减 name对应的值,当name不存在时,则创建name=amount,否则,则自减。
参数:
name,Redis的name
amount,自减数(整数) -
append(key, value)
在redis name对应的值后面追加内容
参数:
key, redis的name
value, 要追加的字符串
Hash操作
hash表现形式上有些像pyhton中的dict,可以存储一组关联性较强的数据!。就是key对应的值是一个小字典 , redis中Hash在内存中的存储格式如下图:
原生redis的Hash操作命令:
通过string可以看出redis-py的操作都是参考原生进行的,所以看下面的API就可以大概知道原生redis怎么写
redis-py中Hash的API:
hset(name, key, value)
name对应的hash中设置一个键值对(不存在,则创建;否则,修改)
参数:
name,redis的name
key,name对应的hash中的key
value,name对应的hash中的value
注:
hsetnx(name, key, value),当name对应的hash中不存在当前key时则创建(相当于添加)hmset(name, mapping)
在name对应的hash中批量设置键值对
参数:
name,redis的name
mapping,字典,如:{'k1':'v1', 'k2': 'v2'}
如:
r.hmset('xx', {'k1':'v1', 'k2': 'v2'})hget(name,key)
在name对应的hash中获取根据key获取valuehmget(name, keys, *args)
在name对应的hash中获取多个key的值
参数:
name,reids对应的name
keys,要获取key集合,如:['k1', 'k2', 'k3']
*args,要获取的key,如:k1,k2,k3
如:
r.mget('xx', ['k1', 'k2'])
或
print r.hmget('xx', 'k1', 'k2')hgetall(name)
获取name对应hash的所有键值hlen(name)
获取name对应的hash中键值对的个数hkeys(name)
获取name对应的hash中键值对的个数hvals(name)
获取name对应的hash中所有的value的值hexists(name, key)
检查name对应的hash是否存在当前传入的keyhdel(name,*keys)
将name对应的hash中指定key的键值对删除hincrby(name, key, amount=1)
自增name对应的hash中的指定key的值,不存在则创建key=amount
参数:
name,redis中的name
key, hash对应的key
amount,自增数(整数)hincrbyfloat(name, key, amount=1.0)
自增name对应的hash中的指定key的值,不存在则创建key=amount
参数:
name,redis中的name
key, hash对应的key
amount,自增数(浮点数)
自增name对应的hash中的指定key的值,不存在则创建key=amounthscan(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
List操作
List操作,redis中的List在在内存中按照一个name对应一个List来存储,跟python里面的List一样一样的。如图:
原生redis的List操作命令:
通过string可以看出redis-py的操作都是参考原生进行的,所以看下面的API就可以大概知道原生redis怎么写
redis-py中List的API:
lpush(name,values)
在name对应的list中添加元素,每个新的元素都添加到列表的最左边
如:
r.lpush('oo', 11,22,33)
保存顺序为: 33,22,11
扩展:
rpush(name, values) 表示从右向左操作lpushx(name,value)
在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边
更多:
rpushx(name, value) 表示从右向左操作llen(name)
name对应的list元素的个数linsert(name, where, refvalue, value))
在name对应的列表的某一个值前或后插入一个新值
参数:
name,redis的name
where,BEFORE或AFTER
refvalue,标杆值,即:在它前后插入数据
value,要插入的数据r.lset(name, index, value)
对name对应的list中的某一个索引位置重新赋值
参数:
name,redis的name
index,list的索引位置
value,要设置的值r.lrem(name, value, num)
在name对应的list中删除指定的值
参数:
name,redis的name
value,要删除的值
num, num=0,删除列表中所有的指定值;
num=2,从前到后,删除2个;
num=-2,从后向前,删除2个lpop(name)
在name对应的列表的左侧获取第一个元素并在列表中移除,返回值则是第一个元素
更多:
rpop(name) 表示从右向左操作lindex(name, index)
在name对应的列表中根据索引获取列表元素lrange(name, start, end)
在name对应的列表分片获取数据
参数:
name,redis的name
start,索引的起始位置
end,索引结束位置ltrim(name, start, end)
在name对应的列表中移除没有在start-end索引之间的值,去头尾
参数:
name,redis的name
start,索引的起始位置
end,索引结束位置rpoplpush(src, dst)
从一个列表取出最右边的元素,同时将其添加至另一个列表的最左边
参数:
src,要取数据的列表的name
dst,要添加数据的列表的nameblpop(keys, timeout)
将多个列表排列,按照从左到右去pop对应列表的元素
参数:
keys,redis的name的集合
timeout,超时时间,当元素所有列表的元素获取完之后,阻塞等待列表内有数据的时间(秒), 0 表示永远阻塞
更多:
r.brpop(keys, timeout),从右向左获取数据brpoplpush(src, dst, timeout=0)
从一个列表的右侧移除一个元素并将其添加到另一个列表的左侧
参数:
src,取出并要移除元素的列表对应的name
dst,要插入元素的列表对应的name
timeout,当src对应的列表中没有数据时,阻塞等待其有数据的超时时间(秒),0 表示永远阻塞
set集合操作
Set操作,跟python中的集合又是一样一样的,Set集合就是不允许重复的列表 ,一般集合是无序的(没有索引),但是redis中也给我们提供了有序的集合!
原生redis的Set操作命令:
通过string可以看出redis-py的操作都是参考原生进行的,所以看下面的API就可以大概知道原生redis怎么写
redis-py中Set的API:
sadd(name,values)
name对应的集合中添加元素scard(name)
获取name对应的集合中元素个数sdiff(keys, *args)
求差集(集合1有集合2没有的集合元素),在第一个name对应的集合中且不在其他name对应的集合的元素集合sdiffstore(dest, keys, *args
获取第一个name对应的集合中且不在其他name对应的集合,再将其新加入到dest对应的集合中sinter(keys, *args)
获取多个name对应集合的交集sinterstore(dest, keys, *args)
获取多个name对应集合的交集,再将其加入到dest对应的集合中sismember(name, value)
检查value是否是name对应的集合的成员smembers(name)
获取name对应的集合的所有成员smove(src, dst, value)
某个成员从一个集合中移动到另外一个集合spop(name)
从集合的右侧(尾部)移除一个成员,并将其返回srandmember(name, numbers)
从name对应的集合中随机获取 numbers 个元素 ,抽奖程序可以用到srem(name, values)
在name对应的集合中删除某些值sunion(keys, *args)
获取多个name对应的集合的并集sunionstore(dest,keys, *args)
获取多个name对应的集合的并集,并将结果保存到dest对应的集合中sscan(name, cursor=0, match=None, count=None) sscan_iter(name, match=None, count=None)
同字符串的操作,用于增量迭代分批获取元素,避免内存消耗太大
有序集合,在集合的基础上,为每元素排序;元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。
zadd(name, *args, **kwargs)
在name对应的有序集合中添加元素,使用方法:zadd(name,'value1',分数,value2,分数)
如:
zadd('zz', 'n1', 1, 'n2', 2)
或
zadd('zz', n1=11, n2=22)zcard(name)
获取name对应的有序集合元素的数量zcount(name, min, max)
获取name对应的有序集合中分数 在 [min,max] 之间的个数zincrby(name, value, amount)
自增name对应的有序集合的 name 对应的分数r.zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)
按照索引范围获取name对应的有序集合的元素
参数:
name,redis的name
start,有序集合索引起始位置(非分数)
end,有序集合索引结束位置(非分数)
desc,排序规则,默认按照分数从小到大排序
withscores,是否获取元素的分数,默认只获取元素的值
score_cast_func,对分数进行数据转换的函数
更多:
从大到小排序
zrevrange(name, start, end, withscores=False, score_cast_func=float)
按照分数范围获取name对应的有序集合的元素
zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func=float)
从大到小排序
zrevrangebyscore(name, max, min, start=None, num=None, withscores=False, score_cast_func=float)zrank(name, value)
获取某个值在 name对应的有序集合中的排行(从 0 开始)
更多:
zrevrank(name, value),从大到小排序zrem(name, values)
删除name对应的有序集合中值是values的成员
如:zrem('zz', ['s1', 's2'])zremrangebyrank(name, min, max)
根据排行范围删除zremrangebyscore(name, min, max)
根据分数范围删除zscore(name, value)
获取name对应有序集合中 value 对应的分数zinterstore(dest, keys, aggregate=None)
获取两个有序集合的交集,如果遇到相同值不同分数,则按照aggregate进行操作
aggregate的值为: SUM MIN MAXzunionstore(dest, keys, aggregate=None)
获取两个有序集合的并集,如果遇到相同值不同分数,则按照aggregate进行操作
aggregate的值为: SUM MIN MAXzscan(name, cursor=0, match=None, count=None, score_cast_func=float) zscan_iter(name, match=None, count=None,score_cast_func=float)
同字符串相似,相较于字符串新增score_cast_func,用来对分数进行操作
redis其他常用操作
redis-py中其他的API:
delete(*names)
根据删除redis中的任意数据类型
原生redis命令:del key
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 ,但不匹配 hilloexpire(name ,time)
为某个redis的某个name设置超时时间rename(src, dst)
对redis的name重命名为
参数:
src:原name
dst:新namemove(name, db))
将redis的某个值移动到指定的db下 ,如果db下已经存在该name则不执行
redis是一个公共的缓存db,有可能不同的两个程序往redis存了同name的数据,那这就造成了混乱了。所以redis可以生成多个独立的互不影响的内存空间即db,让不同的进程的数据存储到不同的db,那就不会相互影响了。
PS:redis最多只能支持16个db。默认是在db0 如果想要切换db可以使用select
命令
如:select 1
表示切换到db1randomkey()
随机获取一个redis的name(不删除)type(name)
获取name对应值的类型scan(cursor=0, match=None, count=None) scan_iter(match=None, count=None)
同字符串操作,用于增量迭代获取key
管道
redis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作(类似事务,要么全部成功,要么全部执行失败)。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
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) #transaction=开启事务操作
pipe.set('name', 'deehuang')
pipe.set('role', 'headsomeboy')
pipe.execute()
发布订阅
redis的发布订阅功能很简单,一边发送消息,另外一边接收消息。如果在线就能接收到消息,不在线就接收不到。
发布者:服务器
订阅者:Dashboad和数据处理
Demo如下:
import redis
class RedisHelper:
def __init__(self):
self.__conn = redis.Redis(host='10.211.55.4')
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 RedisHelper import RedisHelper
obj = RedisHelper()
redis_sub = obj.subscribe()
while True:
msg= redis_sub.parse_response() #没有消息接收时是阻塞的
print ("recv:",msg)
发布者:
from RedisHelper import RedisHelper
obj = RedisHelper()
obj.public('hello')
更多的redis命令可以参考这里
补充:redis的定期持久化
redis自动的会将修改的key-value进行周期的持久化。这个周期可以在配置文件中设置:
进入配置文件
vim /etc/redis/redis.conf
找到参数 save
默认是 save 900 1 表示 900秒存一次
如果想手动的给数据进行持久化可以使用命令:
save
就完成了手动刷磁盘进行数据持久化
参考文献1
[参考文献2](