前言
看看業務遇到了什麼問題?
我們要從網際網路架構的演變之路開始說起Redis的前世今生。
在我們小的時候,網路世界好像就是隻有通過大屁股桌上型電腦才能進入一樣,彼時的手機只是用來打打電話,發發簡訊,網上購物還沒有在中國普及,Jack Ma 的TB還沒有走進千家萬戶,能上網的使用者只是很少的一部分人群。那時候的場景是登入著QQ,玩著單機的遊戲,連線上視訊觀看都不是那麼流暢。網際網路專案的架構是多麼簡單:
網站初期
那時候的網路專案特點:網站訪問量低,大多數都是以靜態網頁為主,很少有動態互動應用,單個資料庫就可以滿足要求。
網站中期
隨著網際網路迅速的普及,大量的使用者開始使用網際網路,終端裝置越來越多的入門,流量開始急劇增加。大部分使用MySQL架構的網站在資料庫上都開始出現效能問題,Web程式不能再僅僅專注在功能上,同時也在追求效能。開始使用快取技術緩解資料庫壓力,優化資料庫的結構和索引。剛開始時比較流行的是通過檔案快取來緩解資料庫壓力,但是當訪問量繼續增大,檔案快取中的資料不能在多臺Web伺服器之間共享,大量的小檔案IO也帶來了比較高的IO壓力。在這種情況下,Memcache就成了一款非常有效的解決方案。
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) 與範圍查詢, bitmaps, hyperloglogs 和 地理空間(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的應用場景
- 熱點資料加速查詢(主要場景),如熱點商品、熱點資訊等訪問量較高的資料
- 即時資訊查詢,如公交到站資訊、線上人數資訊等
- 時效性資訊控制,如驗證碼控制、投票控制等
- 分散式資料共享,如分散式叢集架構中的session分離訊息佇列
2.Redis的安裝
-
凡是技術必登其官網,在官網下載redis-xx.xx.xx.tar.gz安裝包並上傳到Linux的/opt目錄;
-
在/opt目錄下,解壓安裝包到指定的子目錄下:命令:tar -zxvf redis-xx.xx.xx.tar.gz
-
安裝gcc環境,我們需要將原始碼編譯後再安裝,因此需要安裝c語言的編譯環境!不能直接make!我們可以先檢測是否有gcc環境:
若沒有gcc直接make會報錯:
安裝gcc:sudo yum install -y gcc-c++
使用sudo許可權安裝。如果在沒有安裝gcc環境下,如果執行了make,不會成功!安裝環境後,
第二次make有可能報錯:Jemalloc/jemalloc.h:沒有那個檔案
**解決方案:執行make distclean** 然後再進行make編譯
-
編譯,執行make命令!
-
編譯完成後,安裝,執行make install命令!
-
預設檔案會被安裝到 /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,眼過千遍不如手敲一遍。
我是清風,希望這篇文章對你有幫助,怕什麼真理無窮,進一寸有一寸的歡喜。奧利給。