Redis 入門權威指北

清風畫扇發表於2021-06-16

前言

看看業務遇到了什麼問題?

我們要從網際網路架構的演變之路開始說起Redis的前世今生。

在我們小的時候,網路世界好像就是隻有通過大屁股桌上型電腦才能進入一樣,彼時的手機只是用來打打電話,發發簡訊,網上購物還沒有在中國普及,Jack Ma 的TB還沒有走進千家萬戶,能上網的使用者只是很少的一部分人群。那時候的場景是登入著QQ,玩著單機的遊戲,連線上視訊觀看都不是那麼流暢。網際網路專案的架構是多麼簡單:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-b0wLvxoP-1623849610589)(D:\Source\image\Redis\web初始架構.png)]

網站初期

那時候的網路專案特點:網站訪問量低,大多數都是以靜態網頁為主,很少有動態互動應用,單個資料庫就可以滿足要求。

網站中期

隨著網際網路迅速的普及,大量的使用者開始使用網際網路,終端裝置越來越多的入門,流量開始急劇增加。大部分使用MySQL架構的網站在資料庫上都開始出現效能問題,Web程式不能再僅僅專注在功能上,同時也在追求效能。開始使用快取技術緩解資料庫壓力,優化資料庫的結構和索引。剛開始時比較流行的是通過檔案快取來緩解資料庫壓力,但是當訪問量繼續增大,檔案快取中的資料不能在多臺Web伺服器之間共享,大量的小檔案IO也帶來了比較高的IO壓力。在這種情況下,Memcache就成了一款非常有效的解決方案。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-9nreu5z7-1623849610591)(D:\Source\image\Redis\MemCache快取.png)]

Memcache作為一個獨立的分散式快取伺服器,為多個Web伺服器提供了一個共享的高效能快取服務,在Memcache伺服器上,又發展了根據hash演算法來進行多臺Memcache快取服務的擴充套件,然後又出現了一致性hash來解決增加或減少快取伺服器導致重新hash帶來的大量快取失效問題。

網站後期

由於資料庫的寫入壓力增加,Memcached只能緩解資料庫的讀取壓力。讀寫集中在一個資料庫上讓資料庫不堪重負,大部分網站開始使用主從複製技術來達到讀寫分離,以提高讀寫效能和讀庫的可擴充套件性。Mysql的master-slave模式成為這個時候的網站標配了:

在這裡插入圖片描述

網站再後期

在Memcached的快取記憶體,MySQL的主從複製,讀寫分離的基礎之上,這時MySQL主庫的寫壓力開始出現瓶頸,而資料量的持續猛增,由於MyISAM使用表鎖,在高併發下會出現嚴重的鎖問題,大量的高併發MySQL應用開始使用InnoDB引擎代替MyISAM。

在這裡插入圖片描述

同時,開始流行使用分表分庫來緩解寫壓力和資料增長的擴充套件問題。這個時候,分表分庫成了一個熱門技術,是業界討論的熱門技術問題。也就在這個時候,MySQL推出了還不太穩定的表分割槽,這也給技術實力一般的公司帶來了希望。雖然MySQL推出了MySQL Cluster叢集,但效能也不能很好滿足網際網路的要求,只是在高可靠性上提供了非常大的保證。

MySQL資料庫也經常儲存一些大文字欄位,導致資料庫表非常的大,在做資料庫恢復的時候就導致非常的慢,不容易快速恢復資料庫。比如1000萬4KB大小的文字就接近40GB的大小,如果能把這些資料從MySQL省去,MySQL將變得非常的小。關聯式資料庫很強大,但是它並不能很好的應付所有的應用場景。MySQL的擴充套件性差(需要複雜的技術來實現),大資料下IO壓力大,表結構更改困難,正是當前使用MySQL的開發人員面臨的問題。

現階段大致架構

在這裡插入圖片描述

隨著資料獲取終端越來越多,以及更多的更快的網路頻寬,資訊不僅僅是之前的業務資料,伴隨著資料多樣化的大資料時代,網際網路時代下如何提升:高可擴、高效能、高併發成為不斷需要提升和攻克的問題。資料的體量急劇增加、資料樣式(不滿足於以前的表格型,如文字、圖片、音訊、視訊,各類終端等等)和資料實時性的要求(比如直播、金融證券。。。。)。如何在各個模組之間提升資料儲存和檢索效率也變得更為重要。

當傳統的關係型資料庫對於一些半結構化、非結構化資料的處理表現不佳的時候,如何儲存處理這些非結構化資料,開始有了新的思考和應對策略。

NoSQL解決方案

直到所謂NoSQL的解決方案問世了,NoSQL是為“為新興的新資料儲存空間命名”問題而創造的一個名詞。Not only SQL。其思想不提供SQL查詢資料的手段,只提供一些比較簡單的、類似於API介面的方式來存取資料。當然,也會有一些工具為NoSQL資料儲存提供了SQL語言的入口。

ACP 定理

一個分散式系統只能同時實現一致性、可用性和分割槽容錯性中的兩個。例如:Vogels(亞馬遜技術長 Werner Vogels)提到的很有現實代表性的一句話:
“在一系列研究結果中發現,在較大型的分散式系統中,由於網路分隔,一致性與可用性不能同時滿足。意味著三個要素最多隻能同時實現兩個,不可能三者兼顧;放寬一致性的要求會提升系統的可用性,提升一致性意味著系統需要犧牲一定的可用性。”

在這裡插入圖片描述

NoSQL優勢:

  • 易擴充套件

    • NoSQL資料庫種類繁多,但它們都有一個共通的特點:就是去除關係型資料庫的“關係型”特點。資料之間無關係,這樣就變得非常容易擴充套件,而相對應的來看:關係型資料庫修改表結構非常困難。這就為專案架構設計提供了更大的擴充套件空間。
  • 大資料量高效能

    • NoSQL資料庫都具有非常高的讀寫效能,尤其在大資料量的情況下,表現同樣優秀。這得益於NoSQL資料庫中資料之間沒有“關係”,資料庫結構簡單。

    • 從快取角度來看,MySQL的Query Cache是表級別的粗粒度快取,假設儲存了100條資料,其中有一條資料修改了,整個快取失效,效率很低。而NoSQL資料庫的快取是記錄級的細粒度快取,任何一條記錄的修改都不影響其他記錄,效率很高。

  • 多樣靈活的資料模型

    • NoSQL資料庫無需事先為要儲存的資料建立欄位,隨時可以儲存自定義的資料格式。而在關聯式資料庫裡,增刪欄位是一件非常麻煩的事情。如果是非常大資料量的表,增減修改欄位簡直就是一個噩夢。

Redis

1. 簡介:

Redis:Remote Dictionary Server(遠端字典伺服器): 是用C語言開發基於記憶體完全開源免費的,遵守 BSD 協議高效能的key-value 儲存系統,是跨平臺的非關係型資料庫。

支援多種型別的資料結構,如 字串(strings)雜湊(hashes)列表(lists)集合(sets)有序集合(sorted sets) 與範圍查詢, bitmapshyperloglogs地理空間(geospatial) 索引半徑查詢。 Redis 內建了 複製(replication)LUA指令碼(Lua scripting)LRU驅動事件(LRU eviction)事務(transactions) 和不同級別的 磁碟持久化(persistence), 並通過 Redis哨兵(Sentinel)和自動 分割槽(Cluster)提供高可用性(high availability)。

以上說明來自官網

整理一下其特性:

  • 1.支援多種資料結構(是指Value的型別,Key的型別只能是String):
    • String:字串
    • Hashes:雜湊,類似於Map<String ,String>,且其KV值只能是String型別
    • list:列表,可以重複的集合且有序,有序既可以通過索引進行操作
    • sets:集合,不可以重複的集合,無序
    • ZSets:有序集合,sorted sets,通過指定score值進行排序的集合
  • 支援資料持久化,可以將記憶體中的資料儲存在磁碟中,重新啟動的時候依據配置進行載入使用
  • Redis 支援資料的備份,即 master-slave 模式的資料備份。

Redis的優勢

  • 1)效能極高 – Redis 能讀的速度是 110000 次/s,寫的速度是 81000 次/s 。

  • 2)豐富的資料型別 – Redis 支援二進位制案例的 Strings, Lists, Hashes, Sets 及Ordered Sets 資料型別操作。

  • 3)原子 – Redis 的所有操作都是原子性的,意思就是要麼成功執行要麼失敗完全不執行。單個操作是原子性的。多個操作也支援事務,即原子性,通過 MULTI 和 EXEC指令包起來。

  • 4)豐富的特性 – Redis 還支援 publish/subscribe, 通知, key 過期等等特性。

Redis 與其他 key-value 儲存有什麼不同?

  • 1.Redis 有著更為複雜的資料結構並且提供對他們的原子性操作,這是一個不同於其他資料庫的進化路徑。Redis 的資料型別都是基於基本資料結構的同時對程式設計師透明,無需進行額外的抽象。

  • 2.Redis 執行在記憶體中但是可以持久化到磁碟,所以在對不同資料集進行高速讀寫時需要權衡記憶體,因為資料量不能大於硬體記憶體。在記憶體資料庫方面的另一個優點是,相比在磁碟上相同的複雜的資料結構,在記憶體中操作起來非常簡單,這樣 Redis可以做很多內部複雜性很強的事情。同時,在磁碟格式方面他們是緊湊的以追加的方式產生的,因為他們並不需要進行隨機訪問。

Redis的應用場景

  1. 熱點資料加速查詢(主要場景),如熱點商品、熱點資訊等訪問量較高的資料
  2. 即時資訊查詢,如公交到站資訊、線上人數資訊等
  3. 時效性資訊控制,如驗證碼控制、投票控制等
  4. 分散式資料共享,如分散式叢集架構中的session分離訊息佇列

2.Redis的安裝

  1. 凡是技術必登其官網,在官網下載redis-xx.xx.xx.tar.gz安裝包並上傳到Linux的/opt目錄;

  2. 在/opt目錄下,解壓安裝包到指定的子目錄下:命令:tar -zxvf redis-xx.xx.xx.tar.gz

  3. 安裝gcc環境,我們需要將原始碼編譯後再安裝,因此需要安裝c語言的編譯環境!不能直接make!我們可以先檢測是否有gcc環境:

    在這裡插入圖片描述

    若沒有gcc直接make會報錯:

在這裡插入圖片描述

安裝gcc:sudo yum install -y gcc-c++ 

使用sudo許可權安裝。如果在沒有安裝gcc環境下,如果執行了make,不會成功!安裝環境後,
第二次make有可能報錯:Jemalloc/jemalloc.h:沒有那個檔案

在這裡插入圖片描述

**解決方案:執行make distclean** 然後再進行make編譯
  1. 編譯,執行make命令!

  2. 編譯完成後,安裝,執行make install命令!

  3. 預設檔案會被安裝到 /usr/local/bin目錄

在這裡插入圖片描述

bin目錄下檔名稱 檔案作用
Redis-benchmark 壓力測試。標準是每秒80000次寫操作,110000次讀操作 (服務啟動起來後執行,類似安兔兔跑分)
Redis-check-aof 修復有問題的AOF檔案
Redis-check-dump 修復有問題的dump.rdb檔案
Redis-sentinel 啟動哨兵,叢集使用
redis-server 啟動伺服器
redis-cli 啟動客戶端

Redis相應的shell命令的操作可以參見菜鳥教程https://www.runoob.com/redis/redis-install.html

3.Redis配置檔案

redis配置檔案為redis安裝的bin目錄下redis.conf檔案

1.單位配置

# 1k => 1000 bytes
# 1kb => 1024 bytes
# 1m => 1000000 bytes
# 1mb => 1024*1024 bytes
# 1g => 1000000000 bytes
# 1gb => 1024*1024*1024 bytes

1k和1kb是不同的,單位的大小寫不敏感

2.include引數

可以將公共的配置放入到一個公共的配置檔案中,然後通過子配置檔案引入父配置檔案中的內容!

將配置按照模組分開!一般將引用公共配置的檔案表示放在配置最前邊:redis 服務啟動需要指定對應的配置檔案,預設是bin下的redis.conf檔案。

################################## INCLUDES ###################################

# If instead you are interested in using includes to override configuration
# options, it is better to use include as the last line.
#
# include /path/to/local.conf
# include /path/to/other.conf

3.Network引數配置

屬性 含義 備註
bind 限定訪問的主機地址 如果沒有bind,就是任意ip地址都可以訪問。生產環境下,需要寫自己應用伺服器的ip地址。
protected-mode 安全防護模式 如果沒有指定bind指令,也沒有配置密碼,那麼保護模式就開啟,只允許本機訪問(loaclhost或127.0.0.1)。
port 埠號 預設是6379
tcp-backlog 網路連線過程中,某種狀態的佇列的長度 redis是單執行緒的,指定高併發時訪問時排隊的長度。超過後,就呈現阻塞狀態。可以理解是一個請求到達後至到接受程式處理前的佇列長度。(一般情況下是運維根據叢集效能調控)高併發情況下,此值可以適當調高。
timeout 超時時間 預設永不超時
tcp-keepalive 對客戶端的心跳檢測間隔時間

4.general引數配置

屬性 含義 備註
daemonize 是否為守護程式模式執行 守護程式模式可以在後臺執行
pidfile 程式id檔案儲存的路徑 配置PID檔案路徑,當redis作為守護程式執行的時候,它會把 pid 預設寫到 /var/redis/run/redis_6379.pid 檔案裡面
loglevel 定義日誌級別 debug(記錄大量日誌資訊,適用於開發、測試階段) verbose(較多日誌資訊) notice(適量日誌資訊,使用於生產環境) warning(僅有部分重要、關鍵資訊才會被記錄)
logfile 日誌檔案的位置 當指定為空字串時,為標準輸出,如果redis以守護程式模式執行,那麼日誌將會輸出到/dev/null
syslog-enabled 是否記錄到系統日誌 要想把日誌記錄到系統日誌服務中,就把它改成 yes
syslog-ident 設定系統日誌的ID
syslog-facility 指定系統日誌設定 必須是 USER 或者是 LOCAL0-LOCAL7 之間的值
databases 設定資料庫數量 預設16,索引為0-15,通過select num 進行選擇

5.其他

屬性 含義 備註
requirepass 設定密碼
maxclients 最大連線數
maxmemory 最大佔用多少記憶體 一旦佔用記憶體超限,就開始根據快取清理策略移除資料如果Redis無法根據移除規則來移除記憶體中的資料,或者設定了“不允許移除”, 那麼Redis則會針對那些需要申請記憶體的指令返回錯誤資訊,比如SET、LPUSH等。
maxmemory-policy noeviction 快取清理策略 (1)volatile-lru:使用LRU演算法移除key,只對設定了過期時間的鍵 (2)allkeys-lru:使用LRU演算法移除key
(3)volatile-random:在過期集合中移除隨機的key,只對設定了過期時間的鍵
(4)allkeys-random:移除隨機的key
(5)volatile-ttl:移除那些TTL值最小的key,即那些最近要過期的key (6)noeviction:不進行移除。針對寫操作,只是返回錯誤資訊
maxmemory-samples 樣本數 樣本數越小,準確率越低,但是效能越好。
LRU演算法和最小TTL演算法都並非是精確的演算法,而是估算值,
所以你可以設定樣本的大小。一般設定3到7的數字。

4.持久化

Redis是怎麼進行持久化的?Redis資料都在記憶體中,記憶體本身就不是一個持久化裝置,一斷電或者重啟不就木有了嘛?

如何避免這個問題或者儘可能減少資料丟失。

我們在開篇的時候介紹redis的時候也講到redis是支援持久化,為此,redis提供了不同級別的持久化方式:

  • RDB持久化方式能夠在指定的時間間隔對資料進行快照儲存;
  • AOF持久化方式記錄每次對伺服器寫的操作,當伺服器重啟的時候會重新執行這些命令來恢復原始的資料,AOF命令以append-only模式追加儲存每次寫的操作到檔案末尾。Redis還能對AOF檔案進行後臺重寫,使得AOF檔案的體積不至於過大。
  • 如果只希望資料在伺服器執行的時候存在,也可以不採用任何持久化方式
  • 也可以同時開啟兩種持久化方式。在此情況下,當redis重啟的時候會優先載入AOF檔案來恢復原始的資料。因為通常情況下AOF檔案儲存的資料集要比RDB檔案儲存的資料集要完整;

以上的持久化級別只是兩種持久化方式的組合。那我們現在就分別看看這兩種持久化方式的具體實現。

4.1.RDB持久化方式

4.1.1RDB簡介:

​ 在指定的時間間隔內將記憶體中的資料集快照寫入磁碟,也就是行話講的Snapshot快照,它恢復時是將快照檔案直接讀到記憶體裡。

4.1.2 工作機制

​ 每隔一段時間,就把記憶體中的資料儲存到硬碟上的指定檔案中。

RDB是預設開啟的!

4.1.3 RDB特點

Redis會單獨建立(fork)一個子程式來進行持久化,會先將資料寫入到一個臨時檔案中,待持久化過程都結束了,再用這個臨時檔案替換上次持久化好的檔案。整個過程中,主程式是不進行任何IO操作的,這就確保了極高的效能如果需要進行大規模資料的恢復,且對於資料恢復的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。

最後一次持久化後的資料可能丟失

比如:兩次儲存的時間間隔內,伺服器當機,或者發生斷電問題。

在這裡插入圖片描述

4.1.4 RDB儲存策略和觸發機制

儲存策略

  • save 900 1 900 秒內如果至少有 1 個 key 的值變化,則儲存

  • save 300 10 300 秒內如果至少有 10 個 key 的值變化,則儲存

  • save 60 10000 60 秒內如果至少有 10000 個 key 的值變化,則儲存

  • save “” 就是禁用RDB模式(一般不用該模式,預設開啟上邊三個)

RDB觸發機制

  • ①基於自動儲存的策略,就是滿足儲存策略條件

  • ②執行save,或者bgsave命令!執行時,是阻塞狀態。

  • ③執行flushall命令,也會產生dump.rdb,但裡面是空的,沒有意義。

  • ④當執行shutdown命令時,也會主動地備份資料。

4.1.5 RDB優缺點
優點:
  • RDB是一個非常緊湊的檔案,它儲存了某個時間點的資料集,非常適用於資料集的備份。比如你可以在每個小時儲存一下過去24小時內的資料,同時每天儲存過去30天的資料,這樣即使出了問題也可以根據需求恢復到不同版本的資料集
  • RDB 是一個緊湊的單一檔案,很方便傳送到另一個遠端資料中,非常適合用於災難恢復
  • RDB在儲存RDB檔案時,父程式fork出一個子程式。接下來的工作全部由子程式來做,父程式不需要做其他IO操作,所以RDB持久化方式可以最大化redis的效能
  • 與AOF方式相比,再回復大的資料集的時候,RDB方式會更快一些
缺點
  • 如果redis意外停止工作的情況下丟失資料最少的話,RDB方式不滿足當前需求。雖然我們可以配置不同的save 時間點(例如每隔5分鐘並且資料集有100個寫的操作)時,Redis要完整的儲存整個資料集是一個比較繁重的工作,通常在save間隔中間發生redis服務崩潰重啟,會丟失這個save間隔中的資料
  • RDB需要經常fork子程式來儲存資料集到硬碟上,當資料集比較大的時候,fork過程是非常耗時的,可能會導致Redis在一些毫秒級內不能響應客戶端的請求。如果資料集巨大且CPU效能不佳的情況下,持續時間會達到秒級。

4.2 AOF持久化方式

4.2.1 AOF簡介

​ AOF是以日誌的形式來記錄每個寫操作,將每一次對資料進行修改,都把新建、修改資料的命令儲存到指定檔案中。Redis重新啟動時讀取這個檔案,重新執行新建、修改資料的命令恢復資料。

預設不開啟,需要手動開啟

AOF檔案的儲存路徑,同RDB的路徑一致。

AOF在儲存命令的時候,只會儲存對資料有修改的命令,也就是寫操作!

當RDB和AOF存的不一致的情況下,按照AOF來恢復。因為AOF是對RDB的補充。備份週期更短,也就更可靠。

4.2.2 AOF 儲存策略
  • appendfsync always:每次產生一條新的修改資料的命令都執行儲存操作;效率低,但是安全!

  • appendfsync everysec:每秒執行一次儲存操作。如果在未儲存當前秒內操作時發生了斷電,仍然會導致一部分資料丟失(即1秒鐘的資料)。

  • appendfsync no:從不儲存,將資料交給作業系統來處理。更快,也更不安全的選擇。

    推薦(並且也是預設)的措施為每秒 fsync 一次, 這種 fsync 策略可以兼顧速度和安全性。

4.2.3 AOF檔案修復

如果AOF檔案中出現了殘餘命令,會導致伺服器無法重啟。此時需要藉助redis-check-aof工具來修復!

redis-check-aof  --fix 檔案
4.2.4 AOF的優缺點
優點
  • 使用AOF會讓Redis更加耐久:可以使用不同的fsync策略,預設使用每秒fsync 的策略,Redis的效能依然很好,一旦出現故障,最多丟失1秒的資料
  • AOF檔案是一個只進行追加的日誌檔案,所以不需要寫入seek,即使由於某些原因(磁碟空間不足,寫過程當機等)未執行完整的寫入命令,也可以使用redis-check-aof工具修復這些問題
  • Redis 可以在AOF檔案體積變得過大時,自動的在後臺對AOF進行重寫:重寫的新AOF檔案包含了恢復當前資料集所需的最小命令集合。整個重寫操作是絕對安全的,因為Redis在建立新AOF檔案的過程中,會繼續將命令追加到現有的AOF檔案裡面,即使重寫過程中發生當機,現有的AOF檔案也不會丟失。而一旦新AOF檔案建立完畢,Redis就會從舊AOF檔案切換到新的AOF檔案,並開始對新AOF檔案進行追加操作
  • AOF檔案有序地儲存了對資料執行的所有寫入操作,這些寫入操作以Redis協議的格式儲存,因此AOF檔案的非常容易讓人讀懂,對檔案進行分析(parse)也很輕鬆。匯出AOF檔案也非常簡單。舉個例子:如果不小心執行了flushall命令,只要AOF檔案未被重寫,那麼只要停止伺服器,移除AOF檔案末尾的FLUSHALL命令,並重啟Redis,就可以恢復資料集到FLUSHALL執行前的狀態。
缺點
  • 對於相同的資料集來說,AOF檔案的體積通常大於RDB檔案的體積。
  • 根據使用的fsync策略,AOF的速度可能會慢於RDB。一般情況下,每秒fsync的效率已經很高,而fsync可以讓AOF速度和RDB一樣快,即使在高負荷下也是如此。不過處理巨大的寫入載入時,RDB可以提供更有保證的最大延遲時間。
  • 每次讀寫都同步的時候,有一定的效能壓力

4.3 如何選擇?

小孩子才做選擇,要學會全都要,你單獨用RDB你會丟失很多資料,你單獨用AOF,你資料恢復沒RDB來的快,真出什麼問題的時候第一時間用RDB恢復,然後AOF做資料補全,真香!冷備熱備一起上,才是網際網路時代一個高健壯性系統的王道。

Redis作為記憶體資料庫從本質上來說,如果不想犧牲效能,就不可能做到資料的“絕對”安全。

RDB和AOF都只是儘可能在兼顧效能的前提下降低資料丟失的風險,如果真的發生資料丟失問題,儘可能減少損失。

在整個專案的架構體系中,Redis大部分情況是扮演“二級快取”角色。二級快取適合儲存的資料

  • 經常要查詢,很少被修改的資料。

  • 不是非常重要,允許出現偶爾的併發問題。

  • 不會被其他應用程式修改。

如果Redis是作為快取伺服器,那麼說明資料在MySQL這樣的傳統關係型資料庫中是有正式版本的。資料最終以MySQL中的為準。

5. 事務

5.1 redis中事務簡介

  • Redis中事務,不同於傳統的關係型資料庫中的事務。

  • Redis中的事務指的是一個單獨的隔離操作。

  • Redis的事務中的所有命令都會序列化、按順序地執行且不會被其他客戶端傳送來的命令請求所打斷。

  • Redis事務的主要作用是串聯多個命令防止別的命令插隊

5.2 redis事務常用命令(shell)

MULTI 標記一個事務塊的開始
EXEC 執行事務中所有在排隊等待的指令並將連結狀態恢復到正常
當使用WATCH 時,只有當被監視的鍵沒有被修改,
且允許檢查設定機制時,EXEC會被執行
DISCARD 重新整理一個事務中所有在排隊等待的指令,並且將連線狀態恢復到正常。
如果已使用WATCH,DISCARD將釋放所有被WATCH的key。
WATCH 標記所有指定的key 被監視起來,在事務中有條件的執行(樂觀鎖)

5.3 Redis事務演示

5.3.1 簡單組隊

MULTI開啟組隊,EXEC依次執行佇列中的命令。

在這裡插入圖片描述

DISCARD中途取消組隊

在這裡插入圖片描述

5.3.2 組隊失敗
”殃及池魚“

在編譯的過程中,Redis檢測出來了錯誤的語法命令,因此它認為這條組隊,一定會發生錯誤,因此全體取消

在這裡插入圖片描述

”自作自受“

此種情況,語法符合規範,Redis只有在執行中,才可以發現錯誤。而在Redis中,並沒有回滾機制,因此錯誤的命令,無法執行,正確的命令會全部執行!

在這裡插入圖片描述

為什麼Redis不支援回滾

如果使用關係型資料如MySQL、SQL Server、Oracle等,事務不支援回滾會覺得有點出乎意料,有點奇怪。

引用官方的說明:

  • redis命令只會因為錯誤的語法而失敗(並且這些問題在入隊是不能發現),或是命令用在了錯誤型別的鍵上面,這就是說,失敗的命令是由編譯錯誤造成的,而這些錯誤應該在開發的過程中被發現,而不是在生產中。意思就:你丫的,給了你語法怎麼用,你還用錯了,就自己承擔自己寫錯的成本。
  • redis不需要對回滾進行處理,就可以讓Redis內部保持簡單快速。

5.4redis 鎖及策略

Redis不支援悲觀鎖。Redis作為快取伺服器使用時,以讀操作為主,很少寫操作,相應的操作被打斷的機率較少。不採用悲觀鎖是為了防止降低效能。

策略

  • Redis採用了樂觀鎖策略(通過watch操作)。樂觀鎖支援讀操作,適用於多讀少寫的情況!

  • 在事務中,可以通過watch命令來加鎖;使用 UNWATCH可以取消加鎖;

  • 如果在事務之前,執行了WATCH(加鎖),那麼執行EXEC 命令或 DISCARD 命令後,鎖對自動釋放,即不需要再執行 UNWATCH 了

6.主從複製

6.1 什麼是Redis主從複製

當單機Redis的效能是有限的,而Redis常用其讀高併發的特性,當一臺Redis有要讀又要寫的時候,這就頂不住了啊。太過於壓榨就會崩潰的哦。那就把讀寫分離,又因為讀的需求是大於寫的操作併發,就可以用一個master機器去寫,其他多個salve機器去完成讀的任務請求。不僅實現了redis儲存的擴容,還實現了水平擴容。

配置多臺Redis伺服器,以主機和備機的身份分開。主機資料更新後,根據配置和策略,自動同步到備機的master/salver機制,Master以寫為主,Slave以讀為主,二者之間自動同步資料。

在這裡插入圖片描述

主從目的:

  • 讀寫分離提高Redis效能;

  • 避免單點故障,容災快速恢復

機制原理:

​ 每次從機聯通後,都會給主機傳送sync指令,主機立刻進行存檔操作,傳送RDB檔案到從機,從機收到RDB檔案後,進行全盤載入。之後每次主機的寫操作命令,都會立刻傳送給從機,從機執行相同的命令來保證主從的資料一致!

注意:主庫接收到SYNC的命令時會執行RDB過程,即使在配置檔案中禁用RDB持久化也會生成,但是如果主庫所在的伺服器磁碟IO效能較差,那麼這個複製過程就會出現瓶頸,慶幸的是,Redis在2.8.18版本開始實現了無磁碟複製功能(不過該功能還是處於試驗階段),設定repl-diskless-sync yes。即Redis在與從資料庫進行復制初始化時將不會將快照儲存到磁碟,而是直接通過網路傳送給從資料庫,避免了IO效能差問題。

在這裡插入圖片描述

6.2 配置redis主從複製

6.2.1 準備

不同的主機配置不同的Redis服務,否則在一臺機器上面跑多個Redis服務,需要配置多個Redis配置檔案。

  • ①準備Redis配置檔案,每個配置檔案,需要配置以下屬性
daemonize yes: 服務在後臺執行
port:埠號
pidfile:pid儲存檔案
logfile:日誌檔案(如果沒有指定的話,就不需要)
dump.rdb: RDB 
appendonly 關掉,或者是更改appendonly檔案的名稱。

  • ②根據配置檔案,啟動多個Redis服務
6.2.2 配置
原則:配從不配主
一、臨時建立主從關係
  • 在從伺服器上執行SLAVEOF ip:port命令;
  • 執行info replication命令

在這裡插入圖片描述

二 永久建立

在從節點配置檔案中,編寫slaveof屬性配置

# slaveof <masterip> <masterport>

三 恢復身份

命令:slaveof no one

7.哨兵模式

7.1 簡介

在主從複製下,只有一個master,那master如果掛了,整個redis就不能保證可用了。如果某一個slave節點崩潰了,同樣我們不能在分配對應的請求到該節點進行讀操作。如何監控主從狀態,並解決master單點故障問題?哨兵模式應用而生。

作用

  • 叢集監控:主從狀態檢測

  • 故障轉移:如果Master異常,則會進行Master-Slave切換,將其中一個Slave作為Master,將之前的Master作為Slave(如果重啟成功 )

  • 訊息通知:如果某個 Redis 例項有故障,那麼哨兵負責傳送訊息作為報警通知給管理員。

  • 配置中心:如果故障轉移發生了,通知 client 客戶端新的 master 地址。

哨兵必須用三個例項去保證自己的健壯性的,哨兵+主從並不能保證資料不丟失,但是可以保證叢集的高可用

多個哨兵,不僅同時監控主從狀態,且哨兵之間也互相監控!

在這裡插入圖片描述

下線

​ ①主觀下線:Subjectively Down,簡稱 SDOWN,指的是當前 Sentinel 例項對某個redis伺服器做出的下線判斷。

​ ②客觀下線:Objectively Down, 簡稱 ODOWN,指的是多個 Sentinel 例項在對Master Server做出 SDOWN 判斷,並且通過 SENTINEL is-master-down-by-addr 命令互相交流之後,得出的Master Server下線判斷,然後開啟failover.

工作原理

  • ①每個Sentinel以每秒鐘一次的頻率向它所知的Master,Slave以及其他 Sentinel 例項傳送一個 PING 命令 ;

  • ②如果一個例項(instance)距離最後一次有效回覆 PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 則這個例項會被 Sentinel 標記為主觀下線;

  • ③如果一個Master被標記為主觀下線,則正在監視這個Master的所有 Sentinel 要以每秒一次的頻率確認Master的確進入了主觀下線狀態;

  • ④當有足夠數量的 Sentinel(大於等於配置檔案指定的值)在指定的時間範圍內確認Master的確進入了主觀下線狀態, 則Master會被標記為客觀下線 ;

  • ⑤在一般情況下, 每個 Sentinel 會以每 10 秒一次的頻率向它已知的所有Master,Slave傳送 INFO 命令

  • ⑥當Master被 Sentinel 標記為客觀下線時,Sentinel 向下線的 Master 的所有 Slave 傳送 INFO 命令的頻率會從 10 秒一次改為每秒一次 ;

  • ⑦若沒有足夠數量的 Sentinel 同意 Master 已經下線, Master 的主觀下線狀態就會被移除;

  • 若 Master 重新向 Sentinel 的 PING 命令返回有效回覆, Master 的客觀下線狀態就會被移除

在這裡插入圖片描述

總結

好了,今天的文章就結束了,我們從網際網路的架構演變來看各個元件服務的需求,從而引出了NoSQL。Redis作為當前快取伺服器的弄潮兒,我們從Redis的官網介紹分析了redis的特點,也給出了Redis安裝的示例以及我們一般關注的配置引數的作用。接著從Redis的持久化了解了RDB持久化方式特點以及其優缺點、AOF持久化機理 與優缺點。接著對於Redis的主從複製以及事務瞭解了Redis的高可用,瞭解了哨兵模式的背景和機制。部分操作文章沒有列出,因為覺得官網已經很詳盡了,另外菜鳥教程網站對於命令也算詳盡就沒有重複列出。建議大家手動在Linux環境下安裝redis,眼過千遍不如手敲一遍。
我是清風,希望這篇文章對你有幫助,怕什麼真理無窮,進一寸有一寸的歡喜。奧利給。

相關文章