天天看點

【實踐】REDIS緩存資料庫從安裝到入門1.摘要2. 安裝3. 指令訂閱者的用戶端會顯示如下消息4.參考

【實踐】REDIS緩存資料庫從安裝到入門1.摘要2. 安裝3. 指令訂閱者的用戶端會顯示如下消息4.參考

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 之間的關系:

【實踐】REDIS緩存資料庫從安裝到入門1.摘要2. 安裝3. 指令訂閱者的用戶端會顯示如下消息4.參考

當有新消息通過 PUBLISH 指令發送給頻道 channel1 時, 這個消息就會被發送給訂閱它的三個用戶端:

【實踐】REDIS緩存資料庫從安裝到入門1.摘要2. 安裝3. 指令訂閱者的用戶端會顯示如下消息4.參考

【執行個體】

以下執行個體示範了釋出訂閱是如何工作的。在我們執行個體中我們建立了訂閱頻道名為 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