
1.摘要
Redis(REmote DIctionary Server) 是一個開源的使用ANSI C語言編寫、遵守BSD協定、支援網絡、可基于記憶體亦可持久化的日志型、Key-Value資料庫,并提供多種語言的API。
對一個産品,技術的認知,從基本的安裝和使用開始最容易獲得直覺認知。
本文包括REDIS在UBUNTU的安裝,基本指令的操作使用和不錯的參考文檔。
2. 安裝
在 Ubuntu 系統安裝 Redis 可以使用以下指令:
sudo apt-get update
sudo apt-get install redis-server
啟動 Redis:
redis-server
檢視 redis 是否啟動:
redis-cli
以上指令将打開以下終端:
redis 127.0.0.1:6379>
127.0.0.1 是本機 IP ,6379 是 redis 服務端口。現在我們輸入 PING 指令,能傳回PONG表示成功了。
3. 指令
3.1 REDIS配置
Redis 的配置檔案位于 Redis 安裝目錄下,檔案名為 redis.conf(Windows 名為 redis.windows.conf)。
你可以通過 CONFIG 指令檢視或設定配置項。
redis 127.0.0.1:6379> CONFIG GET *
redis.conf 配置項說明如下:
序号 | 配置項 | 說明 |
---|---|---|
1 | daemonize no Redis | 預設不是以守護程序的方式運作,可以通過該配置項修改,使用 yes 啟用守護程序(Windows 不支援守護線程的配置為 no ) |
2 | pidfile /var/run/redis.pid | 當 Redis 以守護程序方式運作時,Redis 預設會把 pid 寫入 /var/run/redis.pid 檔案,可以通過 pidfile 指定 |
3 | port 6379 | 指定 Redis 監聽端口,預設端口為 6379,作者在自己的一篇博文中解釋了為什麼選用 6379 作為預設端口,因為 6379 在手機按鍵上 MERZ 對應的号碼,而 MERZ 取自意大利歌女 Alessia Merz 的名字 |
4 | bind 127.0.0.1 | 綁定的主機位址 |
5 | timeout 300 | 當用戶端閑置多長時間後關閉連接配接,如果指定為 0,表示關閉該功能 |
6 | loglevel notice | 指定日志記錄級别,Redis 總共支援四個級别:debug、verbose、notice、warning,預設為 notice |
7 | logfile stdout | 日志記錄方式,預設為标準輸出,如果配置 Redis 為守護程序方式運作,而這裡又配置為日志記錄方式為标準輸出,則日志将會發送給 /dev/null |
8 | databases 16 | 設定資料庫的數量,預設資料庫為0,可以使用SELECT 指令在連接配接上指定資料庫id |
9 | save <seconds> <changes> | Redis 預設配置檔案中提供了三個條件:save 900 1 save 300 10 save 60 10000 分别表示 900 秒(15 分鐘)内有 1 個更改,300 秒(5 分鐘)内有 10 個更改以及 60 秒内有 10000 個更改。指定在多長時間内,有多少次更新操作,就将資料同步到資料檔案,可以多個條件配合 |
10 | rdbcompression yes | 指定存儲至本地資料庫時是否壓縮資料,預設為 yes,Redis 采用 LZF 壓縮,如果為了節省 CPU 時間,可以關閉該選項,但會導緻資料庫檔案變的巨大 |
11 | dbfilename dump.rdb | 指定本地資料庫檔案名,預設值為 dump.rdb |
12 | dir ./ | 指定本地資料庫存放目錄 |
13 | slaveof <masterip> <masterport> | 設定當本機為 slav 服務時,設定 master 服務的 IP 位址及端口,在 Redis 啟動時,它會自動從 master 進行資料同步 |
14 | masterauth <master-password> | 當 master 服務設定了密碼保護時,slav 服務連接配接 master 的密碼 |
15 | requirepass foobared | 設定 Redis 連接配接密碼,如果配置了連接配接密碼,用戶端在連接配接 Redis 時需要通過 AUTH <password> 指令提供密碼,預設關閉 |
16 | maxclients 128 | 設定同一時間最大用戶端連接配接數,預設無限制,Redis 可以同時打開的用戶端連接配接數為 Redis 程序可以打開的最大檔案描述符數,如果設定 maxclients 0,表示不作限制。當用戶端連接配接數到達限制時,Redis 會關閉新的連接配接并向用戶端傳回 max number of clients reached 錯誤資訊 |
17 | maxmemory <bytes> | 指定 Redis 最大記憶體限制,Redis 在啟動時會把資料加載到記憶體中,達到最大記憶體後,Redis 會先嘗試清除已到期或即将到期的 Key,當此方法處理 後,仍然到達最大記憶體設定,将無法再進行寫入操作,但仍然可以進行讀取操作。Redis 新的 vm 機制,會把 Key 存放記憶體,Value 會存放在 swap 區 |
18 | appendonly no | 指定是否在每次更新操作後進行日志記錄,Redis 在預設情況下是異步的把資料寫入磁盤,如果不開啟,可能會在斷電時導緻一段時間内的資料丢失。因為 redis 本身同步資料檔案是按上面 save 條件來同步的,是以有的資料會在一段時間内隻存在于記憶體中。預設為 no |
19 | appendfilename appendonly.aof | 指定更新日志檔案名,預設為 appendonly.aof |
20 | appendfsync everysec | 指定更新日志條件,共有 3 個可選值:no:表示等作業系統進行資料緩存同步到磁盤(快)always:表示每次更新操作後手動調用 fsync() 将資料寫到磁盤(慢,安全)everysec:表示秒同步一次(折中,預設值) |
21 | vm-enabled no | 指定是否啟用虛拟記憶體機制,預設值為 no,簡單的介紹一下,VM 機制将資料分頁存放,由 Redis 将通路量較少的頁即冷資料 swap 到磁盤上,通路多的頁面由磁盤自動換出到記憶體中(在後面的文章我會仔細分析 Redis 的 VM 機制) |
22 | vm-swap-file /tmp/redis.swap | 虛拟記憶體檔案路徑,預設值為 /tmp/redis.swap,不可多個 Redis 執行個體共享 |
23 | vm-max-memory 0 | 将所有大于 vm-max-memory 的資料存入虛拟記憶體,無論 vm-max-memory 設定多小,所有索引資料都是記憶體存儲的(Redis 的索引資料 就是 keys),也就是說,當 vm-max-memory 設定為 0 的時候,其實是所有 value 都存在于磁盤。預設值為 0 |
24 | vm-page-size 32 | Redis swap 檔案分成了很多的 page,一個對象可以儲存在多個 page 上面,但一個 page 上不能被多個對象共享,vm-page-size 是要根據存儲的 資料大小來設定的,作者建議如果存儲很多小對象,page 大小最好設定為 32 或者 64bytes;如果存儲很大大對象,則可以使用更大的 page,如果不确定,就使用預設值 |
25 | vm-pages 134217728 | 設定 swap 檔案中的 page 數量,由于頁表(一種表示頁面空閑或使用的 bitmap)是在放在記憶體中的,,在磁盤上每 8 個 pages 将消耗 1byte 的記憶體。 |
26 | vm-max-threads 4 | 設定通路swap檔案的線程數,最好不要超過機器的核數,如果設定為0,那麼所有對swap檔案的操作都是串行的,可能會造成比較長時間的延遲。預設值為4 |
27 | glueoutputbuf yes | 設定在向用戶端應答時,是否把較小的包合并為一個包發送,預設為開啟 |
28 | hash-max-zipmap-entries 64 | hash-max-zipmap-value 512 指定在超過一定的數量或者最大的元素超過某一臨界值時,采用一種特殊的雜湊演算法 |
29 | activerehashing yes | 指定是否激活重置哈希,預設為開啟(後面在介紹 Redis 的雜湊演算法時具體介紹) |
30 | include /path/to/local.conf | 指定包含其它的配置檔案,可以在同一主機上多個Redis執行個體之間使用同一份配置檔案,而同時各個執行個體又擁有自己的特定配置檔案 |
更多資訊可參考:https://www.runoob.com/redis/redis-conf.html
3.2 設定密碼和驗證
在配置檔案中配置requirepass的密碼(當redis重新開機時密碼依然有效)。
redis 127.0.0.1:6379> config set requirepass mypass
查詢密碼:
redis 127.0.0.1:6379> config get requirepass
(error) ERR operation not permitted
複制
密碼驗證:
redis 127.0.0.1:6379> auth mypass
OK
複制
再次查詢:
redis 127.0.0.1:6379> config get requirepass
1) "requirepass"
2) "mypass"
複制
PS:如果配置檔案中沒添加密碼 那麼redis重新開機後,密碼失效;
如果需要在遠端 redis 服務上執行指令,同樣我們使用的也是 redis-cli 指令。
$ redis-cli -h host -p port -a password
【執行個體】
以下執行個體示範了如何連接配接到主機為 127.0.0.1,端口為 6379 ,密碼為 mypass 的 redis 服務上。
$redis-cli -h 127.0.0.1 -p 6379 -a "mypass"
redis 127.0.0.1:6379>
複制
先登陸後驗證:
redis 127.0.0.1:6379> auth "mypass"
OK
複制
AUTH指令跟其他redis指令一樣,是沒有加密的;阻止不了攻擊者在網絡上竊取你的密碼;
3.3 REDIS支援的類型
Redis支援五種資料類型:string(字元串),hash(哈希),list(清單),set(集合)及zset(sorted set:有序集合)。
<1> String(字元串)
string 類型是 Redis 最基本的資料類型,string 類型的值最大能存儲 512MB。
各個資料類型應用場景:
https://www.runoob.com/redis/redis-data-types.html
【執行個體】
redis 127.0.0.1:6379> SET name "duncanwang"
OK
redis 127.0.0.1:6379> GET name
"duncanwang"
複制
<2>Hash(哈希)
Redis hash 是一個 string 類型的 field 和 value 的映射表,hash 特别适合用于存儲對象。
【執行個體】
127.0.0.1:6379> HMSET say field1 "Hello" field2 "world"
OK
127.0.0.1:6379> HMGET say field1
1) "Hello"
127.0.0.1:6379> HMGET say field2
1) "world"
複制
執行個體中我們使用了 Redis HMSET, HGET 指令,HMSET 設定了兩個 field=>value 對, HGET 擷取對應 field 對應的 value。
每個 hash 可以存儲 232 -1 鍵值對(40多億)。
<3> List(清單)
Redis 清單是簡單的字元串清單,按照插入順序排序。你可以添加一個元素到清單的頭部(左邊)或者尾部(右邊)。
【執行個體】
127.0.0.1:6379> LPUSH mylist "duncan"
(integer) 1
127.0.0.1:6379> LPUSH mylist "jenise"
(integer) 2
127.0.0.1:6379> LPUSH mylist "dijior"
(integer) 3
127.0.0.1:6379> LRANGE mylist 0 2
1) "dijior"
2) "jenise"
3) "duncan"
複制
清單最多可存儲 232 - 1 元素 (4294967295, 每個清單可存儲40多億)。
<4> Set(集合)
Redis 的 Set 是 string 類型的無序集合。
集合是通過哈希表實作的,是以添加,删除,查找的複雜度都是 O(1)。
SADD 指令
添加一個 string 元素到 key 對應的 set 集合中,成功傳回 1,如果元素已經在集合中傳回 0。
SADD key member
【執行個體】
127.0.0.1:6379> SADD myset "duncanwang"
(integer) 1
127.0.0.1:6379> SADD myset "jenise"
(integer) 1
127.0.0.1:6379> SADD myset "dejior"
(integer) 1
127.0.0.1:6379> SADD myset "duncanwang"
(integer) 0
127.0.0.1:6379> SMEMBERS myset
1) "dejior"
2) "jenise"
3) "duncanwang"
複制
注意:以上執行個體中 rabitmq 添加了兩次,但根據集合内元素的唯一性,第二次插入的元素将被忽略。
集合中最大的成員數為 232 - 1(4294967295, 每個集合可存儲40多億個成員)
<5> zset(sorted set:有序集合)
Redis zset 和 set 一樣也是string類型元素的集合,且不允許重複的成員。
不同的是每個元素都會關聯一個double類型的分數。redis正是通過分數來為集合中的成員進行從小到大的排序。
zset的成員是唯一的,但分數(score)卻可以重複。
ZADD 指令
添加元素到集合,元素在集合中存在則更新對應score
ZADD key score member
【執行個體】
127.0.0.1:6379> ZADD myzset 0 "duncanwang"
(integer) 1
127.0.0.1:6379> ZADD myzset 1 "jenise"
(integer) 1
127.0.0.1:6379> ZADD myzset 2 "dejior"
(integer) 1
127.0.0.1:6379> ZADD myzset 1 "dejior"
(integer) 0
127.0.0.1:6379> ZRANGEBYSCORE myzset 0 3
1) "duncanwang"
2) "dejior"
3) "jenise"
複制
3.4 Redis 釋出訂閱
Redis 釋出訂閱(pub/sub)是一種消息通信模式:發送者(pub)發送消息,訂閱者(sub)接收消息。
Redis 用戶端可以訂閱任意數量的頻道。
下圖展示了頻道 channel1 , 以及訂閱這個頻道的三個用戶端 —— client2 、 client5 和 client1 之間的關系:
當有新消息通過 PUBLISH 指令發送給頻道 channel1 時, 這個消息就會被發送給訂閱它的三個用戶端:
【執行個體】
以下執行個體示範了釋出訂閱是如何工作的。在我們執行個體中我們建立了訂閱頻道名為 redisChat:
redis 127.0.0.1:6379> SUBSCRIBE redisChat
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "redisChat"
3) (integer) 1
複制
現在,我們先重新開啟個 redis 用戶端,然後在同一個頻道 redisChat 釋出兩次消息,訂閱者就能接收到消息。
redis 127.0.0.1:6379> PUBLISH redisChat "Redis is a great caching technique"
(integer) 1
redis 127.0.0.1:6379> PUBLISH redisChat "Learn redis by runoob.com"
(integer) 1
複制
訂閱者的用戶端會顯示如下消息
1) "message"
2) "redisChat"
3) "Redis is a great caching technique"
1) "message"
2) "redisChat"
3) "Learn redis by runoob.com"
複制
Redis 釋出訂閱指令
下表列出了 redis 釋出訂閱常用指令:
序号 | 指令 | 描述 |
---|---|---|
1 | PSUBSCRIBE pattern [pattern ...] | 訂閱一個或多個符合給定模式的頻道。 |
2 | PUBSUB subcommand [argument [argument ...]] | 檢視訂閱與釋出系統狀态。 |
3 | PUBLISH channel message | 将資訊發送到指定的頻道。 |
4 | PUNSUBSCRIBE [pattern [pattern ...]] | 退訂所有給定模式的頻道。 |
5 | SUBSCRIBE channel [channel ...] | 訂閱給定的一個或多個頻道的資訊。 |
6 | UNSUBSCRIBE [channel [channel ...]] | 指退訂給定的頻道。 |
3.5 Redis 事務
Redis 事務可以一次執行多個指令, 并且帶有以下三個重要的保證:
批量操作在發送 EXEC 指令前被放入隊列緩存。
收到 EXEC 指令後進入事務執行,事務中任意指令執行失敗,其餘的指令依然被執行。
在事務執行過程,其他用戶端送出的指令請求不會插入到事務執行指令序列中。
一個事務從開始到執行會經曆以下三個階段:
開始事務。
指令入隊。
執行事務。
執行個體
以下是一個事務的例子, 它先以 MULTI 開始一個事務, 然後将多個指令入隊到事務中, 最後由 EXEC 指令觸發事務, 一并執行事務中的所有指令:
redis 127.0.0.1:6379> MULTI
OK
redis 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days"
QUEUED
redis 127.0.0.1:6379> GET book-name
QUEUED
redis 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series"
QUEUED
redis 127.0.0.1:6379> SMEMBERS tag
QUEUED
redis 127.0.0.1:6379> EXEC
1) OK
2) "Mastering C++ in 21 days"
3) (integer) 3
4) 1) "Mastering Series"
2) "C++"
3) "Programming"
複制
單個 Redis 指令的執行是原子性的,但 Redis 沒有在事務上增加任何維持原子性的機制,是以 Redis 事務的執行并不是原子性的。
事務可以了解為一個打包的批量執行腳本,但批量指令并非原子化的操作,中間某條指令的失敗不會導緻前面已做指令的復原,也不會造成後續的指令不做。
Redis 事務指令
下表列出了 redis 事務的相關指令:
序号 | 指令 | 描述 |
---|---|---|
1 | DISCARD | 取消事務,放棄執行事務塊内的所有指令。 |
2 | EXEC | 執行所有事務塊内的指令。 |
3 | MULTI | 标記一個事務塊的開始。 |
4 | UNWATCH | 取消 WATCH 指令對所有 key 的監視。 |
5 | WATCH key [key ...] | 監視一個(或多個) key ,如果在事務執行之前這個(或這些) key 被其他指令所改動,那麼事務将被打斷。 |
4.參考
(1)官網
https://redis.io/
(2)redis中文網
http://www.redis.cn/documentation.html
(3)Redis 教程
https://www.runoob.com/redis/redis-tutorial.html
(4)Redis 伺服器
https://www.runoob.com/redis/redis-server.html
(5)Redis 資料備份與恢複
https://www.runoob.com/redis/redis-backup.html
(6)Redis 持久化
一起看懂Redis兩種持久化方式的原理
https://segmentfault.com/a/1190000015983518?utm_source=tag-newest