Redis-Linux-高階
開啟Linux 命令視窗,使用root許可權,然後下載redis 的壓縮包,這裡下載4.0.0 版本的,
redis 是C 語言寫的,要先確定 虛擬機器安裝有 gcc 沒有的話下載安裝:yum install gcc
步驟:
1、先 cd / 切換到 根目錄
2、輸入命令:wget http://download.redis.io/releases/redis-4.0.0.tar.gz
3、然後解壓:tar zxvf redis-4.0.0.tar.gz
4、進入解壓好的資料夾裡:cd redis-4.0.0
// 可以先看看系統預設安裝目錄,和redis 要安裝到的目錄 cat Makefile
// 編譯:make
5、可以直接編譯 並安裝:make install
6、 安裝完以後,cd src 進到裡面的src 目錄,然後ll 可以看到安裝好的redis
7、redis-server 直接回車,就啟動了redis
8、 啟動以後,就不用管了,再複製一個會話,開啟客戶端去連服務端 試試:
正常使用,連線成功
如果要啟動多臺redis 解決辦法:src的redis 安裝目錄 下執行命令:redis-server --port 6380 回車
這樣redis 的埠就變成6380 了,再去用客戶端連線就會失敗,要連線的是:redis-cli -p 6380 就能連線成功了
上面兩種方式不推薦,一般在企業裡啟動的是
先cd redis-4.0.0 目錄下,找到一個redis.conf 的redis 配置檔案,
然後輸入命令:cat redis.conf | grep -v "#" |grep -v "^$" > redis-6379.conf
就是複製一份redis.conf ,取名redis-6379.conf ,當然,都在在同一目錄下,然後編輯這個redis-6379.conf 檔案,只留下:
port 6379 daemonize yes logfile "6379.log" dir /redis-4.0.0/data
中間出錯的話,就先提前在redis-4.0.0 目錄下新建一個data ,然後再 儲存這個redis-6379.conf 檔案
然後就可以輸出命令:redis-server redis-6379.conf 啟動redis 服務
redis-cli 啟動客戶端小試一下
redis 的安裝目錄下應該再見一個資料夾 conf ,不然以後要起多個redis 服務,豈不是好多的配置檔案,太亂了:
使用命令:mkdir conf 新建一個conf 目錄
然後把這個 6379 的配置檔案剪下到 conf 目錄裡:mv redis-6379.conf conf
這樣的話,啟動redis 服務命令是:redis-server conf/redis-6379.conf
啟動多個redis 服務:
先 cd conf 到conf 目錄下,然後:cp redis-6379.conf redis-6380.conf 複製一個6379 的檔案 6380
然後 vim redis-6380.conf 編寫6380 的配置:
只需要改這些,然後儲存退出就可以了,這樣的話 redis-server conf/redis-6380.conf 就啟動了
客戶端啟動的話,redis-cli -p [埠號] 指定埠號
redis-cli -h [IP地址] 指定IP地址
持久化
RDB:快照方式,執行一次命令,就儲存一次
執行儲存命令:save 每次set 資料時候每儲存一次,就會再那個data 檔案裡的rdb 檔案生出一條資訊,要手動執行的。。
比如要設定 6379 這個埠的rdb 檔案儲存,先去把 redis-6379.conf 這個檔案編寫一下:
然後就可以正常使用了,比如這個 dump-6379.rdb 檔案會在data 目錄下生成,
這樣就把資料持久化了,比如把6379 的這個服務的記憶體清除,然後重新啟動6379 這個埠,
然後去客戶端一樣能查詢之前儲存過的資料,因為當6379 重新啟動時候,資料就已經被載入了
save 指令的工作原理
當多個客戶端 訪問服務 時候,是有先後順序的,因為redis 是單執行緒的,這樣就類似於訊息佇列那種的吧。。。
如果有一個save 指定執行過長,其他客戶端就會等著這個 save 指令,
所以線上環境不建議使用save 指令,因為會很拉低伺服器的效能,可能造成嚴重的阻塞!
解決方法:bgsave 指令:手動啟動後臺儲存操作,但不是立即執行的
bgsave 使用:一樣是在客戶端操作,比如set 完資料然後就bgsave,然後會給提示資訊:Background saving started 後臺執行,save 是馬上執行,
bgsave 執行原理
自動執行持久化命令:
找到相對應要配置的服務端 配置檔案:
rdb 的啟動方式:
1、伺服器 執行過程中重啟會啟動 命令:debug reload
2、關閉伺服器時候指定儲存資料 命令:shutdown save
3、主從複製時候,後面才會講到
RDB 的缺點:
儲存資料量大,效率就低,
基於快照思想,IO 效能較低,
基於fork 建立子程序,記憶體額外消耗,
宕機可能帶來的資料丟失風險
AOF:不寫入全資料,記錄部分資料,記錄操作過程,對所有操作記錄,排除資料丟失風險
aof 是Redis 持久化的主流方式
AOF 功能開啟:預設是不開啟的。。。
配置: appendonly yes | no 先開啟配置 AOF
AOF 寫資料策略 配置: appendfsync always | everysec | no 然後根據選擇使用方式持久化
always 是有一個命令就儲存一次,拉低了cpu 的效能,不推薦使用,no 是系統預設,是沒辦法控制的
everysec 這種的是一秒儲存一次,不管有多少命令一秒儲存一次,推薦使用,就算丟失也只有一秒的資料
操作配置:
vim 開啟conf 配置資料夾裡的 6379 配置,然後加上AOF 的配置:
appendonly yes
appendfsync everysec
加上配置以後 :wq 儲存,然後執行 6379 的埠:redis-server redis-6379.conf
就可以發現 data 資料夾裡多了一個appendonly.aof 檔案
為了避免以後的aof 持久化檔案過多,建議使用appendonly-xxx埠號.aof 的這種格式
AOF 重寫:提高效率
手動重寫: bgrewriteaof 執行這個命令以後,會返回結果通知,後臺已經開始重寫了
自動重寫: auto-aof-rewrite-min-size [size]
auto-aof-rewrite-percentage [percentage]
RDB 和 AOF 的區別:
事務 redis 事務就是一個命令執行的佇列,將一系列預定義的命令包裝成一個整體,一次性按新增順序執行,直接不被打斷或干擾
一個佇列中、一次性、順序性、不被打斷干擾
事務基本操作:
開啟事務:multi 設定事務開啟位置,後面的所有指令都加在了事務裡
執行事務:exec 設定事務結束位置,同時執行事務,和multi 成對使用,成對出現
在multi 和 exec 中間這一段的所有命令,都在事務裡,操作非常簡單。。
取消事務:discard 終止當前事務,在multi 之後 和 exec 之前使用!
注意:如果在事務中輸入指令錯誤,那麼事務裡將會解析命令錯誤,就會報錯,比如:set 寫成了 est ,就會報錯
如果命令的型別不匹配,也不行,比如:lpush xx 雖然不會報錯,但是結束,執行事務時候就會報錯。但是後面的指令還是會執行!
所以redis 的事務不支援回滾,如果真的出錯了,推薦思路:百度把。。。 因為redis 的事務在企業中用的比較少
事務鎖
用於業務場景:開始事務以後,如果在執行事務之前,被另一個客戶端 或者 其他方法更改或執行了命令 事務裡指定的key ,那個這個事務不會執行了,返回nil 空
watch [key1] [key2]... 只能用在開始事務multi 的前面,不能寫在事務裡面!就是隻能在執行事務之前加 鎖
unwatch 如果在watch key1 key2... 後面加上uwatch 命令,那麼這個鎖就取消了
分散式鎖 比如三個人同時買一個東西,這個東西只有一個,那麼其他兩個人就買不到了
由於數值一直在改變,因為東西在一直賣出去嘛,所以watch 事務鎖已經不能解決這個問題了
解決方案: 使用 setnx 設定一個公共鎖,就是鎖住了公共的方法後,別人都不能用了
setnx lock-key [value]: 比如:set num 10 命令以後,setnx lock-num 1,這個值無所謂,
然後可以incrby num -1 就等於10-1了,然後再釋放鎖:del lock-num
死鎖:比如:正在鎖住的情況下,宕機了,可是鎖還是鎖住了,就像上廁所把門鎖住了,可你卻睡著了。。。。哈哈
解決方案:設定規定時間,長時間不釋放鎖,就把鎖給砸了。。。
expire lock-key [second] 在setnx lock-key value 的下面用expire lock-key second ,比如:expire lock-num 10 十秒後鎖就失效了,當然也可以提前釋放鎖。
pexpire lock-key [milliseconds] 這個是毫秒
一般使用毫秒執行業務比較多,不適合鎖住太長時間
刪除策略
過期資料 就是以前redis 裡面定義的有效期的資料,但是過多,影響了cpu 的效能,給cpu 增加了壓力,但是這些資料又不急著操作
資料刪除策略:
1、定時刪除
建立一個定時器,當 key 設定的有效時間過了時候,由定時器操作,優點就是節約記憶體,缺點就是增加了cpu 的壓力,因為到點了就刪除
總結:定時刪除就是拿處理器的效能換取了記憶體儲存空間,拿時間換空間
2、惰性刪除
和定時刪除對比鮮明,資料的設定時間到期了也不刪除,等到下次再呼叫這個資料時候,提示你資料不存在,這個時候才刪除
優缺點也很明顯,節約了cpu 的效能,但是記憶體壓力就大了
總結:就是拿儲存空間換取處理器效能,拿空間換時間
3、定期刪除
以上兩種策略都太極端了,這裡的定期刪除時折中的方案
redis 裡使用的時惰性刪除 和 定期刪除 這兩種方案
逐出演算法
逐出演算法的8 種配置:
伺服器配置:redis.conf 平常可能用不到,用的很少
設定伺服器守護程序方式執行: daemonize yes | no
繫結主機地址: bind 127.0.0.1
設定伺服器埠號: port 6379
設定資料庫數量: databases 16
這些都是再conf 的各個配置檔案里加上就行了
日誌配置:
伺服器指定日誌記錄級別: loglevel debug | verbose | notice | warning 預設的是verbose
日誌記錄檔名: logfile 埠號.log
客戶端配置:
設定最大連線客戶端數量,預設是無限制的: maxclients 0 達到上限,redis 就關閉新的連線了
客戶端空閒等的時間: timeout 300 300 秒後如果客戶端沒有任何操作,就給關了。取消該功能就設定為 0
高階資料型別: Bitmaps、HyperLogLog、GEO
Bitmaps 是以String 型別二進位制中儲存的位 進行儲存,是做狀態統計的
setbit [key] [二進位制下標位置] [設定數值] 比如:setbit bits 0 1 或者setbit bits 100 1 二進位制長度不要過長,影響效能
獲取:getbit bits 0 返回1
HyperLogLog 做計數統計的
GEO 是做地理位置,心機計算的。用於座標,計算座標點距離,比如地圖軟體、附近人什麼的功能這些裡都用到了
橫座標 縱座標 名字
單位
GEO 算的是水平位置,比如地圖上平面的,如果是比如:山上到山下的位置,在地圖上就是垂直的了,這個是不能計算距離的
測試:
叢集 主從複製、哨兵模式、叢集
主從複製
1、建立連線
推薦使用方法三
比如在 6380埠的伺服器(從表)要連 6379埠號的伺服器(主表),
開啟6380 的配置檔案,加上配置: slaveof 127.0.0.1 6379
主 從 斷開連線:slaveof no one 從 從伺服器客戶端 輸入這個命令就斷開和主機的連線了
2、資料同步
如果由於master 的緩衝區過小,所以導致緩衝區一直存在資料,就會一直主從複製,就造成了死迴圈
解決辦法:在master 伺服器設定一下 緩衝區的大小,多少合適呢?:
執行id:
比如說突然斷電了,或者閃連了,中間斷開了一些時間,那麼在重新連線時候,master 會驗證 之前連線的slave 的執行id ,
從而來判斷是不是剛剛連線的那臺slave ,如果是,那就繼續連結,如果不是,就會連線失敗連線不上的。
執行id 是一個 40位的字元。
偏移量:主要用於部分複製
3、命令傳播
細化全量複製 + 部分複製
心跳機制:主要就是看主、從 伺服器是不是還連線上的,有沒有斷開短接,就是隔一會就ping,然後那邊 pong
哨兵模式
哨兵一般都是配置的奇數,多個哨兵,最少配置三個
哨兵結構搭建:
然後儲存退出
然後把這個複製三份,就是三個哨兵。
這時候可以去把主、從 伺服器都啟動。
然後就可以先啟動一個哨兵:命令:redis-sentinel sentinel-26379.conf
用這個命令把三個哨兵都啟動,然後主、從伺服器,客戶端都正常使用
注意:如果其中master 掛掉了,會有一個哨兵發現這件事,其他哨兵一起來進行投票,決定真的掛掉了,然後再隨機
挑選一個slave 來當master ,確保正常使用
叢集
如果要加一個redis,把其他的儲存的槽分一點到這個新的redis空間裡,redis 叢集之間相互都是聯絡著的,每個redis 都知道各個redis 之間
儲存的槽的位置id,當客戶訪問資料時,如果第一次沒有找對槽的位置,就會返回給伺服器告訴具體的槽在哪個位置,最多兩次就找到了
叢集搭建
找到redis.conf 這個的redis 配置檔案,然後如上圖配置完成儲存退出,然後把這個可以複製衣服呢,改名字redis-6379.conf,
然後複製這個檔案多份,做叢集,最好都是redis-xxx埠號.conf 檔名
然後依次啟動多個redis 的叢集,可以靠各個埠號區分開的
啟動redis 叢集:要事先下載好有ruby 和 gem ,這兩個東西版本要一樣
然後執行 ./redis-trib.rb 這個命令,後面跟上所有的叢集ip 地址:埠號
回車確定這個命令以後,發現資訊打印出來了,告訴你每個redis 的空間的槽是多少,哪些是master 哪些是 slave 等等
然後輸入 yes 確認
然後又會列印資訊,哪些redis叢集加入了,槽 的編號什麼的,redis 叢集搭建完成
存取資料
叢集裡面啟動客戶端的命令是 redis-cli -c 要加上-c 才行,然後set 指令存放一個數據,有返回結果告訴說槽的編號,redis 的埠號等
拿到資料時候,必須要指定端口才行:
主從切換:
如果有一個 從伺服器下線掉線了,master 會告知整個redis 叢集,某個slave 下線了
如果是 主伺服器master 掉了連不上了,slave 會根據你的設定來進行等待連線,一秒連一次,直至發現連不上主伺服器了,
就會有slave 自己謀朝篡位,當上了master 頂上去了,就算原來的主伺服器又上來了,也不能當主服務了,只能當 從服務了
快取預熱
當伺服器剛起來時候,快取裡沒有資料,處理器就會加速運轉導致壓力過大,為了避免資料訪問時候直接從資料庫拿資料,然後放在
快取裡給處理器增加壓力。所以提前把資料放入快取裡
快取雪崩
資料訪問再瞬間突然變得很大,快取裡的資料跟不上,伺服器也會崩了。
快取擊穿
和雪崩有一些相似,redis 記憶體平穩無波動,但是資料庫崩潰。
一般問題是:原因是拿到的都是同一個key ,說明這個key 過期了
快取穿透
在正常節日中,也沒有搶購什麼的業務,伺服器突然崩了,感覺訪問量比過節時候還多,
問題排查發現:redis 有大面積未命中,就是有很多key 無效了,結果發現很多非正常的URL 輪徑的訪問
一般的黑客攻擊會想辦法弄癱瘓公司的伺服器,所以故意弄了很多不正確的url 訪問
解決方案:還是從黑客的角度解決
效能指標監控
好了,redis 可以先告一段落啦~
期待下期吧