天天看點

Redis 的進階應用

Ø  簡介

本文主要介紹 Redis 中的進階應用,主要包括以下内容:

1.   安全性

2.   主從複制

3.   事務處理

4.   持久化機制

5.   釋出訂閱消息

6.   虛拟記憶體的使用

7.   性能監控

設定用戶端連接配接後進行任何操作前需要使用的密碼。

由于 redis 速度非常快,是以在一台比較好的伺服器下,一個外部使用者可以在一秒鐘進行150k次的密碼嘗試,是以需要設定強大的密碼防止黑客的暴力破解。

1)   為用戶端設定登入密碼(兩種方式)

1.   第一種方式,在 redis.conf 配置檔案中設定 requirepass 密碼,重新開機 redis-server 後同樣生效。

1)   使用 vi 打開 redis.conf 檔案

[root@192 ~]# vi /usr/local/redis/etc/redis.conf

2)   搜尋 requirepass 的位置,輸入指令 /requirepass 并設定密碼,如圖:

Redis 的進階應用

3)   輸入:wq指令儲存并退出編輯。

4)   關閉 redis-server

[root@192 ~]# pkill redis-server

5)   開啟 redis-server(注意:這裡必須保證使用的是剛才修改過的 redis.conf 檔案)

[root@192 ~]# /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf

6)   再次通路 redis 就需要輸入密碼授權了,例如:

Redis 的進階應用

7)   也可以在登入 redis-cli 時同時指定密碼,例如:

Redis 的進階應用

但是出現了一個警告,意思是使用 -a 指定密碼不安全!

2.   第二種方式,設定隻在目前 redis-server 重新開機之前生效的登入密碼,代碼如下:

[root@192 ~]# /usr/local/redis/bin/redis-cli

127.0.0.1:6379> get name

"abc"

127.0.0.1:6379> config set requiepass 123456

(error) ERR Unsupported CONFIG parameter: requiepass

127.0.0.1:6379> config set requirepass 123456

OK

(error) NOAUTH Authentication required.

127.0.0.1:6379> auth 123456

這種方式有幾個問題:

1)   重新開機 redis-server 之後之前設定的密碼會被清除掉;

2)   不會将設定的密碼記錄到 redis.conf 中;

3)   可以了解為設定的一個臨時密碼。

Ø 

注意:在做 Redis 叢集時,所有的 Redis 用戶端密碼需要保持一緻。

Redis 主從複制可以允許多個 slave server 擁有和 master server 相同的資料庫版本,防止單節點伺服器(伺服器奔潰、資料丢失)。

1.   Redis 主從複制的特點:

1)   master 可以用于多個 slave.

2)   多個 slave 可以連接配接同一個 master 外,還可以連接配接到其他 slave.

3)   主從複制不會阻塞 master,在同步資料時,master 可以繼續處理 client 請求。

4)   提高系統的伸縮性。

5)   注意:slave 不能進行寫操作,否則報錯:

(錯誤)READONLY-您不能針對隻讀副本進行寫入。

2.   Redis 主從複制過程:

1)   slave 與 master 建立連接配接,發送 sync 同步指令。

2)   master 會啟動一個背景程序,将資料庫快照儲存到檔案中,同時 master 主程序會開始收集新的寫指令并緩存。

3)   背景完成儲存後,就将此檔案發送給 slave.

4)   slave 将此檔案儲存到硬碟上。

3.   配置主從伺服器:

1)   在 slave 的配置檔案中加入以下配置:

1.   指定 master 的IP和端口,搜尋/replicaof 或 /slaveof

Redis 的進階應用

2.   指定 master 的請求密碼,搜尋/masterauth

Redis 的進階應用

2)   開啟 slave 的 redis-server 可能報錯:

MASTER <-> REPLICA sync started

Error condition on socket for SYNC: No route to host

解決辦法:

1.   關閉 master 的 reids-server

2.   将 redis.conf 中的 bind 127.0.0.1 改為 bind 0.0.0.0 即可。

3.   如果還是報錯,關閉防火牆:service iptables stop

4.   開啟 master 的 reids-server

3)   區分目前是主機還是從機

1.   輸入 info 或者 info replication 指令,主機資訊:

Redis 的進階應用

2.   輸入 info 或者 info replication 指令,從機資訊:

Redis 的進階應用

4)   其他

注意開啟 redis-server 時配置檔案的指定,例如:

/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf

優點:可以完整的 Redis 中的資料做備份。

缺點:當主機擋掉後,不能馬上的做主從切換。

它隻是 Redis 叢集中的一小部分功能。

Redis 對事務的支援比較簡單。Redis 隻能保證一個 Client 發起的事務中的指令可可以連續的執行,而中間不會插入其他 Client 的指令。當一個 Client 在一個連接配接中發出 multi 指令時,這個連接配接會進入一個事務上下文,該連接配接後續的指令不會立即執行,而是先放到一個隊列中,當執行 exec 指令時,redis 會順序的執行隊列中的指令。

1)   事務相關操作

1.   開啟與送出事務

127.0.0.1:6379> multi   #開啟事務

127.0.0.1:6379> set name abeam

QUEUED

127.0.0.1:6379> set age 30

127.0.0.1:6379> exec    #送出事務

2.   取消事務中的隊列任務

127.0.0.1:6379> set key2 vlaue2

127.0.0.1:6379> set key3 vlaue3

127.0.0.1:6379> discard #取消事務

2)   Redis 不能復原事務中的隊列,例如:

127.0.0.1:6379> multi

127.0.0.1:6379> incr age

127.0.0.1:6379> incr name   #這裡的指令會報錯

127.0.0.1:6379> exec

(integer) 31    #但是,這裡的指令被正常執行了

(error) ERR value is not an integer or out of range

3)   樂觀鎖複雜事務控制

樂觀鎖:

大多數是基于資料版本(version)的記錄機制實作的。即為資料增加一個版本表示,在基于資料庫表的版本解決方案中,一般是通過為資料表添加一個"version"字段來實作讀取資料時,将此版本号一同讀出,之後更新時對此版本号加1.此時,将送出資料的版本号與資料表中對應記錄的目前版本号進行對比,如果送出的資料版本号大于資料庫目前版本号,則予以更新,否則認為是過期資料。

1.   Redis 使用 watch 指令實作

樂觀鎖

watch 指令會監事給定的 key,當 exec 時如果監視的 key 從調用 watch 後發生過變化,則整個事務會失敗。可以調用 watch 多次監控多個 key, 這樣就可以對指定的 key 加樂觀鎖了。

注意 watch 的 key 是對整個連接配接有效的,事務也一樣。如果連接配接斷開,監視和事務都會被自動清除。

exec、discard、unwatch 指令都會清除連接配接中的所有監視。

1)   Session1

127.0.0.1:6379> set age1 10

OK

127.0.0.1:6379> set age2 20

127.0.0.1:6379> watch age1  #可以同時監控多個key

2)   Session2

127.0.0.1:6379> set age1 100

127.0.0.1:6379> set age2 200

3)   Session1

127.0.0.1:6379> incr age1

127.0.0.1:6379> incr age2

127.0.0.1:6379> exec    #整個送出失敗(因為監聽的age1發生變化)

(nil)

127.0.0.1:6379> get age1

"100"

127.0.0.1:6379> get age2

"200"

4)   悲觀鎖(非Redis知識)

基于資料庫的實作

,當A使用者查詢、更新某條資料後,未送出之前B使用者不允許進行更新,例如:

SELECT * FROM Member WHERE Id = 1 FOR UPDATE;

4.   持久化機制

Redis 是一個支援持久化的記憶體資料庫,也就是說 redis 需要經常将記憶體中的資料同步到硬碟來保證持久化。Redis 支援兩種持久化方式:

1.   Snapshotting(快照)

(存儲資料)

快照是預設方式的持久化方式,這種方式是将記憶體中的資料寫入到二進制檔案中,預設的檔案名為

dump.rdb

。可以通過配置設定自動做快照持久化的方式,配置 redis 在 n 秒内如果超過 m 個 key 被修改就自動快照,例如:

save 900 1      #900秒内如果超過1個key被修改,則發起快照儲存

save 300 10     #同上

save 60 10000   #同上

2.   Append-only file(縮寫aof)的方式

(存儲操作指令:增删改)

由于快照方式是在一定間隔時間做一次的,是以如果 redis 意外 down 掉的話,就會丢失最後一次快照後的所有修改。

aof 比快照方式具有更好的持久化性,是由于在使用 aof 時,redis 就會将

每一個收到的寫指令都通過 write 函數追加到檔案中

,當 redis 重新開機時會通過重新執行檔案中儲存的寫指令來在記憶體中重建整個資料庫的内容。

當然由于 os 會在核心中緩存 write 做的修改,是以可能不是立即寫到磁盤上,這樣 aof 方式的持久化也還是可能丢失部分修改。

可以通過配置檔案告訴 redis 我們想要通過 fsync 函數強制 os 寫入到磁盤的時機。

1.   開啟 aof 持久化

1)   将 appendonly no 改為 yes   #啟用 aof 持久化方式

2)   三種持久化選擇

# appendfsync always    #收到寫指令就立即寫入磁盤,最慢,但是保證完全的持久化

appendfsync everysec    #每秒鐘寫入磁盤一次,在性能和持久化方面做了很好的折中,預設值

# appendfsync no        #完全依賴os,性能持久化沒保證

3)   重新開機 redis-server

4)   将檢視到 appendonly.aof 檔案

Redis 的進階應用

5)   檢視檔案内容

Redis 的進階應用

釋出訂閱(

pub/sub

)是一種消息通信模式,主要的目的是

解除

消息釋出者和消息訂閱者之間的

耦合

,Redis 作為一個 pub/sub 的 server, 在訂閱者和釋出者之間起到了消息路由的功能。訂閱者可以通過 subscribe 和 psubscribe 指令向 redis server 訂閱自己感興趣的類型,redis 将資訊類型成為

通道

(channel)。當釋出者通過 publish 指令向 redis server 發送特定類型的消息時,訂閱該資訊類型的

全部 client

都會收到此資訊。

1)   監聽釋出示例

1.   Session1(訂閱1個消息 tv1)

127.0.0.1:6379> subscribe tv1   #訂閱 tv1 的消息通道

Reading messages... (press Ctrl-C to quit)

"subscribe"

"tv1"

(integer) 1

"message"   #收到 tv1 釋出的資訊

"message111"

2.   Session2(訂閱2個消息 tv1、tv2)

127.0.0.1:6379> subscribe tv1 tv2   #訂閱 tv1和tv2 的消息通道

"tv2"

(integer) 2

"message"   #收到 tv2 釋出的資訊

"message222"

3.   Session3(釋出消息)

127.0.0.1:6379> publish tv1 message111  #釋出 tv1 的消息

127.0.0.1:6379> publish tv2 message222  #釋出 tv2 的消息

2)   相關指令

1.   模糊比對訂閱頻道

127.0.0.1:6379> psubscribe tv*

"psubscribe"

"tv*"

2.   檢視用戶端訂閱的頻道

127.0.0.1:6379> pubsub channels     #檢視所有訂閱的頻道

127.0.0.1:6379> pubsub channels *2  #模糊比對訂閱頻道名稱

Redis 的虛拟記憶體與作業系統的虛拟記憶體不是一回事,但是思路和目的都是相同的。就是

暫時把不經常通路的資料從記憶體交換到磁盤中

,進而騰出寶貴的記憶體空間用于其他需要通路的資料。尤其是對 redis 這樣的記憶體資料庫,記憶體總是不夠用的。除了可以将資料分割到多個 redis server 外。另外能夠提高資料庫容量的辦法就是使用虛拟記憶體,把那些

不經常通路的資料交換到磁盤上

下面是 vm 相關配置(redis-2.4.17都有該配置,redis-5.0.5就沒有該配置了?):

vm-enabled yes                 #開啟 vm 功能

vm-swap-file /tmp/redis.swap    #交換出來的 value 儲存的檔案路徑

vm-max-memory 1000000          #redis 使用的最大記憶體上限

vm-page-size 32                #每個頁面的大小32位元組

vm-pages 134217728             #最多使用多個頁面

vm-max-threads 4                #用于執行 value 對象換入的工作線程數量

really-use-vm yes              #是否使用虛拟記憶體

Redis 本身不支援性能監控,但是可以使用"Redis-stat"元件實作性能監控,它可以實作對多個 Redis-Server 進行監控。這個工具可以通過 github 下載下傳,下載下傳位址:https://github.com/junegunn/redis-stat,下面是具體的實作步驟:

1)   建立三個 Redis 運作程序,準備不同的 redis.conf 配置檔案。

2)   建立 redis 資料的儲存目錄,可以同時儲存三個 Redis 程序:

mkdir -p /usr/data/redis/{redis-6379,redis-6380,redis-6381}/{run,logs,dbcache}

3)   将 redis.conf 拷貝一份:

cp /usr/local/redis/etc/redis.conf /usr/local/redis/etc/redis-6379.conf

4)   編輯"redis-6379.conf"配置檔案:

vim /usr/local/redis/etc/redis.conf

1.   取消外網通路限制

注釋掉"bind 127.0.0.1"或者改為"bind 0.0.0.0"

2.   端口保持不變:port 6379

3.   設定背景運作:daemonize yes

4.   設定 pid 儲存檔案路徑

pidfile /usr/data/redis/redis-6379/run/redis_6379.pid

5.   設定日志檔案路徑

logfile "/usr/data/redis/redis-6379/logs/redis.log"

6.   設定資料檔案路徑

dir /usr/data/redis/redis-6379/dbcache/

5)   将"redis-6379.conf"複制為:redis-6380.conf、redis-6380.conf

cp /usr/local/redis/etc/redis-6379.conf /usr/local/redis/etc/redis-6380.conf

cp /usr/local/redis/etc/redis-6379.conf /usr/local/redis/etc/redis-6381.conf

6)   将其他的"*.conf"檔案的6379替換為對應的端口号:

vim /usr/local/redis/etc/redis-

6380

.conf

執行替換指令:1,$s/6379/

/g

6381

7)   啟動所有的 Redis 服務:

/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis-

6379

注:可采用"ps -ef | grep redis"或"netstat -tunpl"檢視是否正常啟動

8)   通過 Github 下載下傳 redis-stat 開發包

l  如果想要使用 redis-stat 檢測包必須下載下傳 ruby 相關環境:

apt-get install ruby ruby-dev rubygems

l  将該工具下載下傳到"/usr/local"目錄下:cd /usr/local/

l  進行 redis-stat 的下載下傳:

git clone https://github.com/junegunn/redis-stat.git

9)   執行"redis-stat"指令

cd /usr/local/redis-stat/bin

gem install redis-stat -V   #加上"-V"參數才會在指令行顯示安裝日志

注:redis-stat 指令必須使用 ruby 進行指令處理

l  如果安裝失敗:Failed to build gem native extension.

Redis 的進階應用

執行"yum install ruby-devel"指令即可。

l  顯示以下内容表示安裝成功:

Installing ri documentation for redis-stat-0.4.14

13 gems installed

10)  啟動 redis-stat 工具進行監聽控制:

/usr/local/redis-stat/bin/redis-stat 192.168.175.128:6379 192.168.175.128:6380 192.168.175.128:6381 -a abeam.

Redis 的進階應用

11)  該工具還支援 Web 檢視,它内部提供一個 HttpServer,在指令中加入相關參數即可:

/usr/local/redis-stat/bin/redis-stat 192.168.175.128:6379 192.168.175.128:6380 192.168.175.128:6381 -a abeam. --verbose --daemon --server=80

打開浏覽器進行通路(這裡打開的是虛拟機中的浏覽器,主機的不知道為什麼不能通路?):

Redis 的進階應用

12)  使用 Redis 的測試工具進行測試

/usr/local/redis/bin/redis-benchmark -h 192.168.175.128 -p 6379 -a abeam. -c 1000 -d 10 -n 10000

/usr/local/redis/bin/redis-benchmark -h 192.168.175.128 -p 6380 -a abeam. -c 1000 -d 10 -n 10000

/usr/local/redis/bin/redis-benchmark -h 192.168.175.128 -p 6381 -a abeam. -c 1000 -d 10 -n 10000

Redis 的進階應用

繼續閱讀