深入剖析Redis系列(一) - Redis入門簡介與主從搭建

零壹技術棧發表於2018-08-17

前言

Redis 是一種基於 鍵值對NoSQL 資料庫。與很多鍵值對資料庫不同,Redis 提供了豐富的 值資料儲存結構,包括 string(字串)、hash(雜湊)、list(列表)、set(集合)、zset(有序集合)、bitmap(點陣圖)等等。

深入剖析Redis系列(一) - Redis入門簡介與主從搭建

其他文章

正文

Redis 是一個使用 ANSI C 編寫的開源、支援 網路、基於 記憶體單執行緒模型可選永續性鍵值對儲存資料庫

1. Redis的特性

  1. 速度快,最快可達到 10w QPS(基於 記憶體C 語言,單執行緒 架構);

  2. 基於 鍵值對 (key/value) 的資料結構伺服器。全稱 Remote Dictionary Server。包括 string(字串)、hash(雜湊)、list(列表)、set(集合)、zset(有序集合)、bitmap(點陣圖)。同時在 字串 的基礎上演變出 點陣圖BitMaps)和 HyperLogLog 兩種資料結構。3.2 版本中加入 GEO地理資訊位置)。

  3. 豐富的功能。例如:鍵過期(快取),釋出訂閱(訊息佇列), Lua 指令碼(自己實現 Redis 命令),事務流水線Pipeline,用於減少網路開銷)。

  4. 簡單穩定。無外部庫依賴,單執行緒模型。

  5. 客戶端語言多。

  6. 持久化(支援兩種 持久化 方式 RDBAOF)。

  7. 主從複製(分散式的基礎)。

  8. 高可用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.confRedis 的配置檔案,redis.confRedis 原始碼目錄,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 開發與運維》


歡迎關注技術公眾號: 零壹技術棧

零壹技術棧

本帳號將持續分享後端技術乾貨,包括虛擬機器基礎,多執行緒程式設計,高效能框架,非同步、快取和訊息中介軟體,分散式和微服務,架構學習和進階等學習資料和文章。

相關文章