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"
有了密碼之后,進入客戶端,就得這樣訪問:
3.1.4. Redis
$ redis-cli -h 127.0.0.1 -p 6379 -a 123456
的常用命令
- 啟動命令
$ 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
的 主從模式 正常工作。
有問題可以討論,歡迎大家和我一起學習微信hsj179540