当前位置: 移动技术网 > IT编程>数据库>Redis > Redis的Python客户端redis-py安装使用说明文档

Redis的Python客户端redis-py安装使用说明文档

2017年12月08日  | 移动技术网IT编程  | 我要评论

1.安装

redis-py是redis key-value 数据库的 python 接口,安装如下,后面我们会讲hiredis这个库

复制代码 代码如下:

$ sudo pip install redis
$ sudo pip install hiredis

2.入门

复制代码 代码如下:

>>> import redis

>>> pool = redis.connectionpool(host='localhost', port=6379, db=0)

>>> r = redis.strictredis(connection_pool = pool)

>>> r.set('foo', 'bar')

true

>>> r.get('foo')

'bar'

3.api参考

redis 官方文档详细解释了每个命令()。redis-py 提供了两个实现这些命令的客户端类。strictredis 类试图遵守官方的命令语法,但也有几点例外:

·select:没有实现。参见下面“线程安全”部分的解释。

·del:'del' 是 python 语法的保留关键字。因此redis-py 使用 “delete” 代替。

·config get|set:分别用 config_get 和 config_set 实现。

·multi/exec:作为 pipeline 类的一部分来实现。若在调用pipeline 方法时指定use_transaction=true,在执行 pipeline 时会用 multi 和 exec 封装 pipeline 的操作。参见下面 pipeline 部分。

·subscribe/listen: 和 pipeline 类似,由于需要下层的连接保持状态, pubsub 也实现成单独的类。调用 redis 客户端的 pubsub 方法返回一个 pubsub 的实例,通过这个实例可以订阅频道或侦听消息。两个类(strictredis 和 pubsub 类)都可以发布(publish)消息。

除了上面的改变,strictredis 的子类 redis,提供了对旧版本 redis-py 的兼容:

·lrem:参数 ‘num' 和 ‘value' 的顺序交换了一下,这样‘num' 可以提供缺省值 0.

·zadd:实现时 score 和 value 的顺序不小心弄反了,后来有人用了,就这样了

·setex: time 和 value 的顺序反了

注:最好不要用 redis,这个类只是做兼容用的

4.详细说明

4.1 连接池

在后台,redis-py 采用了连接池(connectionpool)来管理对 redis 服务器的连接。缺省情况下,每个redis 实例都创建自己的连接池。也可以采用向 redis 类的 connection_pool 参数传递已创建的连接池的方式。通过这种方式,可以实现客户端分片或精确控制连接的管理:

复制代码 代码如下:

>>> pool = redis.connectionpool(host='localhost', port=6379, db=0)

>>> r = redis.strictredis(connection_pool=pool)


4.2 连接

connectionpool 管理一组 connection 实例。redis-py 提供两种类型的 connection。缺省情况下,connection 是一个普通的 tcp 连接。 unixdomainsocketconnection 允许和服务器运行在同一个设备上的客户端通过 unix 套接字进行连接。要使用 unixdomainsocketconnection 连接, 只需要通过unix_socket_path 参数传递一个 unix 套接字文件的字符串。另外,确保redis.conf 文件配置了unixsocket 参数(缺省情况下是注释掉的):

复制代码 代码如下:

>>> r = redis.strictredis(unix_socket_path='/tmp/redis.sock')

也可以自己创建 connection 子类。这个特性可以在使用异步框架时用于控制 socket 的行为。要使用自己的connection 初始化客户端类,需要创建一个连接池,通 connection_class 参数把自己的类传递进去。传递的其它关键字参数会在初始化时传递给自定义的类:
复制代码 代码如下:

>>> pool = redis.connectionpool(connection_class=yourconnectionclass, your_arg='...', ...)

4.3 分析器

分析类提供了控制如何对 redis 服务器的响应进行分析的途径。redis-py 提供了两个分析类, pythonparser和 hiredisparser。缺省情况下,如果安装了 hiredis 模块, redis-py 会尝试使用 hiredisparser,否则使用 pythonparser。

hiredis 是由 redis 核心团队维护的 c 库。 pieter noordhuis 创建了 python 的实现。分析 redis 服务器的响应时,hiredis 可以提供 10 倍的速度提升。性能提升在获取大量数据时优为明显,比如 lrange 和smembers 操作。

和 redis-py 一样,hiredis 在 pypi 中就有,可以通过 pip 或 easy_install 安装:

复制代码 代码如下:

$ pip install hiredis

或:
复制代码 代码如下:

$ easy_install hiredis

4.4 响应回调函数

客户端类使用一系列回调函数来把 redis 响应转换成合适的 python 类型。有些回调函数在 redis 客户端类的字典 response_callbacks 中定义。

通过 set_response_callback 方法可以把自定义的回调函数添加到单个实例。这个方法接受两个参数:一个命令名和一个回调函数。通过这种方法添加的回调函数只对添加到的对象有效。要想全局定义或重载一个回调函数,应该创建 redis 客户端的子类并把回调函数添加到类的 response_callbacks(原文误为redis_callbacks) 中。

响应回调函数至少有一个参数:redis 服务器的响应。要进一步控制如何解释响应,也可以使用关键字参数。这些关键字参数在对 execute_command 的命令调用时指定。通过 “withscores” 参数,zrange 演示了回调函数如何使用关键字参数。

4.5 线程安全

redis 客户端实例可以安全地在线程间共享。从内部实现来说,只有在命令执行时才获取连接实例,完成后直接返回连接池,命令永不修改客户端实例的状态。

但是,有一点需要注意:select 命令。select 命令允许切换当前连接使用的数据库。新的数据库保持被选中状态,直到选中另一个数据库或连接关闭。这会导致在返回连接池时,连接可能指定了别的数据库。

因此,redis-py 没有在客户端实例中实现 select 命令。如果要在同一个应用中使用多个 redis 数据库,应该给第一个数据库创建独立的客户端实例(可能也需要独立的连接池)。

在线程间传递 pubsub 和 pipeline 对象是不安全的。

4.6 pipeline

pipeline 是 strictredis 类的子类,支持在一个请求里发送缓冲的多个命令。通过减少客户端和服务器之间往来的数据包,可以大大提高命令组的性能。

pipeline 的使用非常简单:

复制代码 代码如下:

>>> r = redis.redis(...)

>>> r.set('bing', 'baz')

>>> # use the pipeline() method to create a pipeline instance

>>> pipe = r.pipeline()

>>> # the following set commands are buffered

>>> pipe.set('foo', 'bar')

>>> pipe.get('bing')

>>> # the execute call sends all bufferred commands to the server, returning

>>> # a list of responses, one for each command.

>>> pipe.execute()

[true, 'baz']

为了方便使用,所有缓冲到 pipeline 的命令返回 pipeline 对象本身。因此调用可以链起来:

复制代码 代码如下:

>>> pipe.set('foo', 'bar').sadd('faz', 'baz').incr('auto_number').execute()

[true, true, 6]


另外,pipeline 也可以保证缓冲的命令组做为一个原子操作。缺省就是这种模式。要使用命令缓冲,但禁止pipeline 的原子操作属性,可以关掉 transaction:

>>> pipe = r.pipeline(transaction=false)
一个常见的问题是:在进行原子事务操作前需要从 redis 中获取事务中要用的数据。比如,假设 incr 命令不存在,但我们需要用 python 创建一个原子版本的 incr。

一个不成熟的实现是获取值(get),在 python 中增一, 设置(set)新值。但是,这不是原子操作,因为多个客户端可能在同一时间做这件事,每一个都通过 get 获取同一个值。

watch 命令提供了在开始事务前监视一个或多个键的能力。如果这些键中的任何一个在执行事务前发生改变,整个事务就会被取消并抛出 watcherror 异常。要实现我们的客户 incr 命令,可以按下面的方法操作:

复制代码 代码如下:

>>> with r.pipeline() as pipe:

...     while 1:

...         try:

...             # 对序列号的键进行 watch

...             pipe.watch('our-sequence-key')

...             # watch 执行后,pipeline 被设置成立即执行模式直到我们通知它

...             # 重新开始缓冲命令。

...             # 这就允许我们获取序列号的值

...             current_value = pipe.get('our-sequence-key')

...             next_value = unicode(int(current_value) + 1)

...             # 现在我们可以用 multi 命令把 pipeline 设置成缓冲模式

...             pipe.multi()

...             pipe.set('our-sequence-key', next_value)

...             # 最后,执行 pipeline (set 命令)

...             pipe.execute()

...             # 如果执行时没有抛出 watcherror,我们刚才所做的确实“原子地”

...             # 完成了

...             break

...         except watcherror:

...             # 一定是其它客户端在我们开始 watch 和执行 pipeline 之间修改了

...             # 'our-sequence-key',我们最好的选择是重试

...             continue


注意,因为在整个 watch 过程中,pipeline 必须绑定到一个连接,必须调用 reset() 方法确保连接返回连接池。如果 pipeline 用作 context manager(如上面的例子所示), reset() 会自动调用。当然,也可以用手动的方式明确调用 reset():
复制代码 代码如下:

>>> pipe = r.pipeline()

>>> while 1:

...     try:

...         pipe.watch('our-sequence-key')

...         current_value = pipe.get('our-sequence-key')

...         next_value = unicode(int(current_value) + 1)

...         pipe.multi()

...         pipe.set('our-sequence-key', next_value)

...         pipe.execute()

...         break

...     except watcherror:

...         continue

...     finally:

...         pipe.reset()

重点(译者注):

·watch 执行后,pipeline 被设置成立即执行模式

·用 multi 命令把 pipeline 设置成缓冲模式

·要么使用 with,要么显式调用 reset()

有一个简便的名为“transaction”的方法来处理这种处理和在 watcherror 重试的模式。它的参数是一个可执行对象和要 watch 任意个数的键,其中可执行对象接受一个 pipeline 对象做为参数。上面的客户端 incr 命令可以重写如下(更可读):

复制代码 代码如下:

>>> def client_side_incr(pipe):

...     current_value = pipe.get('our-sequence-key')

...     next_value = unicode(int(current_value) + 1)

...     pipe.multi()

...     pipe.set('our-sequence-key', next_value)

>>>

>>> r.transaction(client_side_incr, 'our-sequence-key')

4.7 版本计划

redis-py 跟随 redis 发布版本。如 redis-py 2.0.0 应该支持 redis 2.0.0 的所有命令。

4.8 作者

redis-py 由 andy mccurdy () 开发并维护。项目地址在:

特别鸣谢:

·ludovico magnocavallo, python redis 客户端的原作者, 其中一些 socket 代码现在还在使用。

·alexander solovyov 提供通用响应回调系统的思想。

·paul hubbard for initial packaging support.

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网