入门
redis 具有客户端-服务器架构,并使用请求-响应模型。这意味着您(客户端)通过 TCP 连接连接到 Redis 服务器,默认情况下在端口 6379 上。您请求一些操作(例如某种形式的读取、写入、获取、设置或更新),服务器会为您提供响应。
可以有许多客户端与同一台服务器通信,这实际上是 Redis 或任何客户端-服务器应用程序的全部内容。每个客户端在等待服务器响应的套接字上执行(通常是阻塞的)读取。
cliinredis-cli代表命令行界面,而inserver代表redis-server运行服务器。Python/ target=_blank class=infotextkey>Python与在命令行中运行的方式相同,您可以运行redis-cli以跳转到交互式 REPL(Read Eval Print Loop),您可以在其中直接从 shell 运行客户端命令。
但是,首先,您需要启动redis-server以便有一个正在运行的 Redis 服务器可以与之通信。在开发中执行此操作的一种常见方法是在localhost(IPv4 地址127.0.0.1)上启动服务器,这是默认设置,除非您另行通知 Redis。您还可以传递redis-server配置文件的名称,这类似于将其所有键值对指定为命令行参数:
$ redis-server /etc/redis/6379.conf
31829:C 07 Mar 2019 08:45:04.030 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
31829:C 07 Mar 2019 08:45:04.030 # Redis version=5.0.3, bits=64, commit=00000000, modified=0, pid=31829, just started
31829:C 07 Mar 2019 08:45:04.030 # Configuration loaded
我们将daemonize配置选项设置为yes,因此服务器在后台运行。(否则,--daemonize yes用作 的选项redis-server。)
现在您已准备好启动 Redis REPL。redis-cli在命令行上输入。您将看到服务器的主机:端口对,后跟>提示:
127.0.0.1:6379>
这是最简单的 Redis 命令之一PING,它只是测试与服务器的连接并"PONG"在一切正常时返回:
127.0.0.1:6379> PING
PONG
Redis 命令不区分大小写,尽管它们的 Python 对应命令绝对不区分大小写。
注意:作为另一个健全性检查,您可以使用以下命令搜索 Redis 服务器的进程 ID pgrep:
$ pgrep redis-server
26983
要终止服务器,pkill redis-server请从命令行使用。在 mac OS X 上,您还可以使用redis-cli shutdown.
接下来,我们将使用一些常见的 Redis 命令并将它们与纯 Python 中的样子进行比较。
Redis 作为 Python 字典
Redis 代表远程字典服务。
“你的意思是,像 Python字典一样?” 你可能会问。
是的。从广义上讲,您可以在 Python 字典(或通用哈希表)和 Redis 的用途和用途之间得出许多相似之处:
Redis 创建者 Salvatore Sanfilippo 可能不喜欢将 Redis 数据库与普通 Python 进行比较dict。他称该项目为“数据结构服务器”(而不是诸如memcached之类的键值存储),因为值得称赞的是,Redis 支持存储除string:string之外的其他类型的key:value数据类型。但出于我们的目的,如果您熟悉 Python 的字典对象,这是一个有用的比较。
让我们通过例子来学习。我们的第一个玩具数据库(ID 为 0)将是country:capital city的映射,SET用于设置键值对:
127.0.0.1:6379> SET Bahamas Nassau
OK
127.0.0.1:6379> SET Croatia Zagreb
OK
127.0.0.1:6379> GET Croatia
"Zagreb"
127.0.0.1:6379> GET Japan
(nil)
纯 Python 中相应的语句序列如下所示:
>>>
>>> capitals = {}
>>> capitals["Bahamas"] = "Nassau"
>>> capitals["Croatia"] = "Zagreb"
>>> capitals.get("Croatia")
'Zagreb'
>>> capitals.get("Japan") # None
我们使用capitals.get("Japan")而不是capitals["Japan"]因为 Redisnil在找不到键时会返回而不是错误,这类似于 Python 的None.
Redis 还允许您在一个命令中设置和获取多个键值对,MSET并MGET分别:
127.0.0.1:6379> MSET Lebanon Beirut Norway Oslo France Paris
OK
127.0.0.1:6379> MGET Lebanon Norway Bahamas
1) "Beirut"
2) "Oslo"
3) "Nassau"
Python中最接近的东西是dict.update():
>>>
>>> capitals.update({
... "Lebanon": "Beirut",
... "Norway": "Oslo",
... "France": "Paris",
... })
>>> [capitals.get(k) for k in ("Lebanon", "Norway", "Bahamas")]
['Beirut', 'Oslo', 'Nassau']
我们使用.get()而不是.__getitem__()模仿 Redis 在找不到键时返回类似空值的行为。
作为第三个示例,该EXISTS命令执行其听起来的操作,即检查密钥是否存在:
127.0.0.1:6379> EXISTS Norway
(integer) 1
127.0.0.1:6379> EXISTS Sweden
(integer) 0
Python 有in关键字来测试相同的东西,它路由到dict.__contains__(key):
>>>
>>> "Norway" in capitals
True
>>> "Sweden" in capitals
False
这几个示例旨在使用原生 Python 展示一些常见的 Redis 命令在高级别上发生的事情。Python 示例中没有客户端-服务器组件,redis-py还没有进入图片。这只是为了通过示例展示 Redis 的功能。
以下是您见过的几个 Redis 命令及其功能 Python 等价物的摘要:
SET Bahamas Nassau
capitals["Bahamas"] = "Nassau"
GET Croatia
capitals.get("Croatia")
MSET Lebanon Beirut Norway Oslo France Paris
capitals.update(
{
"Lebanon": "Beirut",
"Norway": "Oslo",
"France": "Paris",
}
)
MGET Lebanon Norway Bahamas
[capitals[k] for k in ("Lebanon", "Norway", "Bahamas")]
EXISTS Norway
"Norway" in capitals
Python Redis 客户端库,redis-py您将在本文中很快深入探讨,它的作用有所不同。它封装了到 Redis 服务器的实际 TCP 连接,并将原始命令(作为使用REdis 序列化协议(RESP) 序列化的字节)发送到服务器。然后,它获取原始回复并将其解析回 Python 对象,例如bytes、int或什至datetime.datetime。
注意:到目前为止,您一直在通过交互式redis-cliREPL 与 Redis 服务器通信。您也可以直接发出命令,就像将脚本的名称传递给python可执行文件一样,例如python myscript.py.
到目前为止,您已经看到了一些 Redis 的基本数据类型,它们是string:string的映射。虽然这种键值对在大多数键值存储中都很常见,但 Redis 提供了许多其他可能的值类型,您将在接下来看到。
Python 与 Redis 中的更多数据类型
在启动redis-pyPython 客户端之前,还有助于基本掌握更多 Redis 数据类型。需要明确的是,所有 Redis 键都是字符串。除了到目前为止示例中使用的字符串值之外,它是可以采用数据类型(或结构)的值。
哈希是string:string的映射,称为字段值对,位于一个顶级键下:
127.0.0.1:6379> HSET realpython url "https://realpython.com/"
(integer) 1
127.0.0.1:6379> HSET realpython Github realpython
(integer) 1
127.0.0.1:6379> HSET realpython fullname "Real Python"
(integer) 1
这为一个键,设置了三个字段值对"realpython"。如果您习惯了 Python 的术语和对象,这可能会让人感到困惑。Redis 哈希大致类似于dict嵌套一层深度的 Python:
data = {
"realpython": {
"url": "https://realpython.com/",
"github": "realpython",
"fullname": "Real Python",
}
}
Redis 的字段类似于上面内部字典中每个嵌套键值对的 Python 键。Redis为保存散列结构本身的顶级数据库键保留术语键。
就像MSET基本的字符串:字符串键值对一样,散列也可以在散列值对象HMSET中设置多个对:
127.0.0.1:6379> HMSET pypa url "https://www.pypa.io/" github pypa fullname "Python Packaging Authority"
OK
127.0.0.1:6379> HGETALL pypa
1) "url"
2) "https://www.pypa.io/"
3) "github"
4) "pypa"
5) "fullname"
6) "Python Packaging Authority"
usingHMSET可能更接近于我们分配data给上面嵌套字典的方式,而不是像使用HSET.
两个额外的值类型是列表和集合,它们可以代替散列或字符串作为 Redis 值。它们在很大程度上就是它们听起来的样子,所以我不会用更多的例子来占用你的时间。散列、列表和集合都有一些特定于给定数据类型的命令,在某些情况下由它们的首字母表示:
注意: Redis 列表类型的一个值得注意的特点是它是一个链表而不是数组。这意味着追加是 O(1),而在任意索引号处进行索引是 O(N)。
以下是 Redis 中特定于字符串、哈希、列表和集合数据类型的命令的快速列表:
类型 |
命令 |
套 |
SADD, SCARD, SDIFF, SDIFFSTORE, SINTER, SINTERSTORE, SISMEMBER, SMEMBERS, SMOVE, SPOP, SRANDMEMBER, SREM, SSCAN, SUNION,SUNIONSTORE |
哈希 |
HDEL, HEXISTS, HGET, HGETALL, HINCRBY, HINCRBYFLOAT, HKEYS, HLEN, HMGET, HMSET, HSCAN, HSET, HSETNX, HSTRLEN,HVALS |
列表 |
BLPOP, BRPOP, BRPOPLPUSH, LINDEX, LINSERT, LLEN, LPOP, LPUSH, LPUSHX, LRANGE, LREM, LSET, LTRIM, RPOP, RPOPLPUSH, RPUSH,RPUSHX |
字符串 |
AppEND, BITCOUNT, BITFIELD, BITOP, BITPOS, DECR, DECRBY, GET, GETBIT, GETRANGE, GETSET, INCR, INCRBY, INCRBYFLOAT, MGET, MSET, MSETNX, PSETEX, SET, SETBIT, SETEX, SETNX, SETRANGE,STRLEN |
此表不是 Redis 命令和类型的完整图片。有更高级的数据类型的大杂烩,例如地理空间项目、排序集和HyperLogLog。在 Redis命令页面,您可以按数据结构组进行过滤。还有数据类型总结和Redis数据类型介绍。
因为我们将切换到用 Python 做事情,你现在可以使用REPL清除你的玩具数据库FLUSHDB并退出:redis-cli
127.0.0.1:6379> FLUSHDB
OK
127.0.0.1:6379> QUIT
这将带你回到你的 shell 提示符。您可以redis-server在后台运行,因为本教程的其余部分也需要它。