前言
最近有一个需求,里面涉及到把python获取到的数值存储到redis里,于是就简单研究一下python调用redis的方法。
python要调用redis的时候,需要先安装redis模块,有两个方法。第一个方法就是pip install redis,第二个方法就是easy_install redis,模块装完之后,就可以创建redis连接了。
redis-py提供两个类Redis和StrictRedis来实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令(比如,SET命令对应与StrictRedis.set方法)。 Redis是StrictRedis的子类,用于向后兼容旧版本的redis-py。 官方推荐使用StrictRedis方法,所以我这里只说StrictRedis。
如何连接
连接的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12>>> import redis
#这里是redis的基本情况
>>> host = '这里填写redis的host地址'
>>> port = 6379 #根据实际情况更改端口
>>> password = 'redis对应的密码'
#使用StrictRedis去连接到目标redis
>>> r = redis.StrictRedis(host=host, port=6379, password=password, db=0) #db为选定的数据库,db=0代表选择了0号数据库。redis默认有16个数据库,在conf里面可以配置。如果没有指定的数据库,可以不写。
>>> r.set('age', '88')
>>> r.get('age')
'88'
关系型数据库都有一个连接池的概念:对于大量redis连接来说,如果使用直接连接redis的方式的话,将会造成大量的TCP的重复连接,所以,就引入连接池来解决这个问题。在使用连接池连接上redis之后,可以从该连接池里面生成连接,调用完成之后,该链接将会返还给连接池,供其他连接请求调用,这样将减少大量redis连接的执行时间,那么使用StrictRedis的连接池的实现方式如下:
1
2pool = redis.ConnectionPool(host=host, port=6379, password=password)
r = redis.StrictRedis(connection_pool=pool
或者使用pipeline(管道),通过缓冲多条命令,然后一次性执行的方法减少服务器-客户端之间TCP数据库包,从而提高效率,方法如下:
1
2
3
4
5
6
7
8
9
10
11接上文
pipe = r.pipeline()
#插入数据
>>> pipe.hset("hash_key","leizhu900516",8)
Pipeline>>
>>> pipe.hset("hash_key","chenhuachao",9)
Pipeline>>
>>> pipe.hset("hash_key","wanger",10)
Pipeline>>
>>> pipe.execute()
[1L, 1L, 1L]
批量读取数据的方法如下:
1
2
3
4
5
6
7
8
9>>> pipe.hget("hash_key","leizhu900516")
Pipeline>>
>>> pipe.hget("hash_key","chenhuachao")
Pipeline>>
>>> pipe.hget("hash_key","wanger")
Pipeline>>
>>> result = pipe.execute()
>>> print result
['8', '9', '10'] #有序的列表
pipeline的命令可以写在一起,如p.set('hello','redis').sadd('faz','baz').incr('num').execute(),其实它的意思等同于是:
1
2
3
4
5>>> p.set('hello','redis')
>>> p.sadd('faz','baz')
>>> p.incr('num')
>>> p.execute()
[True, 1, 1]
利用pipeline取值3500条数据,大约需要900ms,如果配合线程or协程来使用,每秒返回1W数据是没有问题的,基本能满足大部分业务。
如何存储
上面已经举了一个age:88的例子,可见创建一个string类型的key并放入value是使用set方法,比如再多存几个名字:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24>>> r.set('name', 'lilei')
True
>>> r.get('name')
'lilei'
>>> r.set('name2', 'zhaowei')
True
>>> r.set('name3', 'james')
True
>>> r.set('name4', 'yaoming')
True
#列出以name开头的所有key
>>> print r.keys("name*")
['name3', 'name4', 'name2', 'name']
#列出所有key
>>> print r.keys()
>>> r.dbsize() #当前数据库包含多少条数据
4L
>>> r.delete('name')
1
>>> r.save() #执行“检查点”操作,将数据写回磁盘。保存时阻塞
True
>>> r.get('name')
>>> r.flushdb() #清空r中的所有数据
True
还有其他类型的存储方法,简单举例子如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#创建一个hash
r.hset('abc:def', 'name', "abcde")
#获取一个hash的所有值
print r.hgetall('abc:def')
#获取一个hash的所有key
print r.hkeys('abc:def')
#创建list
r.sadd('abcd:ef','nihao')
r.sadd('abcd:ef','hello')
r.sadd('xxxx','nihao')
r.sadd('xxxx','good')
#打印出该key中的值 list
print r.smembers('abcd:ef')
#查询两个list中相同的值
print r.sinter('abcd:ef', 'xxxx')
#给两个list取并集
print r.sunion('abcd:ef', 'xxxx')
setnx是SET if Not eXists的缩写,也就是只有不存在的时候才设置,可以利用它来实现锁的效果。python要使用它也是r.setnx(key,value),当发现没有这个key的时候,就会插入这个新的key以及对应的value,如果发现有了个这个key了,那这条就等于没加。
如何删除
py-redis中有个delete接口,既可以删除单个key,也可以全删除key,如果要删除几个key,用法是:r.delete('age')、r.delete('sex', 'age'),如果要全删除,那就是
1
2keys = r.keys()
r.delete(*keys)
执行之后的效果等于flushall。
redis里默认情况下是不支持通配符的,那么要批量删除key怎么做呢?答案就是搭配xargs,比如要删除掉所有2018-03-开头的key:
1redis-cli -hredis地址 -a密码 keys "2018-03-*"|xargs redis-cli -hredis地址 -a密码 del
python将两个list元素一一对应转换为dict
使用python的zip函数和强大的集合操作可以方便的将两个list元素一一对应转换为dict,如下示例代码:
1
2
3
4names = ['n1','n2','n3']
values = [1,2,3]
nvs = zip(names,values)
nvDict = dict( (name,value) for name,value in nvs)
参考资料