- Redis入門指南(第3版)
- 李子驊
- 4988字
- 2021-10-27 17:10:12
第2章 準備
“紙上得來終覺淺,絕知此事要躬行。”
——陸游《冬夜讀書示子聿》
學習Redis最好的辦法就是動手嘗試它。在介紹Redis的核心內容之前,本章先來介紹一下如何安裝和運行Redis,以及Redis的基礎知識,使讀者可以在之后的章節中一邊學習一邊實踐。
2.1 安裝Redis
安裝Redis是開始Redis學習之旅的第一步。在安裝Redis前需要了解Redis的版本規則,以選擇最適合自己的版本,Redis約定次版本號(即第一個小數點后的數字)為偶數的版本是穩定版(如5.0版、6.2版),為奇數的版本是非穩定版(如5.3版、6.1版),生產環境下一般需要使用穩定版本。本書的內容基于 6.0 版編寫,同時絕大部分內容也適用于以前的版本。對于部分只在最新版才有的特性,本書會做特別說明。
2.1.1 在POSIX中安裝
Redis兼容大部分POSIX操作系統,包括Linux、macOS和BSD等,在這些操作系統中,可以直接下載Redis源代碼并進行編譯安裝,以獲得最新的穩定版本。Redis最新穩定版本的源代碼可以從Redis官方網站下載。
下載安裝包后解壓即可使用make命令完成編譯,完整的命令如下:
wget http://download.redis.io/redis-stable.tar.gz tar xzf redis-stable.tar.gz cd redis-stable make
Redis沒有其他外部依賴,安裝過程很簡單。編譯后在Redis源代碼目錄的src文件夾中可以找到若干可執行程序,最好在編譯后直接執行make install命令來將這些可執行程序復制到/usr/local/bin目錄中,以便以后執行程序時可以不用輸入完整的路徑。
在實際運行Redis前,推薦使用make test命令測試Redis是否編譯正確,尤其是在編譯一個不穩定版本的Redis時。
提示
除了手動編譯,還可以使用操作系統中的軟件包管理器來安裝Redis,但目前大多數軟件包管理器中的Redis的版本都比較古老。考慮到 Redis 的每次升級都提供了對以往版本的問題修復和性能提升,使用最新版本的 Redis 往往可以提供更加穩定的體驗。如果希望享受包管理器帶來的便利,在安裝前請確認您使用的軟件包管理器中Redis的版本并了解該版本與最新版之間的差異。Redis官網的“Problems with Redis? This is a good starting point.”中列舉了一些在以往版本中存在的已知問題。
另外,Ubuntu用戶可以使用官方提供的倉庫 redislabs/redis 來方便地安裝最新的穩定版本:
sudo add-apt-repository ppa:redislabs/redis sudo apt-get update sudo apt-get install redis
2.1.2 在macOS中安裝
macOS下的軟件包管理工具Homebrew提供了較新版本的Redis包,所以我們可以直接使用它們來安裝Redis,省去了像其他POSIX操作系統那樣需要手動編譯的麻煩。下面以使用Homebrew安裝Redis為例。
1.安裝Homebrew
在終端輸入如下命令即可安裝Homebrew:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/ install.sh)"
也可以參照Homebrew的官方網站獲取其他的安裝方式。如果之前安裝過Homebrew,請執行brew update來更新Homebrew,以便安裝較新版的Redis。
2.通過Homebrew安裝Redis
使用brew install軟件包名可以安裝相應的包,此處執行brew install redis來安裝Redis:
$ brew install redis ==> Downloading https:// *****redis-6.0.9.big_sur.bottle.tar.gz ==> Downloading from https:// *****redis-6.0.9.big_sur.bottle.tar ######################################################################## 100.0% ==> Reinstalling redis ==> Pouring redis-6.0.9.big_sur.bottle.tar.gz ==> Caveats To have launchd start redis now and restart at login: brew services start redis Or, if you don't want/need a background service you can just run: redis-server /usr/local/etc/redis.conf ==> Summary /usr/local/Cellar/redis/6.0.9: 13 files, 3.9MB
在安裝結果中,Homebrew貼心地提示了如何啟動Redis并讓其隨操作系統自動運行:
brew services start redis
以此方式運行的Redis會加載位于/usr/local/etc/redis.conf的配置文件,關于配置文件的內容會在2.4節中介紹。
2.1.3 在Windows中安裝
Redis官方不支持Windows。有趣的是,微軟[1]早在2011年向Redis提交了一個補丁,以使Redis可以在Windows下編譯運行,但被Salvatore Sanfilippo拒絕了,原因是Linux在服務器領域中已經得到了廣泛的使用,這讓Redis能在Windows下運行相比而言顯得不那么重要。并且Redis使用了如寫時復制等很多操作系統相關的特性,要使這些特性兼容Windows會耗費太多的精力而影響Redis其他功能的開發。盡管如此,微軟還是發布了一個可以在Windows運行的Redis分支[2],不過目前已經停止維護。
如果想使用Windows學習或測試,目前有如下一些方法。
(1)在 Windows 中安裝虛擬機(如VirtualBox),并在其中的 Linux 操作系統安裝Redis。
(2)類似于方法(1),可以直接使用Docker來安裝和運行Redis。
(3)Windows 10提供了適用于Linux的Windows子系統(Windows Subsystem for Linux,WSL),可以在其上安裝Redis。
(4)使用Memurai。Memurai是一個第三方開發商維護的專門運行于Windows的Redis版本。這個開發商在2013年時就開始參與前文提到的微軟維護的分支的開發,后來獨立出Memurai。Memurai是商業軟件,以開發為目的使用是免費的,但是如果用于生產環境則需要付費。
這里以方法(3)為例,簡要介紹一下安裝方法。
(1)參照微軟官方文檔[3],啟用WSL。
(2)在Microsoft Store中安裝一個支持的Linux發行版,考慮到前文提到的Redis官方提供了Ubuntu的官方倉庫,Ubuntu是一個比較好的選擇。
(3)接下來的步驟可以參照2.1.1節,這里不再贅述。
注意
Redis官方并沒有針對Windows提供第一方的支持,所以本節提到的前3種方法只適合在開發環境中運行和使用Redis。運行Redis的最佳操作系統仍然是Linux和macOS,官方推薦的生產操作系統是Linux。
2.2 啟動和停止Redis
安裝完Redis后的下一步就是啟動它,本節將分別介紹在開發環境和生產環境中啟動Redis的方法以及正確停止Redis的步驟。
在這之前首先需要了解Redis包含哪些可執行文件,表2-1中列出了這些文件名以及對應的說明。如果在編譯后執行了make install命令,這些文件會被復制到/usr/local/bin目錄下,所以在命令行中直接輸入文件名即可執行。
表2-1 Redis可執行文件及說明
我們最常使用的兩個文件是redis-server和redis-cli,其中redis-server是Redis的服務器,啟動Redis即執行redis-server;而redis-cli是Redis自帶的Redis命令行客戶端,是學習Redis的重要工具,在2.3節中會詳細介紹它。
2.2.1 啟動Redis
啟動Redis有直接啟動和通過初始化腳本啟動兩種方式,分別適用于開發環境和生產環境。
1.直接啟動
直接執行redis-server即可啟動Redis,十分簡單:
$ redis-server 823:C # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 823:C # Redis version=6.2.1, bits=64, commit=00000000, modified=0, pid=823, just started 823:M * Increased maximum number of open files to 10032 (it was originally set to 256). 823:M * monotonic clock: POSIX clock_gettime ... 823:M # Server initialized 823:M * Ready to accept connections
Redis服務器默認使用6379號端口,通過--port參數可以自定義端口號:
$ redis-server --port 6380
2.通過初始化腳本啟動
在Linux操作系統中可以通過初始化腳本啟動Redis,使Redis能隨操作系統自動運行,在生產環境中推薦使用此方法啟動 Redis,這里以Ubuntu和Debian發行版為例進行介紹。在Redis源代碼目錄的utils文件夾中有一個名為redis_init_script的初始化腳本文件,其內容如下:
#!/bin/sh # # Simple Redis init.d script conceived to work on Linux systems # as it does use of the /proc filesystem. REDISPORT=6379 EXEC=/usr/local/bin/redis-server CLIEXEC=/usr/local/bin/redis-cli PIDFILE=/var/run/redis_${REDISPORT}.pid CONF="/etc/redis/${REDISPORT}.conf" case "$1" in start) if [ -f $PIDFILE ] then echo "$PIDFILE exists, process is already running or crashed" else echo "Starting Redis server..." $EXEC $CONF fi ;; stop) if [ ! -f $PIDFILE ] then echo "$PIDFILE does not exist, process is not running" else PID=$(cat $PIDFILE) echo "Stopping ..." $CLIEXEC -p $REDISPORT shutdown while [ -x /proc/${PID} ] do echo "Waiting for Redis to shutdown ..." sleep 1 done echo "Redis stopped" fi ;; *) echo "Please use start or stop as first argument" ;; esac
我們需要配置Redis的運行方式和持久化文件、日志文件的存儲位置等,具體步驟如下。
(1)配置初始化腳本。首先將初始化腳本復制到/etc/init.d目錄下,文件名為redis_端口號,其中端口號表示要讓Redis監聽的端口號,客戶端通過該端口連接Redis。然后修改腳本第6行的REDISPORT變量的值為同樣的端口號。
(2)建立需要的文件夾。建立表2-2中列出的目錄。
表2-2 需要建立的目錄及說明
(3)修改配置文件。首先將配置文件模板(見2.4節)復制到/etc/redis目錄下,以端口號命名(如“6379.conf”),然后按照表2-3對其中的部分參數進行編輯。
表2-3 需要修改的配置及說明
現在就可以使用/etc/init.d/redis_端口號start來啟動Redis了,而后需要執行下面的命令使Redis隨操作系統自動啟動:
$ sudo update-rc.d redis_端口號 defaults
2.2.2 停止Redis
考慮到Redis有可能正在將內存中的數據同步到硬盤中,強行終止Redis進程可能會導致數據丟失。正確停止Redis的方式應該是向Redis發送SHUTDOWN命令,方法為:
$ redis-cli SHUTDOWN
當Redis接收到SHUTDOWN命令后,會先斷開所有客戶端連接,然后根據配置執行持久化,最后完成退出。
Redis可以妥善處理SIGTERM信號,所以使用kill Redis進程的PID也可以正常停止Redis,效果與發送SHUTDOWN命令一樣。
2.3 Redis命令行客戶端
還記得我們剛才編譯出的redis-cli文件嗎?redis-cli(Redis Command Line Interface)是Redis自帶的基于命令行的Redis客戶端,也是我們學習和測試Redis的重要工具,本書后面會使用它來講解Redis各種命令的用法。
本節將會介紹如何通過redis-cli向Redis發送命令,并且對Redis命令返回值的不同類型進行簡單介紹。
2.3.1 發送命令
通過redis-cli向Redis發送命令有兩種方式,第一種方式是將命令作為redis-cli的參數執行,例如在2.2.2節中用過的redis-cli SHUTDOWN。redis-cli執行時會自動按照默認配置(服務器IP地址為127.0.0.1,端口號為6379)連接Redis,通過參數-h和-p可以分別自定義IP地址和端口號:
$ redis-cli -h 127.0.0.1 -p 6379
Redis提供了PING命令來測試客戶端與Redis的連接是否正常,如果連接正常會收到回復PONG,例如:
$ redis-cli PING PONG
第二種方式是不附帶參數執行redis-cli,這樣會進入交互模式,可以自由輸入命令,例如:
$ redis-cli redis 127.0.0.1:6379> PING PONG redis 127.0.0.1:6379> ECHO hi "hi"
這種方式在要輸入多條命令時比較方便,也是本書中主要采用的方式。為簡便起見,后文中我們將用redis>表示redis 127.0.0.1:6379>。
2.3.2 命令返回值
在大多數情況下,執行一條命令后我們往往會關心命令的返回值,如1.2.4節中的HGET命令的返回值就是我們需要的指定鍵的title字段的值。命令的返回值有5種類型,對于每種類型,redis-cli的展現結果都不同,下面分別說明。
1.狀態回復
狀態回復(status reply)是最簡單的一種回復,例如,向Redis發送SET命令設置某個鍵的值時,Redis會回復狀態OK表示設置成功。另外,之前演示的對PING命令的回復PONG也是狀態回復。狀態回復直接顯示狀態信息,如:
redis> PING PONG
2.錯誤回復
當出現命令不存在或命令格式有錯誤等情況時,Redis會返回錯誤回復(error reply)。錯誤回復以(error)開頭,并在后面跟上錯誤消息。如執行一條不存在的命令:
redis> ERRORCOMMAND (error) ERR unknown command 'ERRORCOMMAND'
在最早的版本中,所有的錯誤消息都是以“ERR”開頭的,而在2.8版以后,部分錯誤消息會以具體的錯誤類型開頭,如:
redis> LPUSH key 1 (integer) 1 redis> GET key (error) WRONGTYPE Operation against a key holding the wrong kind of value
這里錯誤消息開頭的WRONGTYPE就表示類型錯誤,這個改進使得在調試時能更容易地知道遇到的是哪種類型的錯誤。
3.整數回復
Redis雖然沒有整數類型,但是提供了一些用于整數操作的命令,如遞增鍵值的INCR命令會以整數形式返回遞增后的鍵值。除此之外,其他一些命令也會返回整數,如可以獲取當前數據庫中鍵的數量的DBSIZE命令等。整數回復(integer reply)以(integer)開頭,并在后面跟上整數數據:
redis> INCR foo (integer) 1
4.字符串回復
字符串回復(bulk reply)是最常見的一種回復類型,當請求一個字符串類型鍵的鍵值或一個其他類型鍵中的某個元素時,就會得到一個字符串回復。字符串回復以雙引號包裹:
redis> GET foo "1"
特殊情況是當請求的鍵值不存在時得到的結果為空,顯示為(nil)。如:
redis> GET noexists (nil)
5.多行字符串回復
多行字符串回復(multi-bulk reply)同樣很常見,如當請求一個非字符串類型鍵的元素列表時,就會收到多行字符串回復。多行字符串回復中的每行字符串都以一個序號開頭,如:
redis> KEYS * 1) "bar" 2) "foo"
提示
KEYS命令的作用是獲取數據庫中符合指定規則的鍵名,由于讀者的Redis中還沒有存儲數據,因此得到的返回值應該是(empty list or set)。3.1節會具體介紹KEYS命令,此處讀者只需了解多行字符串回復的格式。
2.4 配置
在2.2.1節中,我們通過redis-server的啟動參數port設置了Redis的端口號,除此之外,Redis還支持其他配置選項,如是否開啟持久化、日志級別等。由于可以配置的選項較多,通過啟動參數設置這些選項并不方便,因此Redis支持通過配置文件來設置這些選項。啟用配置文件的方法是在啟動時將配置文件的路徑作為啟動參數傳遞給redis-server,如:
$ redis-server /path/to/redis.conf
通過啟動參數傳遞同名的配置選項會覆蓋配置文件中相應的參數,就像這樣:
$ redis-server /path/to/redis.conf --loglevel warning
Redis提供了一個配置文件的模板文件redis.conf,位于源代碼目錄的根目錄下。
除此之外,還可以在Redis運行時通過CONFIG SET命令在不重新啟動Redis的情況下動態修改部分Redis配置。就像這樣:
redis> CONFIG SET loglevel warning OK
并不是所有的配置都可以使用CONFIG SET命令修改,附錄B列出了哪些配置能夠使用該命令修改。同樣,在執行的時候也可以使用CONFIG GET命令獲得Redis當前的配置情況,如:
redis> CONFIG GET loglevel 1) "loglevel" 2) "warning"
其中,第一行字符串回復表示的是選項名,第二行是選項值。
2.5 多數據庫
第1章介紹過Redis是一個字典結構的存儲服務器,而實際上一個Redis實例提供了多個用來存儲數據的字典,客戶端可以指定將數據存儲在哪個字典中。這與我們熟知的在一個關系數據庫實例中可以創建多個數據庫類似,所以可以將其中的每個字典都理解成一個獨立的數據庫。
每個數據庫對外都以一個從0開始的遞增數字命名,Redis默認支持16個數據庫,可以通過配置參數databases來修改這一數字。客戶端與Redis建立連接后會自動選擇0號數據庫,不過可以隨時使用SELECT命令更換數據庫,如選擇1號數據庫:
redis> SELECT 1 OK redis [1]> GET foo (nil)
然而,這些以數字命名的數據庫又與我們理解的數據庫有所區別。首先,Redis不支持自定義數據庫的名字,每個數據庫都以編號命名,開發者必須自己記錄哪些數據庫存儲了哪些數據。其次,Redis不支持為每個數據庫設置不同的訪問密碼,所以一個客戶端要么可以訪問全部數據庫,要么不能訪問任何數據庫。最后也是最重要的一點是,多個數據庫之間并不是完全隔離的,例如FLUSHALL命令可以清空一個Redis實例中的所有數據庫中的數據。綜上所述,這些數據庫更像一種命名空間,而不適宜存儲不同應用的數據。例如可以使用0號數據庫存儲某個應用的生產環境中的數據,使用1號數據庫存儲該應用的測試環境中的數據,但不適宜使用0號數據庫存儲A應用的數據而使用1號數據庫存儲B應用的數據,不同的應用應該使用不同的Redis實例存儲數據。由于Redis非常輕量級,一個空Redis實例占用的內存只有1 MB左右,因此不用擔心多個Redis實例會占用很多內存。
[1] 微軟開放技術有限公司(Microsoft Open Technologies Inc.)專注于參與開源項目、開放標準工作組以及提出倡議。
[2] 可在GitHub官網搜索“microsoftarchive/redis”獲取。
[3] 適用于Windows 10的文檔為Windows Subsystem for Linus Installation Guide for Windows 10。