programming_python

第十四章 Redis编程-Python篇

1 概述

在介绍完Redis服务器的原理与内部结构之后,接下来我们将介绍如何在程序中高效使用Redis服务器。与关系型数据库编程类似,应用程序是作为客户端与Redis服务器通信的。

Redis客户端与服务器端的通信协议是独立于编程语言的。换句话说,使用任何语言都能实现Redis的客户端。因此,对于每一种流行的编程语言,Redis都有相应的客户端。我们在下面列举几个Redis开发人员推荐使用的客户端。本文将重点介绍Python客户端的使用方法(Python 3.7)。对Java客户端感兴趣的读者可参考第十三章

编程语言客户端库
Chiredis, hiredis-vip
GoRadix, Redigo
JavaJedis, Lettuce, Redisson
Pythonredis-py, walrus
Scalascala-redis

可点击查看更多支持的编程语言和客户端。

2 环境准备

2.1 安装Redis服务器

如果读者运行的是Ubuntu Linux服务器的话,可以使用如下命令安装Redis服务器。如下示例使用的是Ubuntu 20.04 LTS版本。Ubuntu服务器可以在这里免费下载。

> sudo apt-get update
> sudo apt-get install redis-server

安装完毕后,我们可以使用如下命令启动Redis服务器,并测试Redis服务器是否安装成功。如果能够成功发送ping命令,并收到响应PONG,则说明Redis系统安装成功。

> redis-server
> redis-server --version
Redis server v=5.0.7 sha=00000000:0 malloc=jemalloc-5.2.1 bits=64 build=636cde3b5c7a3923
> redis-cli
redis 127.0.0.1:6379> ping
PONG

2.2 安装Redis-py

如果读者使用Python 3的话,可以在Ubuntu下安装python3-redis。

sudo apt-get install python3-redis

3 Redis-py使用方法

3.1 Redis-py的基本使用方法

Redis-py的用法很简单,客户端需要首先需要导入redis包,并创建一个Redis对象,然后再使用该对象操作Redis数据库。

在创建Redis对象时,如果是连接本机运行的Redis服务器,并且使用默认接口的话,可以直接使用默认构造函数Redis()。如果连接的是远程数据库,或者该数据库未使用默认接口的话,可使用Redis(host, port)构造函数创建对象。

在获得了Redis对象实例之后,就可以使用set()/get()成员方法设置和查询数据了。如下面的示例代码所示,该程序连接了本机的Redis服务器,并向其设置了name/value对。最后,程序向Redis服务器查询name对应的值。

import redis

# 连接本地的Redis服务器
redis = redis.Redis(host='localhost', port=6379)

# 向Redis数据库创建name/value的字符串对
redis.set('name', 'value')

# 向Redis服务器查询字符串name对应的value值
redis.get('name')

3.2 Redis-py基本数据结构的使用方法

从上面的代码可以看出,Redis-py对象通过get()/set()方法查询和设置字符串对。我们在下面的代码中展示链表、集合、哈希、有序集合的使用方法。它们都有对应的成员方法支持数据创建、查询和删除。读者应该能从成员方法的名称推测出它们的功能,因为它们与相应的Redis命令的名称相同。

import redis

# 连接本地的Redis服务器
redis = redis.Redis()

# 链表操作示例
redis.rpush('listname', 'firstElement')  # 从链表尾部添加元素firstElement
redis.rpush('listname', 'secondElement') # 从链表尾部添加元素secondElement
lastElement = redis.rpop('listname')  # 从链表尾部移除一个元素
print(lastElement)  # 打印secondElement

# 集合操作示例
redis.sadd('primeNumberSet', '2') # 向质数集合添加数字2
redis.sadd('primeNumberSet', '3') # 向质数集合添加数字3
primeNumbers = redis.smembers('primeNumberSet') # 查询质数集合中所有的元素
exists = redis.sismember('primeNumberSet', '2') # 查询数字2是否在质数集合中

# 哈希表操作示例
redis.hset('dictName', 'name1', 'value1') # 向哈希表dictName插入name1/value1对
redis.hset('dictName', 'name2', 'value2') # 向哈希表dictName插入name2/value2对
allKeyValues = redis.hgetall('dictName') # 查询哈希表dictName中所有的key/value对
value2 = redis.hget('dictName', 'name2') # 向哈希表dictName中查询name2对应的value值

# 有序集合示例
redis.zadd('confidenceOfProgLang', 'java',  100.0)  # 向集合添加元素java,分数100.0
redis.zadd('confidenceOfProgLang', 'python', 90.0) # 向集合添加元素python,分数90.0
confidenceInJava = redis.zscore('confidenceOfProgLang', 'java') # 查询java语言的分数
print(confidenceInJava)

3.3 Redis-py的事务处理

和关系型数据库类似,Redis也支持事务处理。使用事务处理功能能为客户端提供:

  1. 原子性(Atomicity)。即在一个事务中,要么所有的操作全部顺序执行,要么全部不执行;
  2. 事务隔离(Isolation)。即当一个客户端在运行一个事务时,Redis确保不会将其他客户端的指令夹杂在事务中同时处理。

下面的例子展示了客户端程序在一个事务中创建了两个key/value对。事务对象是由调用multi()方法创建的。

import redis

# 连接本地的Redis服务器
redis = redis.Redis()

# 创建一个事务对象
pipeline = redis.pipeline()
pipeline.multi()
pipeline.set('name1', 'value1')
pipeline.set('name2', 'value2')
pipeline.execute()

3.4 Pipelining(流水线)

Pipeline是Redis数据库的一个重要特性。当客户端向服务器发送一条命令之后,客户端并不需要等待命令的应答才能发送下一条命令。多条命令可以一次性下发,然后,再一次性读取它们的结果。Redis服务器会按照收到命令的顺序返回应答。

例如,下面的程序示例中,客户端程序使用Pipeline对象下发了两条命令。这两条命令向链表listname添加两个元素。程序需要调用execute()成员方法以等待接收所有命令的执行结果。

import redis

# 连接本地的Redis服务器
redis = redis.Redis()

# 创建一个Pipeline对象
pipeline = redis.pipeline()

pipeline.rpush('listname', 'firstElement')  # 使用Pipeline向链表添加元素firstElement
pipeline.rpush('listname', 'secondElement') # 使用Pipeline向链表添加元素secondElement
pipeline.execute() # 等待所有命令的结果

3.5 发布者/订阅者

发布者/订阅者模式是由发布者和订阅者两个角色组成的。下面的第一个程序扮演的是订阅者。它通过使用subscribe()成员方法订阅了频道littlewaterdrop_study。subscribe()成员方法接收两个参数。第一个参数是JedisPubSub类型的对象。第二个参数是频道名称。JedisPubSub是一个抽象类。它包含了一些空的成员方法(),以响应不同的事件。其中,onMessage()成员方法就是一个接收新消息的响应函数。每当发布者向频道推送一条新的消息后,订阅者的onMessage()方法就会被调用,新消息的内容会以参数的方式传入进来。

import redis

# 连接本地的Redis服务器
redis = redis.Redis()

pubsub = redis.pubsub()
pubsub.subscribe('littlewaterdrop_study')

print(pubsub.get_message()['data'])

发布者的逻辑简单一些,发布者只需要向频道发送消息即可。下面的源代码示例使用publish()成员方法向频道littlewaterdrop_study发送了一条消息"Welcome to Little Waterdrop"。

import redis

# 连接本地的Redis服务器
redis = redis.Redis()

redis.publish('littlewaterdrop_study', 'Welcome to Little Waterdrop')

4 小结

本章首先介绍了Redis客户端支持的流行的编程语言以及函数库。然后,使用了Redis-py库作为Python客户端的一个例子,讲述了Redis编程的常用场景。

上一章

注册用户登陆后可留言

Copyright  2019 Little Waterdrop, LLC. All Rights Reserved.