前言
Redis
是一種基于 鍵值對 的 NoSQL
數(shù)據(jù)庫蛤克。與很多鍵值對數(shù)據(jù)庫不同厌衙,Redis
提供了豐富的 值數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)畦木,包括 string
(字符串)兜粘、hash
(哈希)申窘、list
(列表)、set
(集合)孔轴、zset
(有序集合)剃法、bitmap
(位圖)等等。
正文
Redis
是一個(gè)使用 ANSI C
編寫的開源路鹰、支持 網(wǎng)絡(luò)贷洲、基于 內(nèi)存、單線程模型晋柱、可選持久性 的 鍵值對存儲(chǔ)數(shù)據(jù)庫优构。
1. Redis的特性
速度快,最快可達(dá)到
10w QPS
(基于 內(nèi)存雁竞,C
語言钦椭,單線程 架構(gòu));基于 鍵值對 (
key/value
) 的數(shù)據(jù)結(jié)構(gòu)服務(wù)器浓领。全稱Remote Dictionary Server
。包括string
(字符串)势腮、hash
(哈希)联贩、list
(列表)、set
(集合)捎拯、zset
(有序集合)泪幌、bitmap
(位圖)盲厌。同時(shí)在 字符串 的基礎(chǔ)上演變出 位圖(BitMaps
)和HyperLogLog
兩種數(shù)據(jù)結(jié)構(gòu)。3.2
版本中加入GEO
(地理信息位置)祸泪。豐富的功能吗浩。例如:鍵過期(緩存),發(fā)布訂閱(消息隊(duì)列)没隘,
Lua
腳本(自己實(shí)現(xiàn)Redis
命令)懂扼,事務(wù),流水線(Pipeline
右蒲,用于減少網(wǎng)絡(luò)開銷)阀湿。簡單穩(wěn)定。無外部庫依賴瑰妄,單線程模型陷嘴。
客戶端語言多。
持久化(支持兩種 持久化 方式
RDB
和AOF
)灾挨。主從復(fù)制(分布式的基礎(chǔ))。
高可用(
Redis Sentinel
)竹宋,分布式(Redis Cluster
)和 水平擴(kuò)容劳澄。
2. Redis的應(yīng)用場景
2.1. 緩存
合理的使用 緩存 能夠明顯加快訪問的速度,同時(shí)降低數(shù)據(jù)源的壓力逝撬。這也是 Redis
最常用的功能浴骂。Redis
提供了 鍵值過期時(shí)間(EXPIRE key seconds
)設(shè)置,并且也提供了靈活控制 最大內(nèi)存 和 內(nèi)存溢出 后的 淘汰策略宪潮。
2.2. 排行榜
每個(gè)網(wǎng)站都有自己的排行榜溯警,例如按照 熱度排名 的排行榜,發(fā)布時(shí)間 的排行榜狡相,答題排行榜 等等梯轻。Redis
提供了 列表(list
)和 有序集合(zset
)數(shù)據(jù)結(jié)構(gòu),合理的使用這些數(shù)據(jù)結(jié)構(gòu)尽棕,可以很方便的構(gòu)建各種排行榜系統(tǒng)喳挑。
2.3. 計(jì)數(shù)器
計(jì)數(shù)器 在網(wǎng)站應(yīng)用中非常重要。例如:點(diǎn)贊數(shù)加 1
滔悉,瀏覽數(shù) 加 1
伊诵。還有常用的 限流操作,限制每個(gè)用戶每秒 訪問系統(tǒng)的次數(shù) 等等回官。Redis
支持 計(jì)數(shù)功能(INCR key
)曹宴,而且計(jì)數(shù)的 性能 也非常好,計(jì)數(shù)的同時(shí)也可以設(shè)置 超時(shí)時(shí)間歉提,這樣就可以 實(shí)現(xiàn)限流笛坦。
2.4. 社交網(wǎng)絡(luò)
贊/踩区转,粉絲,共同好友/喜好版扩,推送废离,下拉刷新等是社交網(wǎng)站必備的功能。由于社交網(wǎng)站 訪問量通常比較大礁芦,而且 傳統(tǒng)的數(shù)據(jù)庫 不太適合保存這類數(shù)據(jù)蜻韭,Redis
提供的 數(shù)據(jù)結(jié)構(gòu) 可以相對比較容易實(shí)現(xiàn)這些功能。
2.5. 消息隊(duì)列
Redis
提供的 發(fā)布訂閱(PUB/SUB
)和 阻塞隊(duì)列 的功能宴偿,雖然和專業(yè)的消息隊(duì)列比湘捎,還 不夠強(qiáng)大,但對于一般的消息隊(duì)列功能基本滿足窄刘。
3. Redis的安裝配置
下面介紹一下 Redis
的安裝流程窥妇。我會(huì)按照如下的順序,逐步搭建出 高可用 的 Redis
緩存服務(wù)器集群娩践。
-
Redis
單機(jī)服務(wù)器 搭建 -
Redis
主從復(fù)制 搭建 -
Redis-Sentinel
高可用 搭建
3.1. Redis單機(jī)服務(wù)器安裝
3.1.1. 下載并解壓
首先從 Redis
官網(wǎng)下載 Redis
源代碼并解壓活翩,這里使用的是 最新穩(wěn)定版本 4.0.11
。依次執(zhí)行如下命令:
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. 編譯并安裝
下載并解壓完畢后翻伺,則對 源碼包 進(jìn)行 編譯安裝材泄,這里 Redis
安裝路徑為 /usr/local/redis
。
注意:
make install PREFIX
=目標(biāo)安裝路徑
cd /usr/local/redis-4.0.11
make install PREFIX=/usr/local/redis
安裝完成時(shí)吨岭,/usr/local/redis/bin
目錄下會(huì)生成的幾個(gè)可執(zhí)行的文件拉宗。
可執(zhí)行文件 | 作用 |
---|---|
redis-server | 啟動(dòng) redis 服務(wù) |
redis-cli redis | 命令行客戶端 |
redis-benchmark | redis 基準(zhǔn)測試工具 |
redis-check-aof | redis AOF 持久化文件檢測和修復(fù)工具 |
redis-check-dump | redis RDB 持久化文件檢測和修復(fù)工具 |
redis-sentinel | 啟動(dòng) redis sentinel |
復(fù)制 Redis
相關(guān)命令到 /usr/local/bin
目錄下,這樣就可以直接執(zhí)行這些命令辣辫,不用寫全路徑旦事。
$ 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
默認(rèn)是 6379
。
$ sudo cp /usr/local/redis-4.0.11/redis.conf /usr/local/
Redis
配置文件主要參數(shù)解析參考:
# redis進(jìn)程是否以守護(hù)進(jìn)程的方式運(yùn)行葬馋,yes為是卖鲤,no為否(不以守護(hù)進(jìn)程的方式運(yùn)行會(huì)占用一個(gè)終端)。
daemonize no
# 指定redis進(jìn)程的PID文件存放位置
pidfile /var/run/redis.pid
# redis進(jìn)程的端口號
port 6379
# 綁定的主機(jī)地址
bind 127.0.0.1
# 客戶端閑置多長時(shí)間后關(guān)閉連接畴嘶,默認(rèn)此參數(shù)為0即關(guān)閉此功能
timeout 300
# redis日志級別蛋逾,可用的級別有debug.verbose.notice.warning
loglevel verbose
# log文件輸出位置,如果進(jìn)程以守護(hù)進(jìn)程的方式運(yùn)行窗悯,此處又將輸出文件設(shè)置為stdout的話区匣,就會(huì)將日志信息輸出到/dev/null里面去了
logfile stdout
# 設(shè)置數(shù)據(jù)庫的數(shù)量,默認(rèn)為0可以使用select <dbid>命令在連接上指定數(shù)據(jù)庫id
databases 16
# 指定在多少時(shí)間內(nèi)刷新次數(shù)達(dá)到多少的時(shí)候會(huì)將數(shù)據(jù)同步到數(shù)據(jù)文件
save <seconds> <changes>
# 指定存儲(chǔ)至本地?cái)?shù)據(jù)庫時(shí)是否壓縮文件蟀瞧,默認(rèn)為yes即啟用存儲(chǔ)
rdbcompression yes
# 指定本地?cái)?shù)據(jù)庫文件名
dbfilename dump.db
# 指定本地?cái)?shù)據(jù)問就按存放位置
dir ./
# 指定當(dāng)本機(jī)為slave服務(wù)時(shí)沉颂,設(shè)置master服務(wù)的IP地址及端口,在redis啟動(dòng)的時(shí)候他會(huì)自動(dòng)跟master進(jìn)行數(shù)據(jù)同步
slaveof <masterip> <masterport>
# 當(dāng)master設(shè)置了密碼保護(hù)時(shí)悦污,slave服務(wù)連接master的密碼
masterauth <master-password>
# 設(shè)置redis連接密碼铸屉,如果配置了連接密碼,客戶端在連接redis是需要通過AUTH<password>命令提供密碼切端,默認(rèn)關(guān)閉
requirepass footbared
# 設(shè)置同一時(shí)間最大客戶連接數(shù)彻坛,默認(rèn)無限制。redis可以同時(shí)連接的客戶端數(shù)為redis程序可以打開的最大文件描述符踏枣,如果設(shè)置 maxclients 0昌屉,表示不作限制。當(dāng)客戶端連接數(shù)到達(dá)限制時(shí)茵瀑,Redis會(huì)關(guān)閉新的連接并向客戶端返回 max number of clients reached 錯(cuò)誤信息
maxclients 128
# 指定Redis最大內(nèi)存限制间驮,Redis在啟動(dòng)時(shí)會(huì)把數(shù)據(jù)加載到內(nèi)存中,達(dá)到最大內(nèi)存后马昨,Redis會(huì)先嘗試清除已到期或即將到期的Key竞帽。當(dāng)此方法處理后,仍然到達(dá)最大內(nèi)存設(shè)置鸿捧,將無法再進(jìn)行寫入操作屹篓,但仍然可以進(jìn)行讀取操作。Redis新的vm機(jī)制匙奴,會(huì)把Key存放內(nèi)存堆巧,Value會(huì)存放在swap區(qū)
maxmemory<bytes>
# 指定是否在每次更新操作后進(jìn)行日志記錄,Redis在默認(rèn)情況下是異步的把數(shù)據(jù)寫入磁盤泼菌,如果不開啟谍肤,可能會(huì)在斷電時(shí)導(dǎo)致一段時(shí)間內(nèi)的數(shù)據(jù)丟失。因?yàn)閞edis本身同步數(shù)據(jù)文件是按上面save條件來同步的灶轰,所以有的數(shù)據(jù)會(huì)在一段時(shí)間內(nèi)只存在于內(nèi)存中谣沸。默認(rèn)為no。
appendonly no
# 指定跟新日志文件名默認(rèn)為appendonly.aof
appendfilename appendonly.aof
# 指定更新日志的條件笋颤,有三個(gè)可選參數(shù) - no:表示等操作系統(tǒng)進(jìn)行數(shù)據(jù)緩存同步到磁盤(快)乳附,always:表示每次更新操作后手動(dòng)調(diào)用fsync()將數(shù)據(jù)寫到磁盤(慢,安全)伴澄, everysec:表示每秒同步一次(折衷赋除,默認(rèn)值);
appendfsync everysec
- 設(shè)置后臺(tái)啟動(dòng)
由于 Redis
默認(rèn)是 前臺(tái)啟動(dòng)非凌,不建議使用举农。修改 Redis
配置文件,把 daemonize no
改為 daemonize yes
敞嗡。
daemonize yes
- 設(shè)置遠(yuǎn)程訪問
Redis
默認(rèn)只允許 本機(jī)訪問颁糟,把 bind
修改為 bind 0.0.0.0
此設(shè)置會(huì)變成 允許所有遠(yuǎn)程訪問航背。如果想指定限制訪問,可設(shè)置對應(yīng)的 IP
棱貌。
bind 0.0.0.0
- 配置
Redis
日志記錄
找到 logfile
配置玖媚,默認(rèn)是:logfile ""
,改為自定義日志文件路徑婚脱。
logfile /var/log/redis_6379.log
- 設(shè)置
Redis
請求密碼
把 requirepass
修改為 123456
今魔,修改之后重啟下服務(wù)
requirepass "123456"
有了密碼之后,進(jìn)入客戶端障贸,就得這樣訪問:
$ redis-cli -h 127.0.0.1 -p 6379 -a 123456
3.1.4. Redis的常用命令
- 啟動(dòng)命令
$ redis-server /usr/local/redis.conf
- 關(guān)閉命令
$ redis-cli -h 127.0.0.1 -p 6379 shutdown
- 查看是否啟動(dòng)
$ ps -ef | grep redis
- 進(jìn)入客戶端
$ redis-cli
- 關(guān)閉客戶端
$ redis-cli shutdown
注意:不建議使用
kill -9
错森,這種方式不但不會(huì)做持久化操作,還會(huì)造成緩沖區(qū)等資源不能優(yōu)雅關(guān)閉篮洁。極端情況下造成AOF
和 復(fù)制丟失數(shù)據(jù) 的情況涩维。shutdown
還有一個(gè)參數(shù),代表是否在關(guān)閉redis
前袁波,生成 持久化文件激挪,命令為redis-cli shutdown nosave|save
。
- 設(shè)置為開機(jī)自動(dòng)啟動(dòng)
$ echo "redis-server /usr/local/redis.conf" >> /etc/rc.local
- 開放防火墻端口
# 添加規(guī)則
iptables -I INPUT -p tcp -m tcp --dport 6379 -j ACCEPT
# 保存規(guī)則
service iptables save
# 重啟iptables
service iptables restart
3.1.5. 注冊Redis為系統(tǒng)服務(wù)
在 /etc/init.d
目錄下添加 Redis
服務(wù)的 啟動(dòng)锋叨,暫停 和 重啟 腳本:
$ sudo /etc/init.d/redis
腳本的內(nèi)容如下:
#!/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
賦予腳本文件可執(zhí)行權(quán)限:
$ chmod 755 /etc/init.d/redis
啟動(dòng)垄分、停止和重啟 redis
服務(wù):
service redis start
service redis stop
service redis restart
3.2. Redis主從復(fù)制集群安裝
3.2.1. Redis-Server配置說明
角色 | IP地址 | 端口號 |
---|---|---|
Redis Master | 10.206.20.231 | 16379 |
Redis Slave | 10.206.20.231 | 26379 |
3.2.2. Redis主從架構(gòu)配置
- 編輯 從機(jī) 的
Redis
配置文件,找到210
行(大概)-#slaveof <masterip> <masterport>
娃磺。去掉該注釋薄湿,填寫 主服務(wù)器 的IP
和 端口。
slaveof 10.206.20.231 16379
- 如果 主服務(wù)器 設(shè)置了密碼偷卧,還需要找到
masterauth <master-password>
這一行豺瘤,去掉注釋,改為masterauth
的主機(jī)密碼听诸。
masterauth 123456
- 配置完成后重啟 從服務(wù)器 的
Redis
服務(wù)坐求。
$ service redis restart
- 重啟完成之后,進(jìn)入 主服務(wù)器 的
redis-cli
模式下晌梨,命令為redis-cli -h 127.0.0.1 -p 16379 -a 123456
桥嗤。輸入INFO replication
查詢到 當(dāng)前主機(jī) 的Redis
的狀態(tài),連接上 主服務(wù)器 的 從服務(wù)器仔蝌。
Redis
主服務(wù)器 的配置文件:
- 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
從服務(wù)器 的配置文件:
- 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
主服務(wù)器 的狀態(tài)如下:
# 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
從服務(wù)器 的狀態(tài)如下:
# 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主從配置驗(yàn)證
上面完成了基本的 主從配置泛领,可以簡單的測試一下效果:
- 進(jìn)入 主服務(wù)器 的
redis-cli
模式,然后set
一個(gè)值敛惊,比如:
> set master_port "16379"
OK
- 切換進(jìn)入 從服務(wù)器 的
redis-cli
的模式渊鞋,查詢剛剛設(shè)置的值看是否存在:
> get master_port
"16379"
此時(shí),我們可以發(fā)現(xiàn)是可以獲取到值的,Redis
的 主從模式 正常工作锡宋。
小結(jié)
本文簡單的說明了 Redis
的相關(guān) 特性 和 應(yīng)用場景儡湾,詳細(xì)地給出 Redis
單服務(wù)器的 編譯,安裝执俩,配置 和 啟動(dòng)盒粮,進(jìn)一步引入了 Redis
主從復(fù)制 的相關(guān)原理和詳細(xì)配置。關(guān)于 Redis
的 高可用機(jī)制 和 集群搭建奠滑,下文將給出詳細(xì)的說明。
參考
《Redis 開發(fā)與運(yùn)維》
歡迎關(guān)注技術(shù)公眾號: 零壹技術(shù)棧
本帳號將持續(xù)分享后端技術(shù)干貨妒穴,包括虛擬機(jī)基礎(chǔ)宋税,多線程編程,高性能框架讼油,異步杰赛、緩存和消息中間件,分布式和微服務(wù)矮台,架構(gòu)學(xué)習(xí)和進(jìn)階等學(xué)習(xí)資料和文章乏屯。