一文帶你掌握 Redis
一、摘要
談起 Redis,相信大家都不會陌生,做過云平臺開發(fā)的程序員多多少少會接觸到它,Redis 英文全稱:?Remote Dictionary Server,也被稱之為遠(yuǎn)程字典服務(wù)。
從官方的定義看,Redis 是一款開源的,遵守 BSD 協(xié)議,使用 C 語言開發(fā)的 key-value 存儲系統(tǒng)。簡單的說,它是一款跨平臺的非關(guān)系型數(shù)據(jù)庫,支持優(yōu)先內(nèi)存存儲,并提供多種語言的 API 客戶端。
Redis 由一個叫 Salvatore Sanfilippo 的人開發(fā)而聞名世界,此人來自意大利的西西里島,網(wǎng)名叫 antirez,如果你有興趣,可以去他的博客逛逛,地址是 antirez.com。
不過從 2010 年起,Redis 的開發(fā)工作由 VMware 主持,到了 2013 年后,Redis 的開發(fā)由 Pivotal 贊助。
Redis 是當(dāng)下互聯(lián)網(wǎng)技術(shù)中使用最為廣泛的緩存中間件之一,隨著它在新浪微博中的使用而逐漸風(fēng)靡國內(nèi)。
雖然開源軟件市場上也有很多優(yōu)秀的緩存服務(wù)中間件,比如 memcache,但是和 redis 對比起來,redis 還是顯得格外的突出,優(yōu)勢如下:
- 性能極高:Redis 能讀的速度是 110000 次/s,寫的速度是 81000次/s
- 數(shù)據(jù)類型豐富:支持 String,Hash,List,Set,Sorted Set 等數(shù)據(jù)類型的操作
- 支持原子性操作:Redis 的每條命令操作都是原子性的,Redis 的操作之所以是原子性的,是因?yàn)槊織l命令的執(zhí)行都是單線程的,不存在線程競爭問題
- 存儲方式多樣化:memecache 把數(shù)據(jù)全部存在內(nèi)存之中,斷電后會掛掉;redis 支持?jǐn)?shù)據(jù)的持久化,同時(shí)也支持?jǐn)?shù)據(jù)的備份,即 master-slave 模式的數(shù)據(jù)備份
- 功能豐富:Redis 還支持 publish/subscribe,通知,key 過期等等特性
在分布式的架構(gòu)環(huán)境下,Redis 基本上是缺一不可的緩存中間件,它能很好的解決服務(wù)與服務(wù)之間數(shù)據(jù)共享的問題,并且性能不受影響。
說了這么多,如何使用呢?我們一起來看看!
二、服務(wù)安裝
2.1、Windows 環(huán)境
因?yàn)?redis 目前官方只支持 LINUX 系統(tǒng),因此沒有 Windows 版本的軟件包,但是好在微軟團(tuán)隊(duì)維護(hù)了開源的 windows 版本,雖然更新不算及時(shí),但是對于普通測試使用足夠了。
2.1.1、服務(wù)器安裝
如果當(dāng)前操作系統(tǒng)是 Windows 系統(tǒng),訪問如下的地址,獲取對應(yīng)的下載鏈接。
根據(jù)系統(tǒng)平臺的實(shí)際情況選擇,這里我們下載Redis-x64-xxx.zip壓縮包到 C 盤,解壓后,將文件夾重新命名為redis。
打開文件夾,內(nèi)容如下:
然后,打開一個 cmd 窗口,使用 cd 命令切換目錄到C:\redis,并且輸入如下命令:
出現(xiàn)以上界面,表示??redis?
?服務(wù)器已經(jīng)成功啟動了。
2.1.2、客戶端測試
如果想用安裝包里面的客戶端腳本測試一下服務(wù),可以這樣操作。
另啟一個 cmd 窗口,原來的窗口不要關(guān)閉,不然就無法訪問服務(wù)端了。
使用 cd 命令切換目錄到C:\redis,并且輸入如下命令:
連接到服務(wù)器之后,輸入寫命令和取命令,相關(guān)命令如下:
2.2、Linux 環(huán)境
如果當(dāng)前操作系統(tǒng)是 Linux 系統(tǒng),訪問如下的官方地址,獲取最新的下載鏈接。
2.2.1、服務(wù)器安裝
本教程使用的最新文檔版本為 6.2.6,下載并安裝:
執(zhí)行完make命令后,redis-6.2.6目錄下會出現(xiàn)編譯后的 redis 服務(wù)程序 redis-server,還有用于測試的客戶端程序 redis-cli,兩個程序位于安裝目錄 src 目錄下。
執(zhí)行下面的腳本,啟動 redis 服務(wù)器。
需要注意的地方是,這種方式啟動 redis 使用的是默認(rèn)配置,也可以通過參數(shù)告訴 redis 使用指定配置文件來啟動服務(wù),其中??redis.conf?
?是一個默認(rèn)的配置文件,我們可以根據(jù)需要使用自己的自定義配置文件。
當(dāng)出現(xiàn)Ready to accept connections時(shí),表示服務(wù)已經(jīng)啟動成功。
2.2.2、客戶端測試
同樣的,如果想用安裝包里面的客戶端腳本測試一下服務(wù),新創(chuàng)建一個命令窗口,這樣操作。
2.2.3、參數(shù)配置
可能有的同學(xué)會發(fā)出一個疑問,如何將 Redis 改成后臺服務(wù)?
也就是將窗體關(guān)閉也能正常提供服務(wù),答案就藏在redis.conf這個配置文件里。
打開redis.conf文件,常用配置如下:
修改配置,然后重啟服務(wù)即可生效,操作如下:
2.2.3、配置詳解
redis.conf詳細(xì)配置項(xiàng)說明如下:
配置參數(shù) | 說明 |
bind 127.0.0.1 | 如果是內(nèi)網(wǎng)可以直接綁定 127.0.0.1, 或者忽略, 0.0.0.0是外網(wǎng) |
port 6379 | 指定 Redis 監(jiān)聽端口,默認(rèn)端口為 6379 |
protected-mode yes | 是否運(yùn)行遠(yuǎn)程訪問,默認(rèn)是yes |
daemonize no | Redis 默認(rèn)不是以守護(hù)進(jìn)程的方式運(yùn)行,可以通過該配置項(xiàng)修改,使用 yes 啟用守護(hù)進(jìn)程 |
databases 16 | 設(shè)置數(shù)據(jù)庫的數(shù)量,默認(rèn)數(shù)據(jù)庫為0,可以使用SELECT 命令在連接上指定數(shù)據(jù)庫id |
requirepass foobared | 設(shè)置 Redis 連接密碼,如果配置了連接密碼,客戶端在連接 Redis 時(shí)需要通過 AUTH password 命令提供密碼,默認(rèn)關(guān)閉 |
timeout 300 | 當(dāng)客戶端閑置多長秒后關(guān)閉連接,如果指定為 0 ,表示關(guān)閉該功能 |
maxclients 128 | 設(shè)置同一時(shí)間最大客戶端連接數(shù),默認(rèn)無限制,Redis 可以同時(shí)打開的客戶端連接數(shù)為 Redis 進(jìn)程可以打開的最大文件描述符數(shù),如果設(shè)置 maxclients 0,表示不作限制。當(dāng)客戶端連接數(shù)到達(dá)限制時(shí),Redis 會關(guān)閉新的連接并向客戶端返回 max number of clients reached 錯誤信息 |
maxmemory ? | 指定 Redis 最大內(nèi)存限制,Redis 在啟動時(shí)會把數(shù)據(jù)加載到內(nèi)存中,達(dá)到最大內(nèi)存后,Redis 會先嘗試清除已到期或即將到期的 Key,當(dāng)此方法處理 后,仍然到達(dá)最大內(nèi)存設(shè)置,將無法再進(jìn)行寫入操作,但仍然可以進(jìn)行讀取操作。Redis 新的 vm 機(jī)制,會把 Key 存放內(nèi)存,Value 會存放在 swap 區(qū) |
pidfile /var/run/redis.pid | 當(dāng) Redis 以守護(hù)進(jìn)程方式運(yùn)行時(shí),Redis 默認(rèn)會把 pid 寫入 /var/run/redis.pid 文件,可以通過 pidfile 指定 |
loglevel notice | 指定日志記錄級別,Redis 總共支持四個級別:debug、verbose、notice、warning,默認(rèn)為 notice |
logfile stdout | 日志記錄方式,默認(rèn)為標(biāo)準(zhǔn)輸出,如果配置 Redis 為守護(hù)進(jìn)程方式運(yùn)行,而這里又配置為日志記錄方式為標(biāo)準(zhǔn)輸出,則日志將會發(fā)送給 /dev/null |
save ? | 指定在多長時(shí)間內(nèi),有多少次更新操作,就將數(shù)據(jù)同步到數(shù)據(jù)文件,可以多個條件配合,比如? |
rdbcompression yes | 指定存儲至本地?cái)?shù)據(jù)庫時(shí)是否壓縮數(shù)據(jù),默認(rèn)為 yes,Redis 采用 LZF 壓縮,如果為了節(jié)省 CPU 時(shí)間,可以關(guān)閉該選項(xiàng),但會導(dǎo)致數(shù)據(jù)庫文件變的巨大 |
dbfilename dump.rdb | 指定本地?cái)?shù)據(jù)庫文件名,默認(rèn)值為 dump.rdb |
dir ./ | 指定本地?cái)?shù)據(jù)庫存放目錄 |
slaveof ? | 設(shè)置當(dāng)本機(jī)為 slave 服務(wù)時(shí),設(shè)置 master 服務(wù)的 IP 地址及端口,在 Redis 啟動時(shí),它會自動從 master 進(jìn)行數(shù)據(jù)同步 |
masterauth ? | 當(dāng) master 服務(wù)設(shè)置了密碼保護(hù)時(shí),slave 服務(wù)連接 master 的密碼 |
appendonly no | 指定是否在每次更新操作后進(jìn)行日志記錄,Redis 在默認(rèn)情況下是異步的把數(shù)據(jù)寫入磁盤,如果不開啟,可能會在斷電時(shí)導(dǎo)致一段時(shí)間內(nèi)的數(shù)據(jù)丟失。因?yàn)?redis 本身同步數(shù)據(jù)文件是按上面 save 條件來同步的,所以有的數(shù)據(jù)會在一段時(shí)間內(nèi)只存在于內(nèi)存中。默認(rèn)為 no |
appendfilename appendonly.aof | 指定更新日志文件名,默認(rèn)為 appendonly.aof |
appendfsync everysec | 指定更新日志條件,共有 3 個可選值:no:表示等操作系統(tǒng)進(jìn)行數(shù)據(jù)緩存同步到磁盤(快);always:表示每次更新操作后手動調(diào)用 fsync() 將數(shù)據(jù)寫到磁盤(慢,安全);everysec:表示每秒同步一次(折中,默認(rèn)值) |
vm-enabled no | 指定是否啟用虛擬內(nèi)存機(jī)制,默認(rèn)值為 no,簡單的介紹一下,VM 機(jī)制將數(shù)據(jù)分頁存放,由 Redis 將訪問量較少的頁即冷數(shù)據(jù) swap 到磁盤上,訪問多的頁面由磁盤自動換出到內(nèi)存中 |
vm-swap-file /tmp/redis.swap | 虛擬內(nèi)存文件路徑,默認(rèn)值為 /tmp/redis.swap,不可多個 Redis 實(shí)例共享 |
vm-max-memory 0 | 將所有大于 vm-max-memory 的數(shù)據(jù)存入虛擬內(nèi)存,無論 vm-max-memory 設(shè)置多小,所有索引數(shù)據(jù)都是內(nèi)存存儲的(Redis 的索引數(shù)據(jù) 就是 keys),也就是說,當(dāng) vm-max-memory 設(shè)置為 0 的時(shí)候,其實(shí)是所有 value 都存在于磁盤。默認(rèn)值為 0 |
vm-page-size 32 | Redis swap 文件分成了很多的 page,一個對象可以保存在多個 page 上面,但一個 page 上不能被多個對象共享,vm-page-size 是要根據(jù)存儲的 數(shù)據(jù)大小來設(shè)定的,作者建議如果存儲很多小對象,page 大小最好設(shè)置為 32 或者 64bytes;如果存儲很大大對象,則可以使用更大的 page,如果不確定,就使用默認(rèn)值 |
vm-pages 134217728 | 設(shè)置 swap 文件中的 page 數(shù)量,由于頁表(一種表示頁面空閑或使用的 bitmap)是在放在內(nèi)存中的,,在磁盤上每 8 個 pages 將消耗 1byte 的內(nèi)存 |
vm-max-threads 4 | 設(shè)置訪問swap文件的線程數(shù),最好不要超過機(jī)器的核數(shù),如果設(shè)置為0,那么所有對swap文件的操作都是串行的,可能會造成比較長時(shí)間的延遲。默認(rèn)值為4 |
glueoutputbuf yes | 設(shè)置在向客戶端應(yīng)答時(shí),是否把較小的包合并為一個包發(fā)送,默認(rèn)為開啟 |
activerehashing yes | 指定是否激活重置哈希,默認(rèn)為開啟(后面在介紹 Redis 的哈希算法時(shí)具體介紹) |
include /path/to/local.conf | 指定包含其它的配置文件,可以在同一主機(jī)上多個Redis實(shí)例之間使用同一份配置文件,而同時(shí)各個實(shí)例又擁有自己的特定配置文件 |
2.3、Mac 環(huán)境
如果當(dāng)前操作系統(tǒng)是 Mac 系統(tǒng),同樣的訪問官方地址http://redis.io/download,下載最新的安裝包。
然后本地解壓,后續(xù)的操作跟??linux?
?一樣,在此就不過多的介紹了!
三、命令行客戶端
如果想要在 redis 服務(wù)上執(zhí)行命令,需要一個 redis 客戶端,而 Redis 客戶端在我們下載的的 redis 的安裝包里面,其實(shí)已經(jīng)有了。
3.1、連接 redis
Redis 客戶端的基本語法為
比如,連接本地的 redis 服務(wù)器(前提是已經(jīng)啟動成功)。
如果 redis 設(shè)置了密碼,通過AUTH命令輸入密碼即可進(jìn)入,方式如下:
如果我們想連接遠(yuǎn)程 redis 服務(wù)器,可以通過如下語法方式實(shí)現(xiàn)。
比如連接192.168.121.1,命令如下:
默認(rèn)連接的數(shù)據(jù)庫是0,如果我們想切換數(shù)據(jù)庫,可以通過如下方式實(shí)現(xiàn)切換!
如果想要關(guān)閉當(dāng)前連接,通過如下方式即可實(shí)現(xiàn)!
3.2、常用的 crud 操作
以字符串為例,增刪改查操作如下!
1、設(shè)置指定 key 的值, SET 在設(shè)置操作成功完成時(shí),返回 OK。
2、查詢指定 key 的值,操作完成時(shí),如果 key 不存在時(shí),返回 (nil)
3、檢查指定 key 的值是否存在,操作完成時(shí),若 key 存在返回 1 ,否則返回 0
4、刪除指定 key 的值,操作完成時(shí),返回被刪除 key 的數(shù)量。
5、設(shè)置 key 的過期時(shí)間,以秒為單位,操作完成時(shí),若成功返回 1 ,否則返回 0。
6、獲取 key 的剩余過期時(shí)間,以秒為單位,操作完成時(shí),當(dāng) key 不存在時(shí),返回 -2;當(dāng) key 存在但沒有設(shè)置剩余生存時(shí)間時(shí),返回 -1;否則,以秒為單位,返回 key 的剩余生存時(shí)間。
7、通過 Incr 命令,實(shí)現(xiàn)指定的 key 原子性自增操作,每執(zhí)行一次 Incr 命令,key 中儲存的數(shù)字值增一,操作完成時(shí),如果 key 不存在,那么 key 的值會先被初始化為 0,然后加 1,返回最后的結(jié)果。
當(dāng)然,也可以在設(shè)置階段,指定某個初始值數(shù)字,比如將??mykey?
?的自增初始值設(shè)置為??10?
?。
3.3、事務(wù)操作
Redis 也支持事務(wù)操作,Redis 事務(wù)可以一次執(zhí)行多個命令, 并且?guī)в幸韵氯齻€重要的保證:
- 1.批量操作在發(fā)送 EXEC 命令前被放入隊(duì)列緩存
- 2.收到 EXEC 命令后進(jìn)入事務(wù)執(zhí)行,事務(wù)中任意命令執(zhí)行失敗,其余的命令依然被執(zhí)行
- 3.在事務(wù)執(zhí)行過程,其他客戶端提交的命令請求不會插入到事務(wù)執(zhí)行命令序列中
一個事務(wù)從開始到執(zhí)行會經(jīng)歷以下三個階段:
- 1.開始事務(wù)
- 2.命令入隊(duì)
- 3.執(zhí)行事務(wù)
以某個事務(wù)操作為例, 我們先以 MULTI 開始一個事務(wù), 然后將多個命令入隊(duì)到事務(wù)中, 最后由 EXEC 命令觸發(fā)事務(wù), 一并執(zhí)行事務(wù)中的所有命令,過程如下:
特別注意的地方是:單個 Redis 命令的執(zhí)行是原子性的,但 Redis 沒有在事務(wù)上增加任何維持原子性的機(jī)制,所以 Redis 事務(wù)的執(zhí)行并不是原子性的。
事務(wù)可以理解為一個打包的批量執(zhí)行腳本,但批量指令并非原子化的操作,中間某條指令的失敗不會導(dǎo)致前面已做指令的回滾,也不會造成后續(xù)的指令不做。
也就是說,如果在set b bbb處失敗,set a aaa已成功不會回滾,set c ccc還會繼續(xù)執(zhí)行,當(dāng)set b bbb處執(zhí)行失敗,這個事務(wù)是不會回滾的。
但是如果執(zhí)行過程中,命令不存在或者是命令參數(shù)不對,這個時(shí)候 redis 的事務(wù)執(zhí)行會失敗,并返回錯誤信息給客戶端;如果是命令邏輯上的執(zhí)行失敗,redis 的事務(wù)無法感知,會繼續(xù)執(zhí)行下去。
3.4、Lua 腳本操作
在上面我們也介紹到了,Redis 事務(wù)的執(zhí)行并不能完全保證原子性,那么如何將一批命令操作做到原子性操作呢?
Redis 支持通過 Lua 腳本來實(shí)現(xiàn)一批命令原子性操作,執(zhí)行腳本的常用命令為 EVAL。
Eval 命令的基本語法如下:
比如簡單的賦值操作如下:
比如我們給指定的key設(shè)置指定值value,并且設(shè)置過期時(shí)間60秒,實(shí)現(xiàn)原子性操作,如果操作成功就返回 1,否則返回 0,內(nèi)容如下:
獲取指定key的值,如果存在就刪除key,實(shí)現(xiàn)原子性操作,如果操作成功就返回 1,否則返回 0,內(nèi)容如下:
以上就是實(shí)現(xiàn)常用的分布式加鎖、解鎖原子性操作的 lua 腳本。
四、可視化客戶端
對于開發(fā)者來說,使用客戶端命令來操作 redis 非常不便捷,因此誕生了很多的基于 redis 的可視化客戶端,今天我們就一起來看看有哪些免費(fèi)又好用的客戶端工具。
4.1、Redis Desktop Manager
Redis Desktop Manager 應(yīng)該是現(xiàn)在使用率最廣的可視化工具了,存在時(shí)間很久,經(jīng)過了數(shù)次迭代,基于 Qt 5 開發(fā),支持跨平臺支持。
以前是免費(fèi)的,不過現(xiàn)在改成收費(fèi)工具,試用期可以有半個月的時(shí)間,最新版的訪問地址如下!
測評:界面看著比較簡潔,該有的功能都有,功能很全,key 的顯示可以支持按冒號分割的鍵名空間。
免費(fèi)版本的下載地址如下!
百度網(wǎng)盤:https://pan.baidu.com/s/1rMWR-OQnfsxJ3_HSqEE8xw
提取碼:tebu
4.2、medis2
medis2 是 mac 系統(tǒng)中使用率最高的 redis 可視化工具,布局簡潔,界面美觀,關(guān)鍵還免費(fèi),最新版的訪問地址如下!
測評:軟件顏值挺高,功能符合日常使用要求,對 key 有顏色鮮明的圖標(biāo)標(biāo)識,在key的搜索上挺方便的,可以模糊搜索出匹配的 key,漸進(jìn)式的 scan,無明顯卡頓,在搜索的體驗(yàn)上還是比較出色的,不過對操作系統(tǒng)要求很高,要求 MacOS 11.0 以上才能安裝,如果當(dāng)前你的操作系統(tǒng)低于以上,只有升級或者換別的軟件!
4.3、AnotherRedisDesktopManager
AnotherRedisDesktopManager 是一款比較穩(wěn)定簡潔的 redis UI工具,國人開發(fā),支持跨平臺,完全免費(fèi),最新版的訪問地址如下!
測評:基本的功能都有,有監(jiān)控統(tǒng)計(jì),支持暗黑主題,還支持集群的添加,是一款非常不錯的可視化客戶端。
4.4、Redis Insight
Redis Insight 是目前官方推薦的一款 redis 可視化工具,功能非常豐富,支持跨平臺,完全免費(fèi),最新版的訪問地址如下!
測評:相比于其他可視化工具,RedisInsight 實(shí)現(xiàn)的功能更強(qiáng)大、執(zhí)行效率更改,通用性更好,出了 CRUD 基本功能的支持,還支持內(nèi)存分析、指標(biāo)監(jiān)控、發(fā)布/訂閱、慢命令日志查詢等等。
五、小結(jié)
本文主要圍繞redis的一些基本知識,做了一次簡單的總結(jié),包括軟件安裝、基本命令操作、可視化客戶端介紹。