入門
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 數據庫包含鍵:值對并支持諸如 、 和 等命令GET,SET以及DEL數百個附加命令。
- Redis鍵始終是字符串。
- Redis值可能是許多不同的數據類型。我們將在本教程中介紹一些更重要的值數據類型:string、list、hashes和sets。一些高級類型包括地理空間項目和新的流類型。
- 許多 Redis 命令在恒定的 O(1) 時間內運行,就像從 Pythondict或任何哈希表中檢索值一樣。
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 值。它們在很大程度上就是它們聽起來的樣子,所以我不會用更多的例子來占用你的時間。散列、列表和集合都有一些特定于給定數據類型的命令,在某些情況下由它們的首字母表示:
- 哈希:對哈希進行操作的命令以 開頭H,例如HSET、HGET或HMSET。
- 集合:對集合進行操作的命令以 開頭S,例如SCARD,它獲取與給定鍵對應的集合值處的元素數。
- 列表:對列表進行操作的命令以Lor開頭R。示例包括LPOP和RPUSH。LorR表示對列表的哪一側進行操作。一些列表命令也以 a 開頭B,表示阻塞。阻塞操作不會讓其他操作在執行時中斷它。例如,BLPOP在列表結構上執行阻塞左彈出。
注意: 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在后臺運行,因為本教程的其余部分也需要它。