前言
Redis
是一種基於 鍵值對 的 NoSQL
資料庫。與很多鍵值對資料庫不同,Redis
提供了豐富的 值資料儲存結構,包括 string
(字串)、hash
(雜湊)、list
(列表)、set
(集合)、zset
(有序集合)、bitmap
(點陣圖)等等。
其他文章
正文
Redis
是一個使用 ANSI C
編寫的開源、支援 網路、基於 記憶體、單執行緒模型、可選永續性 的 鍵值對儲存資料庫。
1. Redis的特性
-
速度快,最快可達到
10w QPS
(基於 記憶體,C
語言,單執行緒 架構); -
基於 鍵值對 (
key/value
) 的資料結構伺服器。全稱Remote Dictionary Server
。包括string
(字串)、hash
(雜湊)、list
(列表)、set
(集合)、zset
(有序集合)、bitmap
(點陣圖)。同時在 字串 的基礎上演變出 點陣圖(BitMaps
)和HyperLogLog
兩種資料結構。3.2
版本中加入GEO
(地理資訊位置)。 -
豐富的功能。例如:鍵過期(快取),釋出訂閱(訊息佇列),
Lua
指令碼(自己實現Redis
命令),事務,流水線(Pipeline
,用於減少網路開銷)。 -
簡單穩定。無外部庫依賴,單執行緒模型。
-
客戶端語言多。
-
持久化(支援兩種 持久化 方式
RDB
和AOF
)。 -
主從複製(分散式的基礎)。
-
高可用(
Redis Sentinel
),分散式(Redis Cluster
)和 水平擴容。
2. Redis的應用場景
2.1. 快取
合理的使用 快取 能夠明顯加快訪問的速度,同時降低資料來源的壓力。這也是 Redis
最常用的功能。Redis
提供了 鍵值過期時間(EXPIRE key seconds
)設定,並且也提供了靈活控制 最大記憶體 和 記憶體溢位 後的 淘汰策略。
2.2. 排行榜
每個網站都有自己的排行榜,例如按照 熱度排名 的排行榜,釋出時間 的排行榜,答題排行榜 等等。Redis
提供了 列表(list
)和 有序集合(zset
)資料結構,合理的使用這些資料結構,可以很方便的構建各種排行榜系統。
2.3. 計數器
計數器 在網站應用中非常重要。例如:點贊數加 1
,瀏覽數 加 1
。還有常用的 限流操作,限制每個使用者每秒 訪問系統的次數 等等。Redis
支援 計數功能(INCR key
),而且計數的 效能 也非常好,計數的同時也可以設定 超時時間,這樣就可以 實現限流。
2.4. 社交網路
贊/踩,粉絲,共同好友/喜好,推送,下拉重新整理等是社交網站必備的功能。由於社交網站 訪問量通常比較大,而且 傳統的資料庫 不太適合儲存這類資料,Redis
提供的 資料結構 可以相對比較容易實現這些功能。
2.5. 訊息佇列
Redis
提供的 釋出訂閱(PUB/SUB
)和 阻塞佇列 的功能,雖然和專業的訊息佇列比,還 不夠強大,但對於一般的訊息佇列功能基本滿足。
3. Redis的安裝配置
下面介紹一下 Redis
的安裝流程。我會按照如下的順序,逐步搭建出 高可用 的 Redis
快取伺服器叢集。
Redis
單機伺服器 搭建Redis
主從複製 搭建Redis-Sentinel
高可用 搭建
3.1. Redis單機伺服器安裝
3.1.1. 下載並解壓
首先從 Redis
官網下載 Redis
原始碼並解壓,這裡使用的是 最新穩定版本 4.0.11
。依次執行如下命令:
cd /usr/local/
wget http://download.redis.io/releases/redis-4.0.11.tar.gz
tar -zxvf redis-4.0.2.tar.gz
複製程式碼
3.1.2. 編譯並安裝
下載並解壓完畢後,則對 原始碼包 進行 編譯安裝,這裡 Redis
安裝路徑為 /usr/local/redis
。
注意:
make install PREFIX
=目標安裝路徑
cd /usr/local/redis-4.0.11
make install PREFIX=/usr/local/redis
複製程式碼
安裝完成時,/usr/local/redis/bin
目錄下會生成的幾個可執行的檔案。
可執行檔案 | 作用 |
---|---|
redis-server | 啟動 redis 服務 |
redis-cli redis | 命令列客戶端 |
redis-benchmark | redis 基準測試工具 |
redis-check-aof | redis AOF 持久化檔案檢測和修復工具 |
redis-check-dump | redis RDB 持久化檔案檢測和修復工具 |
redis-sentinel | 啟動 redis sentinel |
複製 Redis
相關命令到 /usr/local/bin
目錄下,這樣就可以直接執行這些命令,不用寫全路徑。
$ cd /usr/local/redis/bin/
$ sudo sudo cp redis-cli redis-server redis-sentinel /usr/local/bin
複製程式碼
3.1.3. 修改Redis配置檔案
安裝完成之後將 Redis
配置檔案拷貝到 /usr/local
下,redis.conf
是 Redis
的配置檔案,redis.conf
在 Redis
原始碼目錄,port
預設是 6379
。
$ sudo cp /usr/local/redis-4.0.11/redis.conf /usr/local/
複製程式碼
Redis
配置檔案主要引數解析參考:
# redis程式是否以守護程式的方式執行,yes為是,no為否(不以守護程式的方式執行會佔用一個終端)。
daemonize no
# 指定redis程式的PID檔案存放位置
pidfile /var/run/redis.pid
# redis程式的埠號
port 6379
# 繫結的主機地址
bind 127.0.0.1
# 客戶端閒置多長時間後關閉連線,預設此引數為0即關閉此功能
timeout 300
# redis日誌級別,可用的級別有debug.verbose.notice.warning
loglevel verbose
# log檔案輸出位置,如果程式以守護程式的方式執行,此處又將輸出檔案設定為stdout的話,就會將日誌資訊輸出到/dev/null裡面去了
logfile stdout
# 設定資料庫的數量,預設為0可以使用select <dbid>命令在連線上指定資料庫id
databases 16
# 指定在多少時間內重新整理次數達到多少的時候會將資料同步到資料檔案
save <seconds> <changes>
# 指定儲存至本地資料庫時是否壓縮檔案,預設為yes即啟用儲存
rdbcompression yes
# 指定本地資料庫檔名
dbfilename dump.db
# 指定本地資料問就按存放位置
dir ./
# 指定當本機為slave服務時,設定master服務的IP地址及埠,在redis啟動的時候他會自動跟master進行資料同步
slaveof <masterip> <masterport>
# 當master設定了密碼保護時,slave服務連線master的密碼
masterauth <master-password>
# 設定redis連線密碼,如果配置了連線密碼,客戶端在連線redis是需要通過AUTH<password>命令提供密碼,預設關閉
requirepass footbared
# 設定同一時間最大客戶連線數,預設無限制。redis可以同時連線的客戶端數為redis程式可以開啟的最大檔案描述符,如果設定 maxclients 0,表示不作限制。當客戶端連線數到達限制時,Redis會關閉新的連線並向客戶端返回 max number of clients reached 錯誤資訊
maxclients 128
# 指定Redis最大記憶體限制,Redis在啟動時會把資料載入到記憶體中,達到最大記憶體後,Redis會先嚐試清除已到期或即將到期的Key。當此方法處理後,仍然到達最大記憶體設定,將無法再進行寫入操作,但仍然可以進行讀取操作。Redis新的vm機制,會把Key存放記憶體,Value會存放在swap區
maxmemory<bytes>
# 指定是否在每次更新操作後進行日誌記錄,Redis在預設情況下是非同步的把資料寫入磁碟,如果不開啟,可能會在斷電時導致一段時間內的資料丟失。因為redis本身同步資料檔案是按上面save條件來同步的,所以有的資料會在一段時間內只存在於記憶體中。預設為no。
appendonly no
# 指定跟新日誌檔名預設為appendonly.aof
appendfilename appendonly.aof
# 指定更新日誌的條件,有三個可選引數 - no:表示等作業系統進行資料快取同步到磁碟(快),always:表示每次更新操作後手動呼叫fsync()將資料寫到磁碟(慢,安全), everysec:表示每秒同步一次(折衷,預設值);
appendfsync everysec
複製程式碼
- 設定後臺啟動
由於 Redis
預設是 前臺啟動,不建議使用。修改 Redis
配置檔案,把 daemonize no
改為 daemonize yes
。
daemonize yes
複製程式碼
- 設定遠端訪問
Redis
預設只允許 本機訪問,把 bind
修改為 bind 0.0.0.0
此設定會變成 允許所有遠端訪問。如果想指定限制訪問,可設定對應的 IP
。
bind 0.0.0.0
複製程式碼
- 配置
Redis
日誌記錄
找到 logfile
配置,預設是:logfile ""
,改為自定義日誌檔案路徑。
logfile /var/log/redis_6379.log
複製程式碼
- 設定
Redis
請求密碼
把 requirepass
修改為 123456
,修改之後重啟下服務
requirepass "123456"
複製程式碼
有了密碼之後,進入客戶端,就得這樣訪問:
$ redis-cli -h 127.0.0.1 -p 6379 -a 123456
複製程式碼
3.1.4. Redis的常用命令
- 啟動命令
$ redis-server /usr/local/redis.conf
複製程式碼
- 關閉命令
$ redis-cli -h 127.0.0.1 -p 6379 shutdown
複製程式碼
- 檢視是否啟動
$ ps -ef | grep redis
複製程式碼
- 進入客戶端
$ redis-cli
複製程式碼
- 關閉客戶端
$ redis-cli shutdown
複製程式碼
注意:不建議使用
kill -9
,這種方式不但不會做持久化操作,還會造成緩衝區等資源不能優雅關閉。極端情況下造成AOF
和 複製丟失資料 的情況。shutdown
還有一個引數,代表是否在關閉redis
前,生成 持久化檔案,命令為redis-cli shutdown nosave|save
。
- 設定為開機自動啟動
$ echo "redis-server /usr/local/redis.conf" >> /etc/rc.local
複製程式碼
- 開放防火牆埠
# 新增規則
iptables -I INPUT -p tcp -m tcp --dport 6379 -j ACCEPT
# 儲存規則
service iptables save
# 重啟iptables
service iptables restart
複製程式碼
3.1.5. 註冊Redis為系統服務
在 /etc/init.d
目錄下新增 Redis
服務的 啟動,暫停 和 重啟 指令碼:
$ sudo /etc/init.d/redis
複製程式碼
指令碼的內容如下:
#!/bin/sh
#
# redis - this script starts and stops the redis-server daemon
#
# chkconfig: - 85 15
# description: Redis is a persistent key-value database
# processname: redis-server
# config: /usr/local/redis/bin/redis-server
# config: /etc/redis.conf
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
redis="/usr/local/redis/bin/redis-server"
prog=$(basename $redis)
REDIS_CONF_FILE="/etc/redis.conf"
[ -f /etc/sysconfig/redis ] && . /etc/sysconfig/redis
lockfile=/var/lock/subsys/redis
start() {
[ -x $redis ] || exit 5
[ -f $REDIS_CONF_FILE ] || exit 6
echo -n $"Starting $prog: "
daemon $redis $REDIS_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
stop
start
}
reload() {
echo -n $"Reloading $prog: "
killproc $redis -HUP
RETVAL=$?
echo
}
force_reload() {
restart
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|orce-reload}"
exit 2
esac
複製程式碼
賦予指令碼檔案可執行許可權:
$ chmod 755 /etc/init.d/redis
複製程式碼
啟動、停止和重啟 redis
服務:
service redis start
service redis stop
service redis restart
複製程式碼
3.2. Redis主從複製叢集安裝
3.2.1. Redis-Server配置說明
角色 | IP地址 | 埠號 |
---|---|---|
Redis Master | 10.206.20.231 | 16379 |
Redis Slave | 10.206.20.231 | 26379 |
3.2.2. Redis主從架構配置
- 編輯 從機 的
Redis
配置檔案,找到210
行(大概)-#slaveof <masterip> <masterport>
。去掉該註釋,填寫 主伺服器 的IP
和 埠。
slaveof 10.206.20.231 16379
複製程式碼
- 如果 主伺服器 設定了密碼,還需要找到
masterauth <master-password>
這一行,去掉註釋,改為masterauth
的主機密碼。
masterauth 123456
複製程式碼
- 配置完成後重啟 從伺服器 的
Redis
服務。
$ service redis restart
複製程式碼
- 重啟完成之後,進入 主伺服器 的
redis-cli
模式下,命令為redis-cli -h 127.0.0.1 -p 16379 -a 123456
。輸入INFO replication
查詢到 當前主機 的Redis
的狀態,連線上 主伺服器 的 從伺服器。
Redis
主伺服器 的配置檔案:
- redis.conf
daemonize yes
pidfile /var/run/redis-16379.pid
logfile /var/log/redis/redis-16379.log
port 16379
bind 0.0.0.0
timeout 300
databases 16
dbfilename dump-16379.db
dir ./redis-workdir
masterauth 123456
requirepass 123456
複製程式碼
Redis
從伺服器 的配置檔案:
- redis.conf
daemonize yes
pidfile /var/run/redis-26379.pid
logfile /var/log/redis/redis-26379.log
port 26379
bind 0.0.0.0
timeout 300
databases 16
dbfilename dump-26379.db
dir ./redis-workdir
masterauth 123456
requirepass 123456
slaveof 127.0.0.1 16379
複製程式碼
Redis
主伺服器 的狀態如下:
# Replication
role:master
connected_slaves:1
slave0:ip=10.206.20.231,port=16379,state=online,offset=28,lag=1
master_replid:625ae9f362643da5337835beaeabfdca426198c7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:28
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:28
複製程式碼
Redis
從伺服器 的狀態如下:
# Replication
role:slave
master_host:10.206.20.231
master_port:26379
master_link_status:up
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_repl_offset:210
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:625ae9f362643da5337835beaeabfdca426198c7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:210
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:210
複製程式碼
3.2.3. Redis主從配置驗證
上面完成了基本的 主從配置,可以簡單的測試一下效果:
- 進入 主伺服器 的
redis-cli
模式,然後set
一個值,比如:
> set master_port "16379"
OK
複製程式碼
- 切換進入 從伺服器 的
redis-cli
的模式,查詢剛剛設定的值看是否存在:
> get master_port
"16379"
複製程式碼
此時,我們可以發現是可以獲取到值的,Redis
的 主從模式 正常工作。
小結
本文簡單的說明了 Redis
的相關 特性 和 應用場景,詳細地給出 Redis
單伺服器的 編譯,安裝,配置 和 啟動,進一步引入了 Redis
主從複製 的相關原理和詳細配置。關於 Redis
的 高可用機制 和 叢集搭建,下文將給出詳細的說明。
參考
《Redis 開發與運維》
歡迎關注技術公眾號: 零壹技術棧
本帳號將持續分享後端技術乾貨,包括虛擬機器基礎,多執行緒程式設計,高效能框架,非同步、快取和訊息中介軟體,分散式和微服務,架構學習和進階等學習資料和文章。