转自:http://blog.sina.com.cn/s/blog_6262a50e0101574h.html

原文:https://github.com/andymccurdy/redis-py

redis-py

Redis key-value 数据库的 Python 接口。

安装

$ sudo pip install redis

或采用下面方法(最好是用 pip):

$ sudo easy_install redis

从源代码安装:

$sudo python setup.py install

入门

>>> import redis

>>> r = redis.StrictRedis(host='localhost', port=6379, db=0)

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

True

>>> r.get('foo')

'bar'

API 参考

Redis 官方文档详细解释了每个命令(http://redis.io/commands)。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,这个类只是做兼容用的

详细说明

连接池

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

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

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

连接

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

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

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

>>> pool = redis.ConnectionPool(connection_class=YourConnectionClass,

your_arg='...', ...)

分析器

分析类提供了控制如何对 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

响应回调函数

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

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

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

线程安全

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

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

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

在线程间传递 PubSub 和 Pipeline 对象是不安全的。

Pipeline

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

Pipeline 的使用非常简单:

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

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

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

>>> pip3 = 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 = 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')

...         ...

...         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 = current_value + 1

...     pipe.multi()

...     pipe.set('OUR-SEQUENCE-KEY', next_value)

>>>

>>> r.transaction(client_side_incr, 'OUR-SEQUENCE-KEY')

版本计划

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

作者

redis-py 由 Andy McCurdy (sedrik@gmail.com) 开发并维护。项目地址在:http://github.com/andymccurdy/redis-py

特别鸣谢:

·Ludovico Magnocavallo, Python Redis 客户端的原作者, 其中一些 socket 代码现在还在使用。

·Alexander Solovyov 提供通用响应回调系统的思想。

·Paul Hubbard for initial packaging support.

redis-py说明文件(转)的更多相关文章

  1. 如何解析 redis 的 rdb 文件

    目录 安装工具 解析 redis 的 rdb 文件 命令行工具使用,先看 --help 生成内存报告 使用参数过滤想要的数据 比较两个 rdb 文件 查看一个 key 的内存使用情况 常见问题 FAQ ...

  2. Redis 数据恢复方法,redis-port 工具将自建 redis 的 rdb文件同步到云数据库

    1. Redis 恢复的机制 如果只配置 AOF ,重启时加载 AOF 文件恢复数据: 如果同时配置了 RDB 和 AOF ,启动是只加载 AOF 文件恢复数据: 如果只配置 RDB,启动是将加载 d ...

  3. 手写redis的docker文件,通过docker-compose配置redis

    在前面一遍随笔,配置的是mysql主从的docker-compose配置.今天我们来学习配置编排容器redis. 准备环境: docker 18.06.1-ce docker-compose 1.23 ...

  4. Redis实现分布式文件夹锁

    缘起 最近做一个项目,类似某度云盘,另外附加定制功能,本人负责云盘相关功能实现,这个项目跟云盘不同的是,以项目为分配权限的单位,同一个项目及子目录所有有权限的用户可以同时操作所有文件,这样就很容易出现 ...

  5. redis执行lua文件

    1.编写lua文件 还lua表示循环插入1-100的键为1-100值为1-100的键值对到redis中 for i=0,100 do redis.call("set",i,i) e ...

  6. 接口测试框架——第一篇-大框架和setting.py常量文件

    基础知识已经准备的差不多了,今天开始我们就开始写我们的接口测试框架,框架结构已经说过了: 今天我们先完善需要的常量,也就是setting.py文件中的内容,代码如下: # coding: utf-8 ...

  7. pycharm批量清楚pyc、$py.class文件

    By default, the .pyc and $py.class files are ignored, and thus are not visible in the Project tool w ...

  8. thinkphp3.2配置redis缓存和文件缓存

    如果把一些常用但又不容易变的数据存缓存,而不是每次查数据库,这样能很大减轻数据库压力 最近由于项目需要,就尝试了一把redis,但是后面又用了tp3.2的文件缓存,直接进入主题: 在config.ph ...

  9. 本地测试读取redis和普通文件缓存的速度,redis慢一倍?

    重新测试了,换成了Linux服务器,php5.6,512内存.连续读取1千次不同的文件(每个文件41KB),redis也是1千个不同的key,文件缓存还是比redis快! 但是,但是,后来我换成连续读 ...

  10. Golang 实现 Redis(11): RDB 文件解析

    RDB 文件使用二进制方式存储 Redis 内存中的数据,具有体积小.加载快的优点.本文主要介绍 RDB 文件的结构和编码方式,并借此探讨二进制编解码和文件处理方式,希望对您有所帮助. 本文基于 RD ...

随机推荐

  1. 10 The Go Programming Language Specification go语言规范 重点

    The Go Programming Language Specification go语言规范 Version of May 9, 2018 Introduction 介绍 Notation 符号 ...

  2. ArcMap2SLD添加中文支持

    首先,你可以从作者提供的链接下载ArcMap2SLD.zip(支持ArcMap10.2) 1.打开LUT_sld_mapping_file.xml文件(上传文件中已经修改)修改文件<LUT> ...

  3. CVE-2010-0249 极光

    传说中的极光漏洞 Microsoft Internet Explorer非法事件操作内存破坏漏洞 Microsoft Internet Explorer是微软Windows操作系统中默认捆绑的WEB浏 ...

  4. appium+python 【Mac】Android夜神模拟器

    1.官网下载地址:https://www.yeshen.com/ 2.具体的夜神模拟器的介绍请自查 3.下载安装后夜神模拟器后,打开模拟器,进行相应的配置如下: 4. (1).找到android-sd ...

  5. Radon变换——MATLAB

    算法说明: 图像的Radon变换是每个像素的Radon变换的总和. 该算法首先将图像中的像素分成四个子像素,并分别投影每个子像素,如下图所示. 根据投影位置和箱体中心之间的距离,每个子像素的贡献按比例 ...

  6. 一步一步学习IdentityServer4 (2) 开始一个简单的事例

    前面将来一些配置,但是很多都不是必要的,先放一些事例需要的简要配置把 既然是IdentityServer4 所里下面的例子我 直接放到 Linux上 测试环境 CentOS 7 +Nginx1.9.3 ...

  7. hdoj2546 饭卡(DP,01背包)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2546 思路 首先要判断卡里的钱是不是大于等于5元,如果不足5元,直接输出余额:如果大于等于5元,则先留 ...

  8. 四、django rest_framework源码之频率控制剖析

    1 绪言 权限判定之后的下一个环节是访问频率控制,本篇我们分析访问频率控制部分源码. 2 源码分析 访问频率控制在dispatch方法中的initial方法调用check_throttles方法开始. ...

  9. zoj-1610线段树刷题

    title: zoj-1610线段树刷题 date: 2018-10-16 16:49:47 tags: acm 刷题 categories: ACM-线段树 概述 这道题是一道简单的线段树区间染色问 ...

  10. merge into issue

    ORA-30926: unable to get a stable set of rows in the source tables 一.经检查,这个错误是由于数据来源表(即语句中,using后面的f ...