22Python标准库系列之Redis模块

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介:

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