本节主要介绍Redis的5种数据类型,同时使用Python API来操作Redis,其中python版本为3.5, redis版本为4.0.2。
redis-py 的API的使用可以分类为:
(1)连接方式
(2)连接池
(3)操作
- String 操作
- Hash 操作
- List 操作
- Set 操作
- Sort Set 操作
(4)管道
(5)发布订阅
1. redis文件配置
(1)配置redis配置文件
在之前的博客https://www.cnblogs.com/xuejiale/p/10424885.html中安装并配置了redis,为了能够使用python操作redis,还需要再次配置redis的配置文件/etc/redis/6379.conf。
- 找到bind 127.0.0.1这一行,修改为bind 0.0.0.0
- 把protected-mode yes改为no
- 找到daemonize,可以看到reids默认情况下不是后台驻留程序,(将daemonize属性改为yes,表明需要在后台运行,这个根据你个人情况来搞,如果选择后台驻留,建议设一个密码)
(2)启动redis服务端
使用指定配置文件的方式启动
[root@centos redis]# /etc/init.d/redis_6379 stop Stopping ... Redis stopped [root@centos redis]# /etc/init.d/redis_6379 start Starting Redis server... 7759:C 02 Mar 15:48:23.397 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 7759:C 02 Mar 15:48:23.398 # Redis version=4.0.2, bits=64, commit=00000000, modified=0, pid=7759, just started 7759:C 02 Mar 15:48:23.398 # Configuration loaded [root@centos redis]# redis-cli 测试是否可以连接redis: 127.0.0.1:6379> PING PONG 127.0.0.1:6379>
(3)其他操作
在Python中运行时有时候会报相关错误,要把防火墙关掉
暂时关闭防火墙:(立即生效,开机重启,会重新打开)
service iptables stop
永久关闭防火墙(关机重启才会生效)
chkconfig iptables off
(3)redis设置密码
- 在配置文件中设置
在配置文件中找到requirepass foobared行,打开注释并设置密码为redis123,requirepass redis123,保存退出并重启redis:
重启之后连接redis,并测试需要输入密码:
[root@centos redis]# redis-cli 127.0.0.1:6379> SET name lisi (error) NOAUTH Authentication required. 127.0.0.1:6379> AUTH redis123 OK 127.0.0.1:6379> SET name lisi OK
- 在客户端设置
开两个窗口,在一个窗口设置,如下
127.0.0.1:6379> config set requirepass newredis123 OK
在另一个窗口登录:
[root@centos redis]# redis-cli 127.0.0.1:6379> SET name wangwu (error) NOAUTH Authentication required. 127.0.0.1:6379> AUTH newredis123 OK 127.0.0.1:6379> SET name wangwu OK 127.0.0.1:6379>
(4)python redis API安装与运行redis
首先要安装python 操作redis的API接口模块:
sudo pip install redis
or
sudo easy_install redis
or
源码安装
详见:https://github.com/WoLpH/redis-py
为了方便测试,目前及后续我们不设置redis的密码,使用Windows连接Linux上安装的redis,测试程序如下:
1 import redis 2 3 r = redis.Redis(host='192.168.30.134', port=6379) 4 r.set('foo', 'Bar') 5 print(r.get('foo'))
执行结果:
2. 连接方式
redis-py提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令,Redis是StrictRedis的子类,用于向后兼容旧版本的redis-py。
默认情况下,往redis里插入数据后再读出来时所有键与值都是byte类型的,就是说如果你要使用这些值全部都得转换编码。为了读出的数据是string类型,有一个参数decode_responses可以设置,改参数默认为False,连接redis,加上decode_responses=True,写入的键值对中的value为str类型,不加这个参数写入的则为字节类型。例如:
1 import redis 2 3 r = redis.Redis(host='192.168.30.134', port=6379) 4 #r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True) 5 r.set('subject', 'python') 6 7 print(r['subject']) # 如果subject不存在则会报错 8 print(r.get('subject')) # 如果subject不存在则会返回None 9 print(type(r.get('subject')))
执行结果:
1 import redis 2 3 r = redis.Redis(host='192.168.30.134', port=6379, decode_responses=True) 4 #r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True) 5 r.set('subject', 'Go') 6 7 print(r['subject']) # 如果subject不存在则会报错 8 print(r.get('subject')) # 如果subject不存在则会返回None 9 print(type(r.get('subject')))
执行结果:
注意:如果你设置decode_responses=True,在往数据库里真的写二进制数据的时候,那么再读取的时候就会出错。除非你明确可以知道你没有使用二进制value。
3. 连接池
redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池。
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379) 7 #r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True) 8 9 r = redis.Redis(connection_pool=pool) 10 r.set('foo', 'Bar') 11 print(r.get('foo'))
4. 热身
本小节是通过命令行操作redis,后面不会再使用该命令行的方式,会使用python API操作redis。
首先了解几个基础命令,打开redis-cli
(1)获得符合规则的键名列表
KEYS pattern
可以通过help COMMAND来获取该命令的使用信息。比如:
127.0.0.1:6379> help KEYS KEYS pattern summary: Find all keys matching the given pattern since: 1.0.0 group: generic
pattern支持glob风格通配符格式,具体规则如下:
使用KEYS *能够获的Redis中所有的键,如
127.0.0.1:6379> KEYS * 1) "num" 2) "key" 3) "foo" 4) "bar" 5) "name"
注意:KEYS命令需要遍历Redis中所有的键,当键的数量较多时会影响性能,不建议在生产环境中使用。
提示:Redis不区分命令大小写,但习惯于使用大写字母表示Redis命令。
(2)判断一个键是否存在
EXISTS key [key ...] summary: Determine if a key exists
如果键存在则返回整数类型1,否则返回0。
127.0.0.1:6379> EXISTS foo (integer) 1 127.0.0.1:6379> EXISTS noexists (integer) 0
(3)删除键
DEL key [key ...]
summary: Delete a key
可以删除一个或者多个键,返回值是删除的键的个数。如:
127.0.0.1:6379> DEL foo (integer) 1 127.0.0.1:6379> DEL foo (integer) 0
第二次执行 DEL 命令时因为 bar 键已经删除了,实际上并没有删除任何键,所以返回0。
技巧: DEL命令的参数不支持通配符,但是可以结合Linux的管道和xargs命令自行实现删除所有符合规则的键。比如要删除所有以“user:”开头的键,就可以执行redis-cli KEYS "user:*" | xargs redis-cli DEL。另外由于DEL命令支持多个键作为参数,所以还可以执行redis-cli DEL `redis-cli KEYS "user:"`来达到同样的效果,但是性能更好。
(4)获得键值的数据类型
TYPE key
summary: Determine the type stored at key
TYPE命令用来获得键值的数据类型,返回值可能是string(字符串类型)、hash(散列类型)、list(列表类型)、set(集合类型)、zset(有序集合类型)。例如:
127.0.0.1:6379> SET foo 1 OK 127.0.0.1:6379> TYPE foo string 127.0.0.1:6379> LPUSH bar 1 (integer) 1 127.0.0.1:6379> TYPE bar list 127.0.0.1:6379>
5. 操作
(1)String 操作
String操作,redis中的String在在内存中按照一个name对应一个value来存储。字符串类型是Redis中基本的数据类型,他能存储任何形式的字符串,包括二进制数据。你可以用其存储用户的邮箱、JSON化的对象甚至是一张图片。一个字符串类型的键允许存储的最大容量是512M。
1)设置与获取
- set(name, value, ex=None, px=None, nx=False, xx=False)
Set the value at key ``name`` to ``value`` ``ex`` sets an expire flag on key ``name`` for ``ex`` seconds. ``px`` sets an expire flag on key ``name`` for ``px`` milliseconds. ``nx`` if set to True, set the value at key ``name`` to ``value`` only if it does not exist. ``xx`` if set to True, set the value at key ``name`` to ``value`` only if it already exists.
这里只演示ex,其他参数类似,ex过期时间(秒) 这里过期时间是5秒,5秒后,键subject的值就变成None
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 #r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 9 r = redis.Redis(connection_pool=pool) 10 r.set('subject', 'Go', ex=5) 11 print(r.get('subject'))
对于上面的参数有下面的对应API可以直接设置:
setnx(name, value) "Set the value of key ``name`` to ``value`` if key doesn't exist" setex(name, time, value) Set the value of key ``name`` to ``value`` that expires in ``time`` seconds. ``time`` can be represented by an integer or a Python timedelta
object. psetex(name, time_ms, value) Set the value of key ``name`` to ``value`` that expires in ``time_ms`` milliseconds. ``time_ms`` can be represented by an integer or a Python
timedelta object
- mset(mapping)
Sets key/values based on a mapping. Mapping is a dictionary of key/value pairs. Both keys and values should be strings or types that can be
cast to a string via str().
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 9 r = redis.Redis(connection_pool=pool) 10 r.mset({"k1":"v1", "k2":"v2"}) 11 print(r.mget('k1', 'k2')) #['v1', 'v2']
- mget(keys, *args)
Returns a list of values ordered identically to ``keys``
1 import redis 2 3 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 4 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 5 6 r = redis.Redis(connection_pool=pool) 7 print(r.mget('k1', 'k2')) # ['v1', 'v2'] 8 print(r.mget(['k1', 'k2'])) # ['v1', 'v2'] 9 print(r.mget("key1", "key2", "key3", "k1", "k2")) # [None, None, None, 'v1', 'v2']
- getset(name, value)
Sets the value at key ``name`` to ``value`` and returns the old value at key ``name`` atomically.
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 9 r = redis.Redis(connection_pool=pool) 10 r.set("subject", "Go") 11 print(r.get("subject")) # Go 12 print(r.getset("subject", "C++")) # Go 13 print(r.get("subject")) # C++
- getrange(key, start, end)
Returns the substring of the string value stored at ``key``, determined by the offsets ``start`` and ``end`` (both are inclusive)
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 9 r = redis.Redis(connection_pool=pool) 10 r.set("subject", "Go语言") 11 print(r.getrange("subject", 0, 1)) # Go 12 print(r.getrange("subject", 0, 4)) # Go语 注意:汉字占三个字节,取的时候不能截断,比如取0,3错误 13 r.set("subject","C++") # 字母 14 print(r.getrange("subject", 0, 2)) # C++ 15 print(r.getrange("subject", 0, -1)) # C++
- setrange(name, offset, value)
Overwrite bytes in the value of ``name`` starting at ``offset`` with ``value``. If ``offset`` plus the length of ``value`` exceeds the length
of the original value, the new value will be larger than before. If ``offset`` exceeds the length of the original value, null bytes will be
used to pad between the end of the previous value and the start of what's being injected. Returns the length of the new string.
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 9 r = redis.Redis(connection_pool=pool) 10 r.set("subject", "Go语言") 11 print(r.setrange("subject", 0, "C+")) # 8 注意:汉字三个占字节,汉字的字节位置是固定的,占了就报错 12 print(r.get("subject")) # C+语言 13 14 print(r.setrange("subject", 8, "hello你好")) # 19 设置成 5 也会报错 15 print(r.get("subject")) # C+语言hello你好
2)位操作
一个字节由8个二进制位组成,Redis提供了4个命令可以直接对二进制位进行操作。为了演示,先将foo键赋值为bar:
- setbit(name, offset, value)
Flag the ``offset`` in ``name`` as ``value``. Returns a boolean indicating the previous value of ``offset``.
注意:值 value 只能是 1 或 0。
bar 的3个字母 'b','a','r'对应的ASCII码分别为98、97和114,转换成二进制分别如下:
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 9 r = redis.Redis(connection_pool=pool) 10 r.set("foo", "bar") # b 98 a 97 r 114 11 r.setbit("foo", 7, 1) 12 print(r.get("foo")) # car
- getbit(name, offset)
Returns a boolean indicating the value of ``offset`` in ``name``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 9 r = redis.Redis(connection_pool=pool) 10 r.set("foo", "bar") # b 98 a 97 r 114 11 print(r.getbit("foo", 7)) # 0 12 r.setbit("foo", 7, 1) 13 print(r.getbit("foo", 7)) # 1 14 print(r.get("foo")) # car
- bitcount(key, start=None, end=None)
Returns the count of set bits in the value of ``key``. Optional ``start`` and ``end`` paramaters indicate which bytes to consider
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 9 r = redis.Redis(connection_pool=pool) 10 r.set("foo", "bar") # b 98 a 97 r 114 11 print(r.bitcount("foo")) # 10 "bar"转换成二进制总共有10个1
- bitop(operation, dest, *keys)
Perform a bitwise operation using ``operation`` between ``keys`` and store the result in ``dest``.
operation,AND(并) 、 OR(或) 、 NOT(非) 、 XOR(异或)
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 9 r = redis.Redis(connection_pool=pool) 10 r.mset({"num1":"a", "num2":"b"}) 11 print(r.get("num1")) 12 print(r.get("num2")) 13 14 print(bin(97)) 15 print(bin(98)) 16 # a 1100001 17 # b 1100010 18 19 r.bitop("AND", "kand", "num1", "num2") 20 print(r.get("kand")) 21 22 r.bitop("OR", "kor", "num1", "num2") 23 print(r.get("kor")) 24 25 r.bitop("XOR", "kxor", "num1", "num2") 26 print(r.get("kxor"))
3)strlen(name)
Return the number of bytes stored in the value of ``name``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 9 r = redis.Redis(connection_pool=pool) 10 r.set("foo", "helloworld") 11 print(r.strlen("foo")) # 10
4)incr(self, name, amount=1)
Increments the value of ``key`` by ``amount``. If no key exists, the value will be initialized as ``amount``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 9 r = redis.Redis(connection_pool=pool) 10 print(r.get("num")) # 之前存在为 60 11 r.incr("num", 10) # 60 + 10 = 70 12 print(r.get("num")) 13 14 print(r.get("newnum")) # redis实例中没有键 newnum 15 r.incr("newnum", 10) # 初始化为 10 16 print(r.get("newnum")) # 10
应用场景 – 统计某篇博客或者某个网站一天的访问量:
假定我们对一系列页面需要记录点击次数。例如论坛的每个帖子都要记录点击次数,而点击次数比回帖的次数的多得多。如果使用关系数据库来存储点击,可能存在大量的行级锁争用。所以,点击数的增加使用redis的INCR命令最好不过了。当redis服务器启动时,可以从关系数据库读入点击数的初始值(12306这个页面被访问了666666次)。
r.set("visit:12306:totals", 34634) print(r.get("visit:12306:totals"))
每当有一个页面点击,则使用INCR增加点击数即可。
r.incr("visit:12306:totals")
页面载入的时候则可直接获取这个值。
print(r.get("visit:12306:totals"))
incrbyfloat(self, name, amount=1.0) 使用方法同 incr。
Increments the value at key ``name`` by floating ``amount``. If no key exists, the value will be initialized as ``amount``
decr(name, amount=1) 使用方法同 incr。
Decrements the value of ``key`` by ``amount``. If no key exists, the value will be initialized as 0 - ``amount`` # An alias for ``decr()``, because it is already implemented # as DECRBY redis command.
5)append(key, value)
Appends the string ``value`` to the value at ``key``. If ``key`` doesn't already exist, create it with a value of ``value``. Returns the new
length of the value at ``key``.
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 9 r = redis.Redis(connection_pool=pool) 10 print(r.get("name")) # wangwuzhangsan 11 r.append("name", "-zhangsan") 12 print(r.get("name")) # wangwuzhangsan-zhangsan 13 r.append("name", "-lisi") 14 print(r.get("name")) # wangwuzhangsan-zhangsan-lisi
(2) Hash 操作
redis中Hash在内存中的存储格式如下图:
1)设置与获取
- hset(self, name, key, value)
Set ``key`` to ``value`` within hash ``name``. Returns 1 if HSET created a new field, otherwise 0hsetnx(self, name, key, value)
- hsetnx(self, name, key, value)
Set ``key`` to ``value`` within hash ``name`` if ``key`` does not exist. Returns 1 if HSETNX created a field, otherwise 0.
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.hset("hash1", "k1", "v1") 11 r.hset("hash1", "k2", "v2") 12 print(r.hkeys("hash1")) # 取hash中所有的key ['k1', 'k2'] 13 print(r.hget("hash1", "k1")) # 单个取hash的key对应的值 v1 14 print(r.hmget("hash1", "k1", "k2")) # 多个取hash的key对应的值 ['v1', 'v2'] 15 r.hsetnx("hash1", "k2", "v3") # 只能新建 16 print(r.hget("hash1", "k2")) # 并没有修改 k2的值
- hmset(name, mapping)
Set key to value within hash ``name`` for each corresponding key and value from the ``mapping`` dict.
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.hmset("hash2", {"k1": "v1", "k2": "v2", "k3": "v3"}) 11 print(r.hkeys("hash2")) # 取hash中所有的key ['k1', 'k3', 'k2'] 12 print(r.hget("hash2", "k1")) # 单个取hash的key对应的值 v1 13 print(r.hmget("hash2", "k1", "k2", "k3")) # 多个取hash的key对应的值 ['v1', 'v2', 'v3']
- hget(name, key)
Return the value of ``key`` within the hash ``name``
- hmget(name, keys, *args)
Returns a list of values ordered identically to ``keys``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.hmset("hash2", {"k1": "v1", "k2": "v2", "k3": "v3"}) 11 print(r.hkeys("hash2")) # 取hash中所有的key ['k1', 'k3', 'k2'] 12 print(r.hget("hash2", "k1")) # 单个取hash的key对应的值 v1 13 # 方式1 14 print(r.hmget("hash2", "k1", "k2", "k3")) # 多个取hash的key对应的值 ['v1', 'v2', 'v3'] 15 # 方式2 16 print(r.hmget("hash2", ["k1", "k2", "k3"])) # 多个取hash的key对应的值 ['v1', 'v2', 'v3']
- hgetall(name)
Return a Python dict of the hash's name/value pairs
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.hmset("hash2", {"k1": "v1", "k2": "v2", "k3": "v3"}) 11 print(r.hgetall("hash2")) # {'k2': 'v2', 'k1': 'v1', 'k3': 'v3'}
- hlen(name)
Return the number of elements in hash ``name``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.hmset("hash2", {"k1": "v1", "k2": "v2", "k3": "v3"}) 11 print(r.hlen("hash2")) # 3 获取键值对的数量
- hkeys(name)
Return the list of keys within hash ``name``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.hmset("hash2", {"k1": "v1", "k2": "v2", "k3": "v3"}) 11 print(r.hkeys("hash2")) # ['k1', 'k3', 'k2']
- hvals(name)
Return the list of values within hash ``name``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.hmset("hash2", {"k1": "v1", "k2": "v2", "k3": "v3"}) 11 print(r.hkeys("hash2")) # ['k1', 'k3', 'k2'] 12 print(r.hvals("hash2")) # ['v1', 'v3', 'v2']
2)hexists(name, key)
Returns a boolean indicating if ``key`` exists within hash ``name``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.hmset("hash2", {"k1": "v1", "k2": "v2", "k3": "v3"}) 11 print(r.hexists("hash2", "k1")) # True 12 print(r.hexists("hash2", "k5")) # False
3)hdel(name,*keys)
Delete ``keys`` from hash ``name``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.hmset("hash2", {"k1": "v1", "k2": "v2", "k3": "v3", "k5": "v5", "k6": "v6"}) 11 print(r.hgetall("hash2")) # {'k5': 'v5', 'k2': 'v2', 'k1': 'v1', 'k6': 'v6', 'k3': 'v3'} 12 13 r.hdel("hash2", "k1") 14 print(r.hgetall("hash2")) # {'k5': 'v5', 'k2': 'v2', 'k6': 'v6', 'k3': 'v3'} 15 16 r.hdel("hash2", "k2", "k3") 17 print(r.hgetall("hash2")) # {'k6': 'v6', 'k5': 'v5'}
4)hincrby(name, key, amount=1)
Increment the value of ``key`` in hash ``name`` by ``amount``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.hmset("hash2", {"k1": 1, "k2": 2, "k3": 3}) 11 print(r.hget("hash2", "k1")) # 1 12 13 r.hincrby("hash2", "k1", amount=100) 14 print(r.hget("hash2", "k1")) # 101
- hincrbyfloat(name, key, amount=1.0)
Increment the value of ``key`` in hash ``name`` by floating ``amount``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.hmset("hash2", {"k1": 1, "k2": 2, "k3": 3}) 11 print(r.hget("hash2", "k1")) # 1 12 13 r.hincrbyfloat("hash2", "k1", amount=100.02) 14 print(r.hget("hash2", "k1")) # 101.02
5)hscan(name, cursor=0, match=None, count=None)
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时,表示数据已经通过分片获取完毕
Incrementally return key/value slices in a hash. Also return a cursor indicating the scan position. ``match`` allows for filtering the keys by pattern ``count`` allows for hint the minimum number of returns
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 dic = {} 11 for i in range(100): 12 key = "k%s" % i 13 value = "v%s" % i 14 dic[key] = value 15 r.hmset("hash2", dic) 16 17 data = r.hscan("hash2") 18 while True: 19 if data[0] != 0: 20 print(data) 21 data = r.hscan("hash2", cursor=data[0]) 22 else: 23 print(data) 24 break
注意:hscan它们每次执行都只会返回少量元素,所以该命令可以用于生产环境,而不会出现像 KEYS 或者 SMEMBERS 命令一次性将数据全部获取完,从而可能会将内存撑爆,带来的会阻塞服务器的问题。
更加详细的解释:http://www.redis.cn/commands/scan.html
6)hscan_iter(name, match=None, count=None)
利用yield封装hscan创建生成器,实现分批去redis中获取数据
参数:
match,匹配指定key,默认None 表示所有的key
count,每次分片最少获取个数,默认None表示采用Redis的默认分片个数
ake an iterator using the HSCAN command so that the client doesn't need to remember the cursor position. ``match`` allows for filtering the keys by pattern ``count`` allows for hint the minimum number of returns
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 dic = {} 11 for i in range(1000): 12 key = "k%s" % i 13 value = "v%s" % i 14 dic[key] = value 15 r.hmset("hash2", dic) 16 17 for item in r.hscan_iter('hash2', count=100): 18 print(item) 19 print(r.hscan_iter("hash2")) # 生成器内存地址
(3)List 操作
1)lpush(name, *values)
每次将数据加入到key的头部。
Push ``values`` onto the head of the list ``name``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 # lpush 将数据插入到头部 11 r.lpush("list1", 11, 22, 33) # ['33', '22', '11'] 12 print(r.lrange('list1', 0, -1)) 13 14 r.lpush("list1", "newdata") 15 print(r.lrange('list1', 0, -1)) # ['newdata', '33', '22', '11']
- rpush(name, *values)
Push ``values`` onto the tail of the list ``name``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 # lpush 将数据插入到头部 11 r.lpush("list1", 11, 22, 33) # ['33', '22', '11'] 12 print(r.lrange('list1', 0, -1)) 13 14 r.lpush("list1", "head") 15 print(r.lrange('list1', 0, -1)) # ['head', '33', '22', '11'] 16 17 r.rpush("list1", "tail") 18 print(r.lrange('list1', 0, -1)) # ['head', '33', '22', '11', 'tail']
- lpushx(name, value)
Push ``value`` onto the head of the list ``name`` if ``name`` exists
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.lpushx("list2", "head") 11 print(r.lrange('list2', 0, -1)) # [] 12 13 # lpush 将数据插入到头部 14 r.lpush("list2", 11, 22, 33) # ['33', '22', '11'] 15 print(r.lrange('list2', 0, -1)) 16 17 r.lpushx("list2", "head") 18 print(r.lrange('list2', 0, -1)) # ['head', '33', '22', '11']
- rpushx(name, value)
Push ``value`` onto the tail of the list ``name`` if ``name`` exists
2)linsert(name, where, refvalue, value))
Insert ``value`` in list ``name`` either immediately before or after [``where``] ``refvalue`` Returns the new length of the list on success or -1 if ``refvalue`` is not in the list.
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.rpush("list3", 11, 22, 33) 11 print(r.lrange('list3', 0, -1)) # ['11', '22', '33'] 12 13 r.linsert("list3", "before", 22, "00") 14 print(r.lrange('list3', 0, -1)) # ['11', '00', '22', '33'] 15 16 r.linsert("list3", "after", 33, "99") 17 print(r.lrange('list3', 0, -1)) # ['11', '00', '22', '33', '99']
3)lset(name, index, value)
Set ``position`` of list ``name`` to ``value``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.rpush("list5", 11, 22, 33) 11 print(r.lrange('list5', 0, -1)) # ['11', '22', '33'] 12 13 r.lset("list5", 0, 99) 14 print(r.lrange('list5', 0, -1)) # 修改索引0处的值 11->99 ['99', '22', '33']
4)lrem(name, count, value)
Remove the first ``count`` occurrences of elements equal to ``value`` from the list stored at ``name``. The count argument influences the operation in the following ways: count > 0: Remove elements equal to value moving from head to tail. count < 0: Remove elements equal to value moving from tail to head. count = 0: Remove all elements equal to value.
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.rpush("list5", 11, 22, 33, 11, 22 ,33) 11 print(r.lrange('list5', 0, -1)) # ['11', '22', '33', '11', '22', '33'] 12 13 # 如果 count > list中元素的个数,则删除list中所有该元素 14 # count < 0 15 r.lrem("list5", -1, 11) # from tail to head to delete 删除最先出现的11,删除一次 16 print(r.lrange('list5', 0, -1)) # ['11', '22', '33', '22', '33'] 17 # count > 0 18 r.lrem("list5", 2, 22) # from tail to head to delete 删除最先出现的11,删除一次 19 print(r.lrange('list5', 0, -1)) # ['11', '22', '33', '22', '33'] 20 # count = 0 21 r.lrem("list5", 0, 33) # from tail to head to delete 删除最先出现的11,删除一次 22 print(r.lrange('list5', 0, -1)) # ['11']
5)lpop(name)
Remove and return the first item of the list ``name``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.rpush("list5", 11, 22, 33, 11, 22 ,33) 11 print(r.lrange('list5', 0, -1)) # ['11', '22', '33', '11', '22', '33'] 12 13 print(r.lpop("list5")) # 第0个 11 14 print(r.lrange('list5', 0, -1)) # ['22', '33', '11', '22', '33'] 15 print(r.rpop("list5")) # 第4个 33 16 print(r.lrange('list5', 0, -1)) # ['22', '33', '11', '22']
- rpop(name)
Remove and return the last item of the list ``name``
6)ltrim(name, start, end)
Trim the list ``name``, removing all values not within the slice between ``start`` and ``end``
``start`` and ``end`` can be negative numbers just like Python slicing notation
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.rpush("list5", 11, 22, 33, 11, 22 ,33) 11 print(r.lrange('list5', 0, -1)) # ['11', '22', '33', '11', '22', '33'] 12 13 r.ltrim("list5", 1, -2) # 删除两头的值 14 print(r.lrange('list5', 0, -1)) # ['22', '33', '11', '22']
7)lindex(name, index)
Return the item from list ``name`` at position ``index`` Negative indexes are supported and will return an item at the end of the list
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.rpush("list5", 11, 22, 33, 11, 22 ,33) 11 data = r.lrange("list5", 0, -1) 12 print(data) 13 for i in range(len(data)): 14 print(i, r.lindex('list5', i))
8)rpoplpush(src, dst)
RPOP a value off of the ``src`` list and atomically LPUSH it on to the ``dst`` list. Returns the value.
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.rpush("list5", 11, 22, 33) 11 print(r.lrange("list5", 0, -1)) 12 13 r.rpush("list6", 55, 66, 77) 14 print(r.lrange("list6", 0, -1)) 15 # 注意一次只能从list5 的tail移动一个元素到list6的head 16 # r.rpoplpush("list5", "list6") 17 # print(r.lrange("list5", 0, -1)) # ['11', '22'] 18 # print(r.lrange("list6", 0, -1)) # ['33', '55', '66', '77'] 19 20 # 将list5 的所有元素移动一个list6中 21 src_len = len(r.lrange("list5", 0, -1)) 22 for io in range(src_len): 23 r.rpoplpush("list5", "list6") 24 print(r.lrange("list5", 0, -1)) 25 print(r.lrange("list6", 0, -1))
- brpoplpush(src, dst, timeout=0)
注意:timeout timeout,超时时间,当元素所有列表的元素获取完之后,阻塞等待列表内有数据的时间(秒), 0 表示永远阻塞
Pop a value off the tail of ``src``, push it on the head of ``dst`` and then return it. This command blocks until a value is in ``src`` or until ``timeout`` seconds elapse, whichever is first. A ``timeout`` value of 0 blocks
forever.
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.rpush("list5", 11, 22, 33) 11 print(r.lrange("list5", 0, -1)) 12 13 r.rpush("list6", 55, 66, 77) 14 print(r.lrange("list6", 0, -1)) 15 # 注意一次只能从list5 的tail移动一个元素到list6的head 16 # r.brpoplpush("list5", "list6", timeout=2) 17 # print(r.lrange("list5", 0, -1)) # ['11', '22'] 18 # print(r.lrange("list6", 0, -1)) # ['33', '55', '66', '77'] 19 20 # 将list5 的所有元素移动一个list6中 21 src_len = len(r.lrange("list5", 0, -1)) 22 for io in range(src_len): 23 r.brpoplpush("list5", "list6", timeout=2) 24 print(r.lrange("list5", 0, -1)) 25 print(r.lrange("list6", 0, -1)) 26 27 print("done")
- brpop(keys, timeout)
从第一个list开始,依次循环从每个列表的tail取数据,直到所有list为空。
LPOP a value off of the first non-empty list named in the ``keys`` list. If none of the lists in ``keys`` has a value to LPOP, then block for ``timeout`` seconds, or until a value gets pushed on to one of the lists.
If timeout is 0, then block indefinitely.
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.rpush("list10", 3, 4, 5) 11 r.rpush("list11", 6, 7, 8) 12 13 list10_len = r.llen("list10") 14 list11_len = r.llen("list11") 15 16 while (list10_len != 0 or list11_len != 0): 17 data = r.blpop(["list10", "list11"], timeout=2) 18 print(data, r.lrange("list10", 0, -1), r.lrange("list11", 0, -1)) 19 20 list10_len = r.llen("list10") 21 list11_len = r.llen("list11") 22 23 # 从第一个list开始,依次循环从每个列表的tail取数据,直到所有list为空 24 # 执行结果: 25 # ('list10', '3') ['4', '5'] ['6', '7', '8'] 26 # ('list10', '4') ['5'] ['6', '7', '8'] 27 # ('list10', '5') [] ['6', '7', '8'] 28 # ('list11', '6') [] ['7', '8'] 29 # ('list11', '7') [] ['8'] 30 # ('list11', '8') [] []
注意:可以通 r.llen(name) 获取list的长度。
9)自定义增量迭代
由于redis类库中没有提供对列表元素的增量迭代,如果想要循环name对应的列表的所有元素,那么就需要: 1)获取name对应的所有列表 2)循环列表 但是,如果列表非常大,那么就有可能在第一步时就将程序的内存撑爆,所有有必要自定义一个增量迭代的功能:
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 def list_iter(name): 11 """ 12 自定义redis列表增量迭代 13 :param name: redis中的name,即:迭代name对应的列表 14 :return: yield 返回 列表元素 15 """ 16 list_len = r.llen(name) 17 for index in range(list_len): 18 yield r.lindex(name, index) 19 20 print(r.lrange("list2", 0, -1)) # ['head', '33', '22', '11'] 21 # 使用 22 for item in list_iter('list2'): # 遍历这个列表 23 print(item)
(4)Set 操作
Set操作,Set集合就是不允许重复的列表,本身是无序的。
1)sadd(name, *values)
Add ``value(s)`` to set ``name``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.sadd("set1", 33, 44, 55, 66) # 往集合中添加元素 11 print(r.scard("set1")) # 集合的长度是4 12 print(r.smembers("set1")) # 获取集合中所有的成员 {'33', '55', '66', '44'} 13 14 r.sadd("set1", 77, 77) # 往集合中添加元素 会自动去重 15 print(r.scard("set1")) # 集合的长度是4 16 print(r.smembers("set1")) # 获取集合中所有的成员 {'33', '77', '55', '66', '44'}
2)scard(name)
Return the number of elements in set ``name``
3)smembers(name)
Return all members of the set ``name``
- sscan(name, cursor=0, match=None, count=None)
Incrementally return lists of elements in a set. Also return a cursor indicating the scan position. ``match`` allows for filtering the keys by pattern ``count`` allows for hint the minimum number of returns
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 print(r.smembers("set1")) 11 12 for i in range(1000): 13 r.sadd("set1", i) # 往集合中添加元素 14 15 data = r.sscan("set1") # 返回的是一个元组,第一个是游标,供下次使用,第二个是数据 16 print(data) 17 18 while data[0]: 19 data = r.sscan("set1", cursor=data[0]) 20 print(data)
类似于 hscan,可以参考学习。
- sscan_iter(name, match=None, count=None)
Make an iterator using the SSCAN command so that the client doesn't need to remember the cursor position. ``match`` allows for filtering the keys by pattern ``count`` allows for hint the minimum number of returns
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 print(r.smembers("set1")) 11 12 for i in range(1000): 13 r.sadd("set1", i) # 往集合中添加元素 14 15 print(r.sscan_iter("set1")) # <generator object Redis.sscan_iter at 0x0000000002C49DB0> 16 17 for data in r.sscan_iter("set1"): 18 print(data)
注意:同字符串的操作,用于增量迭代分批获取元素,避免内存消耗太大。
4)sdiff(keys, *args)
集合求差集:在第一个name对应的集合中且不在其他name对应的集合的元素集合
Return the difference of sets specified by ``keys``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.sadd("set1", 11, 22, 33) 11 r.sadd("set2", 22, 33, 44) 12 print(r.smembers("set1")) # 获取集合中所有的成员 13 print(r.smembers("set2")) 14 15 print(r.sdiff("set1", "set2")) # 在集合set1但是不在集合set2中 {'11'} 16 print(r.sdiff("set2", "set1")) # 在集合set2但是不在集合set1中 {'44'}
5)sdiffstore(dest, keys, *args)
将在第一个name对应的集合中且不在其他name对应的集合中的元素加入到dest对应的集合中。
Store the difference of sets specified by ``keys`` into a new set named ``dest``.
Returns the number of keys in the new set.
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.sadd("set1", 11, 22, 33, 55) 11 r.sadd("set2", 22, 33, 44) 12 print(r.smembers("set1")) 13 print(r.smembers("set2")) 14 15 r.sdiffstore("set3", "set1", "set2") 16 print(r.smembers("set3")) # {'55', '11'} , 11 和 55在set1中不在set2中
6)sinter(keys, *args)
获取交集。
Return the intersection of sets specified by ``keys``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.sinter("set1", 11, 22, 66, 33, 55) 11 r.sadd("set2", 22, 33, 44) 12 print(r.smembers("set1")) 13 print(r.smembers("set2")) 14 15 print(r.sinter("set1", "set2")) # {'33', '22'}
- sinterstore(dest, keys, *args)
Store the intersection of sets specified by ``keys`` into a new set named ``dest``. Returns the number of keys in the new set.
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.sinter("set1", 11, 22, 66, 33, 55) 11 r.sadd("set2", 22, 33, 44) 12 print(r.smembers("set1")) 13 print(r.smembers("set2")) 14 15 print(r.sinterstore("set3", "set1", "set2")) # {'33', '22'} 16 print(r.smembers("set3")) # {'22', '33'}
7)sunion(keys, *args)
Return the union of sets specified by ``keys``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.sinter("set1", 11, 22, 66, 33, 55) 11 r.sadd("set2", 22, 33, 44) 12 print(r.smembers("set1")) 13 print(r.smembers("set2")) 14 15 print(r.sunion("set1", "set2")) # {'22', '55', '33', '11', '44'}
- sunionstore(dest,keys, *args)
Store the union of sets specified by ``keys`` into a new set named ``dest``. Returns the number of keys in the new set.
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.sinter("set1", 11, 22, 66, 33, 55) 11 r.sadd("set2", 22, 33, 44) 12 print(r.smembers("set1")) 13 print(r.smembers("set2")) 14 15 print(r.sunionstore("set3", "set1", "set2")) 16 print(r.smembers("set3")) # {'44', '33', '11', '55', '22'}
8)sismember(name, value)
检查value是否是name对应的集合的成员,结果为True和False
Return a boolean indicating if ``value`` is a member of set ``name``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.sinter("set1", 11, 22, 66, 33, 55) 11 r.sadd("set2", 22, 33, 44) 12 print(r.smembers("set1")) 13 print(r.smembers("set2")) 14 15 print(r.sismember("set1", 11)) # True 16 print(r.sismember("set2", 11)) # False
9)smove(src, dst, value)
将 src 中的成员移动到 dst 集合中。
Move ``value`` from set ``src`` to set ``dst`` atomically
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.sadd("set1", 11, 22, 66, 33, 55) 11 r.sadd("set2", 22, 33, 44) 12 print(r.smembers("set1")) 13 print(r.smembers("set2")) 14 15 r.smove("set1", "set3", 11) 16 print(r.smembers("set1")) # {'22', '66', '55', '33'} 将 set1中的11移到set3中 17 print(r.smembers("set3")) # {'11'}
10)spop(name)
从集合移除一个成员,并将其返回,说明一下,集合是无序的,所有是随机删除的。
Remove and return a random member of set ``name``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.sadd("set1", 11, 22, 66, 33, 55) 11 r.sadd("set2", 22, 33, 44) 12 print(r.smembers("set1")) 13 print(r.smembers("set2")) 14 15 print(r.spop("set1")) # 33 16 print(r.spop("set2")) # 44
11)srem(name, values)
从集合name中删除指定的元素。
Remove ``values`` from set ``name``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.sadd("set1", 11, 22, 66, 33, 55) 11 r.sadd("set2", 22, 33, 44) 12 print(r.smembers("set1")) 13 print(r.smembers("set2")) 14 15 r.srem("set1", 66, 33) 16 print(r.smembers("set1")) # {'55', '22', '11'} 17 r.srem("set2", 33, 44) 18 print(r.smembers("set2")) # {'22'}
(5)Sort Set 操作
Set操作,Set集合就是不允许重复的列表,本身是无序的。有序集合,在集合的基础上,为每元素排序;元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。
1)zadd(name, mapping, nx=False, xx=False, ch=False, incr=False)
Set any number of element-name, score pairs to the key ``name``. Pairs are specified as a dict of element-names keys to score values. ``nx`` forces ZADD to only create new elements and not to update scores for elements that already exist. ``xx`` forces ZADD to only update scores of elements that already exist. New elements will not be added. ``ch`` modifies the return value to be the numbers of elements changed. Changed elements include new elements that were added and elements whose scores changed. ``incr`` modifies ZADD to behave like ZINCRBY. In this mode only a single element/score pair can be specified and the score is the amount the existing score will be incremented by. When using this mode the return value of ZADD will be the new score of the element. The return value of ZADD varies based on the mode specified. With no options, ZADD returns the number of new elements added to the sorted set.
ZADD 参数(options) (>= Redis 3.0.2)
ZADD 命令在key后面分数/成员(score/member)对前面支持一些参数,他们是: XX: 仅仅更新存在的成员,不添加新成员。 NX: 不更新存在的成员。只添加新成员。 CH: 修改返回值为发生变化的成员总数,原始是返回新添加成员的总数 (CH 是 changed 的意思)。更改的元素是新添加的成员,已经存在的成员更新分数。 所以在命令中指定的成员有相同
的分数将不被计算在内。注:在通常情况下,ZADD返回值只计算新添加成员的数量。 INCR: 当ZADD指定这个选项时,成员的操作就等同ZINCRBY命令,对成员的分数进行递增操作。
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.zadd("zset1", {"n1":11, "n2":22}) 11 r.zadd("zset2", {'m1':22, 'm2':44}) 12 print(r.zcard("zset1")) # 集合长度 2 13 print(r.zcard("zset2")) # 集合长度 2 14 print(r.zrange("zset1", 0, -1)) # 获取有序集合中所有元素 ['n1', 'n2'] 15 print(r.zrange("zset2", 0, -1, withscores=True)) # 获取有序集合中所有元素和分数 [('m1', 22.0), ('m2', 44.0)]
2)zcard(name)
获取有序集合元素个数 类似于len
Return the number of elements in the sorted set ``name``
3)zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)
Return a range of values from sorted set ``name`` between ``start`` and ``end`` sorted in ascending order. ``start`` and ``end`` can be negative, indicating the end of the range. ``desc`` a boolean indicating whether to sort the results descendingly ``withscores`` indicates to return the scores along with the values. The return type is a list of (value, score) pairs ``score_cast_func`` a callable used to cast the score return value
- zrevrange(name, start, end, withscores=False, score_cast_func=float)
从大到小排序(同zrange,集合是从大到小排序的)
Return a range of values from sorted set ``name`` between ``start`` and ``end`` sorted in descending order. ``start`` and ``end`` can be negative, indicating the end of the range. ``withscores`` indicates to return the scores along with the values The return type is a list of (value, score) pairs ``score_cast_func`` a callable used to cast the score return value
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.zadd("zset1", {"n1":11, "n2":22}) 11 r.zadd("zset2", {'m1':22, 'm2':44}) 12 print(r.zcard("zset1")) # 集合长度 2 13 print(r.zcard("zset2")) # 集合长度 2 14 print(r.zrevrange("zset1", 0, -1)) # ['n2', 'n1'] 15 print(r.zrevrange("zset2", 0, -1, withscores=True)) # [('m2', 44.0), ('m1', 22.0)]
- zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func=float)
按照分数范围获取name对应的有序集合的元素。
Return a range of values from the sorted set ``name`` with scores between ``min`` and ``max``. If ``start`` and ``num`` are specified, then return a slice of the range. ``withscores`` indicates to return the scores along with the values. The return type is a list of (value, score) pairs `score_cast_func`` a callable used to cast the score return value
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 for i in range(1, 30): 11 element = 'n' + str(i) 12 r.zadd("zset3", {element:i}) 13 print(r.zrangebyscore("zset3", 15, 25)) # # 在分数是15-25之间,取出符合条件的元素 14 print(r.zrangebyscore("zset3", 12, 22, withscores=True)) # 在分数是12-22之间,取出符合条件的元素(带分数)
- zrevrangebyscore(name, max, min, start=None, num=None, withscores=False, score_cast_func=float)
同zrangebyscore,只是以降序排列
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 for i in range(1, 30): 11 element = 'n' + str(i) 12 r.zadd("zset3", {element:i}) 13 print(r.zrevrangebyscore("zset3", 22, 11, withscores=True)) # 在分数是22-11之间,取出符合条件的元素 按照分数降序排列
- zscan(name, cursor=0, match=None, count=None, score_cast_func=float)
类似于 hscan,可以参考学习
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 for i in range(1, 1000): 11 element = 'n' + str(i) 12 r.zadd("zset3", {element:i}) 13 14 data = r.zscan("zset3", cursor=0) 15 print(data) 16 17 while data[0]: 18 data = r.zscan("zset3", cursor=data[0]) 19 print(data)
- zscan_iter(name, match=None, count=None,score_cast_func=float)
获取所有元素–迭代器
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 for i in range(1, 1000): 11 element = 'n' + str(i) 12 r.zadd("zset3", {element:i}) 13 14 for i in r.zscan_iter("zset3"): 15 print(i)
- zcount(name, min, max)
获取name对应的有序集合中分数 在 [min,max] 之间的个数
Returns the number of elements in the sorted set at key ``name`` with a score between ``min`` and ``max``.
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 for i in range(1, 1000): 11 element = 'n' + str(i) 12 r.zadd("zset3", {element:i}) 13 14 print(r.zrange("zset3", 0, -1, withscores=True)) 15 print(r.zcount("zset3", 11, 22)) #12
4)zincrby(name, amount, value)
Increment the score of ``value`` in sorted set ``name`` by ``amount``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.zadd("zset3", {"num":0}) 11 12 r.zincrby("zset3", 20, "num") # 将num的分数自增20 13 print(r.zrange("zset3", 0, -1, withscores=True)) # [('num', 20.0)]
5)zrank(name, value)
获取某个值在 name对应的有序集合中的索引(从 0 开始)
Returns a 0-based value indicating the rank of ``value`` in sorted set ``name``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.zadd("zset3", {"n1":0, "n3":3, "n2":2, "n6":6, "n5":5}) 11 12 print(r.zrank("zset3", "n1")) # n1的索引号是0 这里按照分数顺序(从小到大) 13 print(r.zrank("zset3", "n6")) # n6的索引号是4 14 15 print(r.zrevrank("zset3", "n1")) # n1的索引号是4 这里安照分数倒序(从大到小)
- zrevrank(name, value)
6)zrem(name, *values)
Remove member ``values`` from sorted set ``name``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.zadd("zset3", {"n1":0, "n3":3, "n2":2, "n6":6, "n5":5}) 11 12 r.zrem("zset3", "n1", "n6") #删除集合中的n1 和 n6 13 print(r.zrange("zset3", 0, -1)) # ['n2', 'n3', 'n5']
- zremrangebyrank(name, min, max)
Remove all elements in the sorted set ``name`` with ranks between ``min`` and ``max``. Values are 0-based, ordered from smallest score to
largest. Values can be negative indicating the highest scores. Returns the number of elements removed
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.zadd("zset3", {"n1":0, "n3":3, "n2":2, "n6":6, "n5":5}) 11 12 r.zremrangebyrank("zset3", 0, 1) # 删除有序集合中的索引号是0, 1的元素 13 print(r.zrange("zset3", 0, -1)) # ['n3', 'n5', 'n6']
- zremrangebyscore(name, min, max)
Remove all elements in the sorted set ``name`` with scores between ``min`` and ``max``. Returns the number of elements removed.
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.zadd("zset3", {"n1":10, "n3":30, "n2":20, "n6":60, "n5":50}) 11 12 r.zremrangebyscore("zset3", 20, 50) # 删除有序集合中的索引号是0, 1的元素 13 print(r.zrange("zset3", 0, -1)) # ['n1', 'n6']
7)zscore(name, value)
Return the score of element ``value`` in sorted set ``name``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.zadd("zset3", {"n1":10, "n3":30, "n2":20, "n6":60, "n5":50}) 11 12 print(r.zscore("zset3", "n3")) # 30.0
(6)其他常用操作
1)delete(*names)
根据删除redis中的任意数据类型(string、hash、list、set、有序set)
Delete one or more keys specified by ``names``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.set("string", "strvalue") 11 r.hset("hset", "hsetkey", "hsetvalue") 12 r.lpush("list", "listvalue1", "listvalue2") 13 r.sadd("set", "setvalue1", "setvalue2") 14 r.zadd("zset", {"n1":10, "n3":30, "n2":20, "n6":60, "n5":50}) 15 16 del_key = ["string", "hset", "list", "set", "zset"] 17 18 for key in r.keys(): 19 if key in del_key: 20 r.delete(key)
2)exists(name)
Returns the number of ``names`` that exist
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.set("string", "strvalue") 11 r.hset("hset", "hsetkey", "hsetvalue") 12 r.lpush("list", "listvalue1", "listvalue2") 13 r.sadd("set", "setvalue1", "setvalue2") 14 r.zadd("zset", {"n1":10, "n3":30, "n2":20, "n6":60, "n5":50}) 15 16 del_key = ["string", "hset", "list", "set", "zset"] 17 18 for key in del_key: 19 if r.exists(key): 20 print(key, " exists") 21 r.delete(key) 22 23 print("--------------") 24 25 for key in del_key: 26 if not r.exists(key): 27 print(key, "do not exists")
3)模糊匹配
参见 4.1 热身中的获得符合规则的键名列表
- keys(pattern='*')
Returns a list of keys matching ``pattern``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.set("fo", "bar") 11 r.set("foo", "bar") 12 r.set("fao", "bar") 13 r.set("fdo", "bar") 14 15 print(r.keys(pattern="*")) # 默认 ['zset', 'fdo', 'list', 'fo', 'set', 'fao', 'string', 'hset', 'foo'] 16 print(r.keys(pattern="fo*")) # ['fo', 'foo'] 17 print(r.keys(pattern="f?o")) # ['fao', 'foo', 'fdo'] 18 print(r.keys(pattern="f[a-c]o")) # ['fao']
4)expire(name ,time)
为某个redis的某个name设置超时时间
Set an expire flag on key ``name`` for ``time`` seconds. ``time`` can be represented by an integer or a Python timedelta object.
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 import time 6 7 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 8 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 9 r = redis.Redis(connection_pool=pool) 10 11 r.set("foo", "bar") 12 13 r.expire("foo", 5) # 5秒之后 foo将不存在 14 15 for i in range(8): 16 if r.exists("foo"): 17 print("foo", " exists") 18 else: 19 print("foo", " do not exists") 20 time.sleep(1)
5)rename(src, dst)
Rename key ``src`` to ``dst``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.set("foo", "bar") 11 r.rename("foo", "foo_bak") 12 13 print(r.get("foo")) # None 14 print(r.get("foo_bak")) # bar
6)randomkey()
Returns the name of a random key
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.mset({"name":"nova", "age":10, "sex":"male", "address":"xian"}) 11 print(r.randomkey())
7)type(name)
Returns the type of key ``name``
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.set("string", "strvalue") 11 r.hset("hset", "hsetkey", "hsetvalue") 12 r.lpush("list", "listvalue1", "listvalue2") 13 r.sadd("set", "setvalue1", "setvalue2") 14 r.zadd("zset", {"n1":10, "n3":30, "n2":20, "n6":60, "n5":50}) 15 16 del_key = ["string", "hset", "list", "set", "zset"] 17 18 for key in del_key: 19 if r.exists(key): 20 print(key, r.type(key))
8)scan(cursor=0, match=None, count=None)
类似于 hscan,可以参考学习
9)scan_iter(match=None, count=None)
10)dbsize()
Returns the number of keys in the current database
11)save()
ell the Redis server to save its data to disk, blocking until the save is complete
12)flushdb(asynchronous=False)
Delete all keys in the current database. ``asynchronous`` indicates whether the operation is executed asynchronously by the server.
(4)管道(pipeline)
redis默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,
如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作。
管道(pipeline)是redis在提供单个请求中缓冲多条服务器命令的基类的子类。它通过减少服务器-客户端之间反复的TCP数据库包,从而大大提高了执行批量命令的功能。
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 # pipe = r.pipeline(transaction=False) # 默认的情况下,管道里执行的命令可以保证执行的原子性,执行pipe = r.pipeline(transaction=False)可以禁用这一特性。 11 # pipe = r.pipeline(transaction=True) 12 pipe = r.pipeline() # 创建一个管道 13 14 # pipe.set('name', 'jack') 15 # pipe.set('role', 'sb') 16 # pipe.incr('num') # 如果num不存在则vaule为1,如果存在,则value自增1 17 # pipe.execute() 18 19 # 管道的命令可以写在一起,下面命令和上面等价 如: 20 pipe.set('name', 'jack').set('role', 'sbb').incr('num').execute() 21 22 print(r.get("name")) 23 print(r.get("role")) 24 print(r.get("num"))
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 pool = redis.ConnectionPool(host='192.168.30.134', port=6379, decode_responses=True) 7 # r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, decode_responses=True, decode_responses=True) 8 r = redis.Redis(connection_pool=pool) 9 10 r.set('count',1000) 11 12 with r.pipeline() as pipe: 13 14 # 先监视,自己的值没有被修改过 15 r.watch('count') 16 17 # 事务开始 18 pipe.multi() 19 old_count = r.get('count') 20 count = int(old_count) 21 if count > 0: # 有库存 22 pipe.set('count', count - 1) 23 24 # 执行,把所有命令一次性推送过去 25 pipe.execute() 26 print(r.get("count")) # 999
(5)发布订阅
- 发布者:服务器
- 订阅者:Dashboad和数据处理
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 class RedisHelper: 7 8 def __init__(self): 9 self.__conn = redis.Redis(host='192.168.30.134', port=6379, decode_responses=True) 10 self.chan_sub = 'fm104.5' 11 self.chan_pub = 'fm104.5' 12 13 def public(self, msg): 14 self.__conn.publish(self.chan_pub, msg) 15 return True 16 17 def subscribe(self): 18 pub = self.__conn.pubsub() 19 pub.subscribe(self.chan_sub) 20 pub.parse_response() 21 return pub
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 from monitor import RedisHelper 5 6 obj = RedisHelper() 7 redis_sub = obj.subscribe() 8 9 while True: 10 msg = redis_sub.parse_response() 11 print(msg) # ['message', 'fm104.5', 'hello anybody']
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 from monitor import RedisHelper 5 6 obj = RedisHelper() 7 obj.public('hello anybody')
(6)sentinel
Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。
它的主要功能有以下几点:
- 不时地监控redis是否按照预期良好地运行;
- 如果发现某个redis节点运行出现状况,能够通知另外一个进程(例如它的客户端);
- 能够进行自动切换。当一个master节点不可用时,能够选举出master的多个slave(如果有超过一个slave的话)中的一个来作为新的master,其它的slave节点会将它所追随的master的地址改为被提升为master的slave的新地址。
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 from redis.sentinel import Sentinel 5 6 # 连接哨兵服务器(主机名也可以用域名) 7 sentinel = Sentinel([('10.211.55.20', 26379), 8 ('10.211.55.20', 26380), 9 ], 10 socket_timeout=0.5) 11 12 # # 获取主服务器地址 13 # master = sentinel.discover_master('mymaster') 14 # print(master) 15 # 16 # # # 获取从服务器地址 17 # slave = sentinel.discover_slaves('mymaster') 18 # print(slave) 19 # 20 # 21 # # # 获取主服务器进行写入 22 # master = sentinel.master_for('mymaster') 23 # master.set('foo', 'bar') 24 25 26 27 # # # # 获取从服务器进行读取(默认是round-roubin) 28 # slave = sentinel.slave_for('mymaster', password='redis_auth_pass') 29 # r_ret = slave.get('foo') 30 # print(r_ret)
参考文献:
- http://www.cnblogs.com/wupeiqi/articles/5132791.html
- Redis入门指南 (第二版)
- https://www.cnblogs.com/LearningOnline/p/9456806.html (linux上部署redis实现与Python上的redis交互)
- http://www.redis.cn/commands/scan.html
- https://blog.csdn.net/kl28978113/article/details/78726946
- https://segmentfault.com/a/1190000002680804 (Redis Sentinel机制与用法)