安裝
redis是C語言編寫的, 要先安裝gcc編譯器
yum -y install gcc automake autoconf libtool make
下載redis壓縮包并解壓到/usr/local/
wget http://download.redis.io/releases/redis-5.0.8.tar.gz
tar -zxvf redis-5.0.8.tar.gz -C /usr/local/
進(jìn)入redis根目錄, 編譯redis代碼
cd redis-5.0.8 && redismake
安裝redis
make PREFIX=/usr/local/redis-5.0.8 install
安裝完成后redis根目錄下會新增bin目錄, 里面放著redis的可執(zhí)行文件
配置文件
redis根目錄下創(chuàng)建conf目錄統(tǒng)一存放配置文件,新建redis.conf配置文件
使用配置文件啟動redis
./redis-server conf/redis.conf
基本配置參數(shù)說明
bind 127.0.0.1
限制訪問IP
port 6379
訪問端口
daemonize yes
后臺啟動
dir /usr/local/redis-5.0.8/data
工作目錄
logfile "redis.log"
日志輸出文件捏膨, 在工作目錄中
maxmemory
最大占用內(nèi)存
maxmemory-policy noeviction
淘汰策略
啟動連接和關(guān)閉
啟動redis服務(wù)有3種方式
- 直接使用bin目錄下的
bin/redis-server
- 配置動態(tài)參數(shù)啟動
bin/redis-server --port=6379
-
使用配置文件啟動(推薦)
bin/redis-server conf/redis.conf
連接redis客戶端
bin/redis-cli -h 127.0.0.1 -p 6379
正常關(guān)閉redis服務(wù)
bin/redis-cli.sh -h 127.0.0.1 -p 6379 shutdown
如果配置了密碼香拉, 連接和關(guān)閉時需要加上-a 參數(shù), 如
bin/redis-cli -h 127.0.0.1 -p 6379 -a ${password} shutdown
常用命令
keys *
查詢所有的key迈勋,比較耗時,不建議使用
dbsize
查詢數(shù)據(jù)總數(shù)
exists key
查詢key存不存在,1:存在 , 0 :不存在
expire key seconds
給key設(shè)置有效期, 單位s
ttl key
查詢key的剩余有效時間隧膏, -1:永久有效,-2:無效的key或已刪除
persist key
設(shè)置key永久有效
del key
刪除key嚷那,1:刪除成功胞枕,0:刪除失敗
type key
查看key的數(shù)據(jù)類型
info
查看服務(wù)器信息
常用數(shù)據(jù)類型
redis為什么這么快
- 內(nèi)存存儲
- 單線程處理數(shù)據(jù),避免上下文切換和靜態(tài)消耗车酣,F(xiàn)IFO曲稼,無需加鎖
- 使用epoll模型索绪,非阻塞IO
數(shù)據(jù)淘汰策略
volatile-lru
優(yōu)先從設(shè)定了過期時間的數(shù)據(jù)中,刪除長時間未使用的數(shù)據(jù)
allkeys-lru
從所有的數(shù)據(jù)中刪除長時間未使用的數(shù)據(jù)
volatile-random
優(yōu)先從設(shè)置了過期時間的數(shù)據(jù)中隨機(jī)刪除
allkeys-random
從所有數(shù)據(jù)中隨機(jī)刪除
volatile-lfu
從設(shè)置了過期時間的數(shù)據(jù)中贫悄,刪除使用次數(shù)最少的數(shù)據(jù)
allkeys-lfu
從所有的數(shù)據(jù)中刪除使用次數(shù)最少的數(shù)據(jù)
volatile-ttl
對設(shè)置了過期時間的數(shù)據(jù)進(jìn)行排序瑞驱,刪除剩余有效時間最少的數(shù)據(jù)
noeviction
內(nèi)存不足時拋異常,不會刪除數(shù)據(jù)
數(shù)據(jù)持久化
RDB(快照)
快照是將內(nèi)存中的數(shù)據(jù)通過序列化并進(jìn)行壓縮窄坦,然后存入硬盤中唤反。重啟redis時會讀取rdb文件恢復(fù)數(shù)據(jù)。
觸發(fā)方式:save命令(同步)
bgsave命令(異步)
配置同步策略
三種方式
自動觸發(fā)機(jī)制:全量復(fù)制
debug reload
shutdown正常退出
會自動觸發(fā)數(shù)據(jù)同步
配置:
save 60 10000
備份策略
dbfilename dump_6379.rdb
RDB備份文件
stop-writes-on-bgsave-error yes
是否在出現(xiàn)錯誤的時候終止RDB備份
rdbcompression yes
RDB備份文件是否進(jìn)行壓縮
缺點(diǎn):
1)備份不及時鸭津,系統(tǒng)宕機(jī)可能會丟失數(shù)據(jù)
2)性能較差彤侍。RDB不是增量備份,每次備份都會把所有的數(shù)據(jù)傳輸?shù)酱疟P逆趋。AOF
AOF是把執(zhí)行的命令寫入到緩沖區(qū)盏阶,然后追加寫入到磁盤中。通過讀取并執(zhí)行這些命令來恢復(fù)數(shù)據(jù)
備份策略:
always
每執(zhí)行一條命令就備份到磁盤
everysec
每隔一秒備份一次
no
備份時機(jī)由操作系統(tǒng)決定
重寫:對寫入.aof文件的命令進(jìn)行優(yōu)化
配置:
appendonly yes
是否開啟AOF備份模式
appendfilename "appendonly_6379.aof"
AOF備份文件
appendfsync everysec
AOF備份策略
no-appendfsync-on-rewrite yes
重寫的時候是否執(zhí)行AOF備份操作
auto-aof-rewrite-percentage 100
觸發(fā)重寫的文件大小增長百分比
auto-aof-rewrite-min-size 64m
觸發(fā)重寫的文件大小RDB和AOF混合模式
配置:
aof-use-rdb-preamble yes
使用RDB和AOF混合模式
主從復(fù)制
可以提高讀數(shù)據(jù)的qps闻书。設(shè)置方法:
方法1. 在需要設(shè)置為從節(jié)點(diǎn)的redis客戶端使用命令
slaveof host port
方法2. 在配置文件中配置master的地址和端口
replicaof host port
哨兵機(jī)制
哨兵服務(wù)可以監(jiān)測redis服務(wù)的運(yùn)行狀態(tài)名斟,當(dāng)有master服務(wù)器掛掉,會從剩余服務(wù)器中選舉出新的master并修改其他slave服務(wù)器的master連接魄眉。
優(yōu)點(diǎn):可以解決單點(diǎn)故障砰盐,提高讀數(shù)據(jù)的qps
缺點(diǎn):無法提高寫請求的qps,存儲容量有局限性
配置
bind 127.0.0.1
限制訪問IP
port 26380
訪問端口
daemonize yes
后臺啟動
dir /usr/local/redis-5.0.8/data
工作目錄
logfile "sentinel_26380.log"
日志輸出文件坑律, 在工作目錄中
protected-mode no
是否開啟保護(hù)模式
告訴sentinel去監(jiān)聽指定ip和port的一個master岩梳,master-name是集群的名字,quorum是指定當(dāng)多少個sentinel認(rèn)為這個master失效時晃择,master才算真正失效
sentinel monitor ${master-name} ${ip} ${port} ${quorum}
master失效多長時間才會被sentinel認(rèn)為是不可用的冀值,單位毫秒,默認(rèn)30秒
sentinel down-after-milliseconds master-name 30000
在發(fā)生failover主備切換時最多可以有多少個slave同時對新的master進(jìn)行同步藕各。這個數(shù)字越小池摧,同步時間越長,數(shù)字越大激况,就有越多的slave因?yàn)閞eplication操作而不可用”炱牵可以設(shè)置為1來保證同時只有一個slave不能處理請求
sentinel parallel-syncs ${master-name} 1
master服務(wù)器失效之后隔多長時間再次檢查該服務(wù)器的狀態(tài)
sentinel failover-timeout ${master-name} 180000
啟動
bin/redis-sentinel conf/sentinel_26380.conf
集群
相對于哨兵機(jī)制:
- 有多臺寫服務(wù)器乌逐,可以提高寫數(shù)據(jù)的qps
- 數(shù)據(jù)分散存儲,提高數(shù)據(jù)量
- 提高帶寬创葡、網(wǎng)絡(luò)流量
配置:
cluster-enabled yes
開啟集群模式
cluster-config-file node_6379.conf
集群服務(wù)器的信息
cluster-node-timeout 15000
節(jié)點(diǎn)間通信超時時間
cluster-require-full-coverage no
集群中一個節(jié)點(diǎn)出現(xiàn)故障浙踢,是否停用整個集群
數(shù)據(jù)分區(qū)規(guī)則
順序分區(qū)
特點(diǎn):
1)數(shù)據(jù)容易傾斜
2)鍵值分布和業(yè)務(wù)相關(guān)
3)支持批量操作
4)可以順序訪問-
Hash分區(qū)
特點(diǎn):
1)數(shù)據(jù)分散度高
2)鍵值分布與業(yè)務(wù)無關(guān)
3)支持批量操作
4)無法順序訪問Hash分區(qū)方案:
1)節(jié)點(diǎn)取余
根據(jù)Hash值 % 分區(qū)數(shù)量
進(jìn)行分區(qū)
注意點(diǎn):節(jié)點(diǎn)取余擴(kuò)容時,為了減少數(shù)據(jù)的遷移量灿渴,盡量翻倍擴(kuò)容(50%遷移量)2)一致性Hash
采用Hash環(huán)的概念洛波,Hash結(jié)果是int類型胰舆,有0-2^32個數(shù)值,這些數(shù)值連在一起首尾相接形成一個環(huán)蹬挤,在這個 環(huán)上均勻的分配節(jié)點(diǎn)缚窿,每個節(jié)點(diǎn)負(fù)責(zé)一塊區(qū)域Hash環(huán)@2x.png
當(dāng)插入或查詢一個key時,首先對key做Hash運(yùn)算得到Hash值焰扳,然后根據(jù)這個Hash值順時針找到對應(yīng)的節(jié)點(diǎn)進(jìn)行存儲和讀取
特點(diǎn):
① 在客戶端對key進(jìn)行Hash運(yùn)算倦零,然后找到對應(yīng)的節(jié)點(diǎn)進(jìn)行存儲和讀取
② 擴(kuò)容或者刪除節(jié)點(diǎn)只會影響下一個相鄰的節(jié)點(diǎn),不會對其他節(jié)點(diǎn)產(chǎn)生影響
③ 翻倍擴(kuò)容吨悍,擴(kuò)容時在每塊區(qū)域分別添加新的節(jié)點(diǎn)扫茅,以保證最小數(shù)據(jù)遷移量和負(fù)載均衡
④ 擴(kuò)容后數(shù)據(jù)不會自動遷移,需要在客戶端手動遷移數(shù)據(jù)育瓜。如果是緩存數(shù)據(jù)葫隙,可以從數(shù)據(jù)庫查詢之后再進(jìn)行緩存,無需遷移數(shù)據(jù)躏仇,所以Hash環(huán)比較適合做緩存
3)虛擬槽
redis將16384個虛擬槽平均分配到節(jié)點(diǎn)服務(wù)器中停蕉,每個節(jié)點(diǎn)服務(wù)器都知道其他服務(wù)器中有哪些槽。操作時會對key進(jìn)行CRC16(key) % 16383
運(yùn)算钙态,得到的結(jié)果就是所在的槽的編號慧起,節(jié)點(diǎn)服務(wù)器接收到請求后,如果計(jì)算出來的槽在當(dāng)前節(jié)點(diǎn)册倒,就直接進(jìn)行數(shù)據(jù)操作蚓挤,如果不在當(dāng)前節(jié)點(diǎn),會連接到對應(yīng)的服務(wù)節(jié)點(diǎn)進(jìn)行操作驻子。
集群搭建流程
- 配置并啟動集群的服務(wù)器
從redis5版本官方提供了一個命令可以自動發(fā)現(xiàn)服務(wù)器灿意、分配虛擬槽和設(shè)置從服務(wù)器,無需手動操作后面2 3 4 步
redis-cli --cluster create ${host1:port1 host2:port2 ...} --cluster -replicas ${slave_ratio}
slave_ratio
是從服務(wù)器占比崇呵,設(shè)置為2就是主從1:2缤剧,設(shè)置為3就是主從1:3
發(fā)現(xiàn)其他服務(wù)器
cluster meet ${host} ${port}
發(fā)現(xiàn)指定服務(wù)器
cluster nodes
或者cluster info
命令查看已發(fā)現(xiàn)的服務(wù)器信息分配虛擬槽
虛擬槽只分配給master服務(wù)器
虛擬槽一共16384個,可以通過腳本循環(huán)執(zhí)行下面命令給指定服務(wù)器分配虛擬槽
redis-cli -h ${host} -p ${port} cluster addslots ${slot}
設(shè)置從服務(wù)器
redis-cli -h ${host} -p ${port} cluster replicate ${master_node_id}
master_node_id
可以通過cluster nodes
命令查看
Redis常見問題
緩存穿透:
緩存穿透一般出現(xiàn)在查詢數(shù)據(jù)庫中不存在的數(shù)據(jù)域慷。緩存沒有命中就會查數(shù)據(jù)庫荒辕, 數(shù)據(jù)庫查不到也不寫入緩存,就會導(dǎo)致這個不存在的數(shù)據(jù)每次都要查詢數(shù)據(jù)庫犹褒,增加數(shù)據(jù)庫的壓力
解決方案:
1)單個key穿透抵窒,可以將這個key在redis中緩存一個空值,設(shè)置較短的有效期叠骑,防止高頻率的查詢數(shù)據(jù)庫
2)多個key穿透李皇,可以通過驗(yàn)證key的合法性來決定是否查詢數(shù)據(jù)庫。如果數(shù)據(jù)量不大宙枷,可以把所有的key放到redis的set集合中掉房,查詢時判斷key如果在set集合中茧跋,再查數(shù)據(jù)庫。如果數(shù)據(jù)量上億卓囚,可以考慮使用布隆過濾器來實(shí)現(xiàn)瘾杭。雪崩:
雪崩是指大量緩存在同一時間失效,所有的請求都會查詢數(shù)據(jù)庫捍岳,造成數(shù)據(jù)庫崩潰富寿。
解決方案:
1)盡量讓key的過期時間均勻分布
2)控制同一個key查詢數(shù)據(jù)庫的線程數(shù)量,在查詢數(shù)據(jù)庫之前再次查詢緩存锣夹。常見的限流算法有計(jì)數(shù)算法页徐、滑動窗口、令牌桶银萍、漏桶等
-
熱點(diǎn)key:
熱點(diǎn)key是指某個key的訪問頻率非常頻繁变勇,導(dǎo)致redis服務(wù)器壓力劇增,無法保證正常提供服務(wù)
解決方案:
1)橫向擴(kuò)容贴唇,增加集群服務(wù)器提高讀數(shù)據(jù)的能力
2) 使用本地緩存搀绣。把熱點(diǎn)數(shù)據(jù)緩存在本地服務(wù)器的內(nèi)存中,減少redis的訪問量
SpringBoot項(xiàng)目集成Redis
- 導(dǎo)入redis包
spring-boot-starter-data-redis
和連接池包commons-pool2
- yml文件中配置redis
redis:
cluster:
nodes: 127.0.0.1:6380,127.0.0.1:6381,127.0.0.1:6382,127.0.0.1:6384,127.0.0.1:6385,127.0.0.1:6386
lettuce:
pool:
min-idle: 10
max-idle: 10
max-active: 10
max-wait: 150000
- 使用redisTemplate操作redis
@Autowired
private RedisTemplate redisTemplate;
// 拿到ValueOperations對象操作redis
ValueOperations<String,String> ops = redisTemplate.opsForValue();
String str = ops.get("key");