Python标准库系列之Redis模块
What is redis?
Redis is an open source (BSD licensed), in-memory data structure store, used as database, cache and message broker. It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs and geospatial indexes with radius queries. Redis has built-in replication, Lua scripting, LRU eviction, transactions and different levels of on-disk persistence, and provides high availability via Redis Sentinel and automatic partitioning with Redis Cluster.
Redis官网:http://redis.io/
以上摘自官网介绍
安装Redis
安装
模块GitHub地址:https://github.com/WoLpH/redis-py
[root@anshengme ~]# yum -y install redis
配置绑定的IP
[root@anshengme ~]# vim /etc/redis.conf bind 0.0.0.0
启动并设置开机自启动
1
2
3
|
[root@anshengme ~]
# systemctl start redis
[root@anshengme ~]
# systemctl enable redis
Created symlink
from
/
etc
/
systemd
/
system
/
multi
-
user.target.wants
/
redis.service to
/
usr
/
lib
/
systemd
/
system
/
redis.service.
|
检查
查看端口
1
2
|
[root@anshengme ~]
# netstat -tlnp | grep "redis"
tcp
0
0
0.0
.
0.0
:
6379
0.0
.
0.0
:
*
LISTEN
1439
/
redis
-
server
0
|
数据写入测试
1
2
3
4
5
6
|
[root@anshengme ~]
# /usr/bin/redis-cli
127.0
.
0.1
:
6379
>
set
url https:
/
/
blog.ansheng.me
OK
127.0
.
0.1
:
6379
> get url
"https://blog.ansheng.me"
127.0
.
0.1
:
6379
> exit
|
安装redis-py
安装redis-py
1
|
pip3 install redis
|
或源码安装
1
|
python setup.py install
|
检查安装是否成功
1
2
|
# 导入模块没报错则安装成功
>>>
import
redis
|
入门及使用
1
2
3
4
5
6
7
8
9
10
11
12
|
# 导入模块
>>>
import
redis
# 连接到Redis服务器
>>> conn
=
redis.Redis(host
=
'192.168.56.100'
, port
=
6379
)
# 写入一条数据
>>> conn.
set
(
'name'
,
'ansheng'
)
True
# 获取一条数据
>>> conn.get(
'name'
)
b
'ansheng'
>>> conn.get(
'url'
)
b
'https://blog.ansheng.me'
|
使用连接池连接到Redis
Behind the scenes, redis-py uses a connection pool to manage connections to a Redis server. By default, each Redis instance you create will in turn create its own connection pool. You can override this behavior and use an existing connection pool by passing an already created connection pool instance to the connection_pool argument of the Redis class. You may choose to do this in order to implement client side sharding or have finer grain control of how connections are managed.
1
2
3
4
5
6
|
>>> pool
=
redis.ConnectionPool(host
=
'192.168.56.100'
, port
=
6379
)
>>> conn
=
redis.Redis(connection_pool
=
pool)
>>> conn.
set
(
'hello'
,
'world'
)
True
>>> conn.get(
'hello'
)
b
'world'
|
使用套接字连接
1
|
>>> r
=
redis.Redis(unix_socket_path
=
'/tmp/redis.sock'
)
|
API
redis-py
提供的API
用来操作redis
String API
set(name, value, ex=None, px=None, nx=False, xx=False)
参数 | 描述 |
---|---|
ex |
过期时间(秒) |
px |
过期时间(毫秒) |
nx |
如果设置为True,则只有name不存在时,当前set操作才执行 |
xx |
如果设置为True,则只有name存在时,岗前set操作才执行 |
1
2
3
4
5
|
>>> conn.
set
(
'k1'
,
'v1'
, ex
=
10
, nx
=
True
)
True
>>> conn.get(
'k1'
)
b
'v1'
>>> conn.get(
'k1'
)
|
setex(name, value, time)
设置过期时间/秒
1
2
3
|
>>> conn.setex(
'k'
,
'v'
,
1
)
True
>>> conn.get(
'k'
)
|
psetex(name, time_ms, value)
设置过期时间/毫秒
1
2
3
|
>>> conn.psetex(
'k'
,
10
,
'v'
)
True
>>> conn.get(
'k'
)
|
setnx(name, value)
设置值,只有key不存在时,执行设置操作
1
2
3
4
5
6
7
|
>>> conn.get(
'k1'
)
>>> conn.setnx(
'k1'
,
'v1'
)
True
>>> conn.get(
'k1'
)
b
'v1'
>>> conn.setnx(
'k2'
,
'v2'
)
False
|
mset(*args, **kwargs)
同时设置多个key/value
1
2
3
4
|
>>> conn.mset(k1
=
'v1'
, k2
=
'v2'
)
True
>>> conn.mset({
'k1'
:
'v1'
,
'k1'
:
'v1'
})
True
|
get(name)
获取单个值
1
2
|
>>> conn.get(
'k1'
)
b
'v1'
|
mget(keys, *args)
获取多个值
1
2
3
4
5
|
>>> conn.mget(
'k1'
,
'k2'
)
[b
'v1'
, b
'v2'
]
# 传入列表
>>> conn.mget([
'name'
,
'url'
])
[b
'ansheng'
, b
'https://blog.ansheng.me'
]
|
getset(name, value)
设置新值并获取原来的值
1
2
3
4
5
6
7
|
>>> conn.
set
(
'hello'
,
'world'
)
True
>>> result
=
conn.getset(
'hello'
,
'Linux'
)
>>> result
b
'world'
>>> conn.get(
'hello'
)
b
'Linux'
|
getrange(key, start, end)
通过索引的方式来获取value的值
1
2
3
4
|
>>> conn.
set
(
'key'
,
'value'
)
True
>>> conn.getrange(
'key'
,
1
,
4
)
b
'alue'
|
setrange(name, offset, value)
根据索引修改value
1
2
3
4
5
6
|
>>> conn.
set
(
'n'
,
'123456789'
)
True
>>> conn.setrange(
'n'
,
0
,
'a'
)
9
>>> conn.get(
'n'
)
b'a23456789
|
setbit(name, offset, value)
getbit(name, offset)
获取value对应某一个索引位置对应的值0/1
1
2
|
>>> conn.getbit(
'k'
,
1
)
1
|
bitcount(key, start=None, end=None)
获取key对应二进制中表示1的个数
bitop(operation, dest, *keys)
将多个值进行值运算,得出的结果保存到一个新值当中
1
2
3
4
5
6
7
8
|
>>> conn.mset(n1
=
'abc'
,n2
=
'cde'
,n3
=
'adc'
)
True
>>> conn.bitop(
'AND'
,
'now_key'
,
'n1'
,
'n2'
,
'n3'
)
3
>>> conn.get(
'now_key'
)
b
'a`a'
>>> conn.mget(
'n1'
,
'n2'
,
'n3'
)
[b
'abc'
, b
'cde'
, b
'adc'
]
|
operation支持AND(并)、OR(或)、NOT(非)、XOR(异或)
strlen(name)
获取value的长度
1
2
3
4
|
>>> conn.
set
(
'name'
,
'安生'
)
True
>>> conn.strlen(
'name'
)
6
|
incr(name, amount=1)
对name的value进行自增,如果name不存在则创建,否则自增
1
2
3
4
5
6
7
8
9
|
>>> conn.get(
'number'
)
>>> conn.incr(
'number'
)
1
>>> conn.get(
'number'
)
b
'1'
>>> conn.incr(
'number'
)
2
>>> conn.incr(
'number'
,
10
)
12
|
incrbyfloat(name, amount=1.0)
同上,支持浮点数自增
1
2
3
4
|
>>> conn.incrbyfloat(
'number'
,
1.5
)
13.5
>>> conn.incrbyfloat(
'number'
,
1.1
)
14.6
|
decr(name, amount=1)
自减,同自增一样,如果进行自减的value不是整数就报错
1
2
3
4
5
6
|
>>> conn.
set
(
'n'
,
10
)
True
>>> conn.decr(
'n'
)
9
>>> conn.decr(
'n'
,
9
)
0
|
append(key, value)
在value后面追加内容
1
2
3
4
5
6
|
>>> conn.
set
(
'blog'
,
'https://blog.ansheng.me'
)
True
>>> conn.append(
'blog'
,
'/'
)
26
>>> conn.get(
'blog'
)
b
'https://blog.ansheng.me/'
|
Hash API
hset(name, key, value)
设置name的键值对,有则修改,没有则创建
1
2
3
4
|
>>> conn.hset(
'dic'
,
'k1'
,
'v1'
)
1
>>> conn.hget(
'dic'
,
'k1'
)
b
'v1'
|
hmset(name, mapping)
同时设置多个name的key/value
1
2
3
4
|
>>> conn.hmset(
'dic'
, {
'k1'
:
'v1'
,
'k2'
:
'v2'
})
True
>>> conn.hget(
'dic'
,
'k2'
)
b
'v2'
|
hget(name, key)
获取name中key的值
1
2
|
>>> conn.hget(
'dic'
,
'k2'
)
b
'v2'
|
hmget(name, keys, *args)
同时获取多个
1
2
3
4
|
>>> conn.hmget(
'dic'
,[
'k1'
,
'k2'
])
[b
'v1'
, b
'v2'
]
>>> conn.hmget(
'dic'
,
'k1'
,
'k2'
)
[b
'v1'
, b
'v2'
]
|
hgetall(name)
获取name对应的所有key/value
1
2
|
>>> conn.hgetall(
'dic'
)
{b
'k1'
: b
'v1'
, b
'k2'
: b
'v2'
}
|
hlen(name)
获取name对应键值对的个数
1
2
|
>>> conn.hlen(
'dic'
)
2
|
hkeys(name)
获取name中所有的key
1
2
|
>>> conn.hkeys(
'dic'
)
[b
'k1'
, b
'k2'
]
|
hvals(name)
获取name中所有的value
1
2
|
>>> conn.hvals(
'dic'
)
[b
'v1'
, b
'v2'
]
|
hexists(name, key)
检查当前name中是否有传入的key
1
2
3
4
|
>>> conn.hexists(
'dic'
,
'k1'
)
True
>>> conn.hexists(
'dic'
,
'kk'
)
False
|
hdel(self, name, *keys)
删除name中对应的key
1
2
3
|
>>> conn.hdel(
'dic'
,
'k1'
)
1
>>> conn.hget(
'dic'
,
'k1'
)
|
hincrby(name, key, amount=1)
name中key对应的value进行自增,如果不存在则创建
1
2
3
4
|
>>> conn.hincrby(
'dic'
,
'number'
)
1
>>> conn.hincrby(
'dic'
,
'number'
,
10
)
11
|
hincrbyfloat(name, key, amount=1.0)
value自增,支持浮点数,同上
1
2
3
4
|
>>> conn.hincrbyfloat(
'dic'
,
'float'
)
1.0
>>> conn.hincrbyfloat(
'dic'
,
'float'
,
0.3
)
1.3
|
hscan(name, cursor=0, match=None, count=None)
增量式迭代获取,hscan可以实现分片的获取数据,并非一次性将数据全部获取完,从而放置内存被撑爆
参数 | 描述 |
---|---|
name |
redis的name |
cursor |
游标(基于游标分批取获取数据) |
match |
匹配指定key,默认None 表示所有的key |
count |
每次分片最少获取个数,默认None表示采用Redis的默认分片个数 |
hscan_iter(name, match=None, count=None)
利用yield封装hscan创建生成器,实现分批去redis中获取数据
参数 | 描述 |
---|---|
match |
匹配指定key,默认None 表示所有的key |
count |
每次分片最少获取个数,默认None表示采用Redis的默认分片个数 |
如:
1
2
|
for
item
in
r.hscan_iter(
'xx'
):
print
|