Redis的相關知識

也曾夢中流浪發表於2020-11-09
  •  什麼是Redis 

  • Redis是一個開源的使用ANSI C語言編寫、遵守BSD協議、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value資料庫。
  • Redis簡單說明

  • redis是單執行緒的,基於記憶體操作。Redis能讀的速度是110000次/s,寫的速度是81000次/s
  • Redis 資料型別

  • redis有五種資料型別,分別是字串(string),雜湊(hash),列表(list),集合(set),有序集合(sorted set)。

 

  • Redis事務

  • redis事務的實質就是一組命令的集合。一個事務中所有命令都被序列化,按順序執行。具有一次性,有序性,排他性。
  • 單子redis命令具有原子性,但是事務中沒有。
  • 使用事務的一般步驟分為:開啟事務,命令入隊,執行事務。
  • 執行事務的時候如果是編譯性報錯(程式碼報錯,命令報錯),那麼事務不會正常執行,如果是執行報錯(比如對資料的不合理處理),那麼只是單個命令不會執行成功,其他正確的命令是會正常執行的。
  • multi  開始事務
  • discard 取消事務  
  • exec 執行事務。
  • watch 監控
  • 我們可以通過watch命令實現一個類似樂觀鎖的操作。即我們預設資料不會出現問題,只有在更新資料時進行判斷,這期間是否有改動過資料(在MySQL中通過version欄位),如果資料變化了,那麼執行就會失敗,一般適用於讀操作比較多的場景。比如:通過watch監視某個key後,在一個執行緒中執行事務(事務中會訪問到監視的key對應的值),而另一執行緒在事務執行前修改了所監視的key對應的值,那麼事務就回執行失敗。

 

  • Redis持久化

  • Redis持久化有RDB和AOF兩種模式。
  • RDB
  • 在指定間隔時間內將記憶體中的資料集快照寫入磁碟,恢復時將快照檔案直接讀到記憶體中。redis會fork一個子程式來持久化,會先把資料寫入到一個臨時檔案中,等持久化過程結束了,在把該檔案替換上次持久化好的檔案。整個過程中,主程式是不進行任何IO操作的,這確保了極高的效能。如果恢復資料量比較大且對資料完整性要求不是很高,那麼推薦用RDB。
  • RDB觸發情況
  • 在滿足save條件下,會觸發
  • 在執行flushall命令也會觸發
  • 在退出redis是時也會產生RDB檔案
  • 缺點:
  • 需要一定時間間隔進行操作,如果在不滿足save條件下當機資料可能會丟失。
  • fork程式會佔用一定記憶體空間。
  • AOF
  • 即append only file。以日誌的形式記錄每個操作,將redis執行過的所有指令都記錄下來,讀的操作不會記錄。redis啟動之處,會通過讀取該檔案構建新的資料,也就是redis啟動的時候把.aof檔案中的操作執行一次來實現資料的恢復。如果這個aof檔案有問題,被修改過,那麼redis是啟動不了的,需要我們自己去修復這個檔案。redis提供了一個工具redis-check-aof,我們可以通過命令redis-check-aof --fix appendonly.aof 進行修復。當AOF檔案大於配置所設定的大小的時,會fork一個程式來重寫aof檔案,使aof檔案不會過大,一般來說aof是可以無限增加的,所以AOF檔案會越來越大。
  • 缺點:
  • 相對於資料檔案來說,AOF遠遠大於RDB,修復資料也比RDB慢。
  • AOF執行效率比RDB慢。
  •  

 

  • 同時開啟兩種持久化方式時
  • 在這種情況下,當redis重啟的時候會優先載入AOF檔案來恢復原始的資料,因為通常情況下,aof檔案儲存的資料要比RDB檔案儲存的資料要完整
  • 資料不實時,同時使用兩者伺服器重啟也只會找AOF檔案,建議使用RDB備份,因為AOF在不斷變化不好備份。
  • 效能方面
  •  因為RDB檔案只用作後備用途,建議在slave上持久化RDB檔案,而且只要15分鐘備份一次就夠了,只保留save 900 1這條規則。
  •  如果只使用AOF,優點是在最惡劣的情況下丟失的資料也不會超過兩秒,啟動指令碼比較簡單隻load自己的aof檔案就可以了,代價一是帶來了持續的IO,二是AOF最後將重寫過程產生的新資料寫到新檔案造 成的阻塞幾乎是不可避免的。在硬碟許可情況下,應該儘量減少AOF rewrite的頻率,AOF重寫的基礎大小預設值64M太小了,可以設定到 5G以上,預設超過原大小100%大小重寫可以改到適當的數值。
  •  如果不使用AOF 僅靠Master-Slave Repllcation 實現高可用性也可以,能省掉一大筆IO,也減少了重寫時帶來的系統波動,代價是如果Master
  •   /Slave 同時倒掉(斷電),會丟失十幾分鐘的資料,啟動指令碼也要比較兩個Master/Slave中的RDB檔案,使用最新的那個。

 

  • Redis釋出訂閱

  • 有三個角色:釋出者,釋出系統,訂閱者。
  • 訂閱者訂閱一個頻道,當釋出者釋出訊息時訂閱者就可以收到。
  • 訂閱某個頻道後,redis-server裡面維護了一個字典,字典的key就是頻道,value是一個連結串列,連結串列裡面就是各個訂閱者,遍歷這個表,把資訊發給各個訂閱者。

 

  • Redis主從複製

  • 主從複製,讀寫分離。80%的壓力都是讀操作。一臺主機可以有多臺從機,一臺從機只有一臺主機。
  • 一般情況下,每臺伺服器都是主伺服器,伺服器身份的修改可以通過命令修改,也可以在配置中 replication相關位置修改。
  • 主機負責寫,從機負責讀,主機中所有資訊和資料都會被從機儲存,主機斷了後,從機中依然能獲取到主機寫的資訊,主機重新連線後,寫的資訊從機依然能獲取到。
  • 如果是命令列生成的從機,斷開後再連線時預設是主機,主要變為從機後,依然能從主機中獲得所有資料。
  • 原理
  • 從機成功連線到主機後,會傳送一個sync的命令到主機,主機接到命令後,會啟動存檔程式,同時收集所有修改資料的命令,在後臺程式執行完畢之後,主機將所有的資料傳送給從機,完成一次資料同步。
  • 全量複製:從機接收到主機的資料後,將其存檔並載入到記憶體中。
  • 增量複製:主機將新增修改資料的命令依次發給從機,以此完成資料同步。

 

  • 哨兵模式

  • 哨兵是一個獨立的程式,哨兵通過傳送命令,等待redis伺服器響應,從而監控執行的多個redis服務。如果當初始設定主機的當機後後,自動通過一個/多個哨兵從從機中選出一個新的主機。
  • 優點:
  •     哨兵叢集,基於主從複製模式,所有的主從配置優點,它全有
  •     主從可以切換,故障可以轉移,系統的可用性會更高
  •     哨兵模式就是主從模式的升級,手動到自動,更加健壯。
  • 缺點:
  •     redis不好線上擴容,叢集容量一旦達到上限,線上擴容就十分麻煩
  •     實現哨兵模式的配置其實是很麻煩的,選擇性太高。

 

  • Redis快取穿透和雪崩

  • 快取穿透
  • 當單個使用者查詢一個資料的時候,如果在快取的找不到,那麼就會去持久層資料庫查詢,如果持久層資料庫也沒有,那麼查詢失敗。如果多個使用者出現這種情況的時候就會給伺服器造成跟大的壓力,出現快取穿透。
  • 解決辦法:
  • 布隆過濾器:布隆過濾器是一種資料結構,對所有可能查詢的資料以hash的方式儲存,先在控制層進行校驗,如果不符合則丟棄,這樣就避免了對底層儲存系統查詢的壓力。
  •  
  • 快取空物件:當儲存層不命中後,即使返回的空物件也儲存起來,同時會設定一個過期時間,之後再查詢這個資料時,就回從快取中取,保護了後端資料來源。這種方式缺點:如果空值能被快取起來,那麼就會需要新的空間新的鍵去儲存這些空值。
  • 即使設定了過期時間,快取層和儲存層還是會有一段時間視窗不一致,對於需要保持一致性的業務會有影響。
  •  
  • 快取擊穿
  • 即當某個熱點資料在快取失效的瞬間,大量請求併發訪問,那麼就會擊穿快取,去訪問資料庫來查詢新的資料並回寫到快取,從而使資料庫壓力過大。
  • 解決方法:
  • 1.把熱點資料設定永不過期。從快取層面來看,熱點資料不過期,所以不會出現資料過期後訪問資料庫問題。但是會佔用記憶體,且redis記憶體滿了後會去清理一些資料。
  • 2.加互斥鎖。保證每個key在同一時間只有一個執行緒去查詢後端服務,其他執行緒沒有獲得分散式鎖的許可權,需要等待。這種操作把壓力轉移到分散式鎖,對鎖的考驗比較大。
  •  
  • 快取雪崩
  • 即在某一時刻快取中大量資料失效或者redis當機。
  • 解決方法:
  • redis高可用。即多增幾臺redis伺服器,其中一臺掛掉後其他的伺服器還可以使用(異地多活)。
  • 限流降級。即快取失效後通過加鎖或者佇列的方式來控制同一時刻對訪問資料庫並且會寫資料到快取的執行緒數量,比如同一時刻只有一條執行緒。
  • 資料預熱。在正式部署的時候,先把可能訪問的資料訪問一遍,這樣就回將大量資料載入到快取中。在即將高併發訪問前手動觸發載入快取不同的key,設定不同的過期時間,讓失效的時間儘量均勻。

 

  • Redis.conf 中一些配置

  •  繫結的IP
  •   是否是保護模式,yes表示是,no表示不是
  •  埠
  •  密碼,需要在這裡設定密碼的話把#去掉,然後把foobared改成要設定的密碼
  •   是否是以守護程式的方式執行,yes表示是,no表示不是
  •  如果以後臺的方式執行,就需要指定一個pid檔案
  •  rdb的檔名,可以用於指定生成的rdb檔名(預設是dump),也可用於更換資料庫,即停掉redis伺服器後,修改配置中的這個rdb名字,啟動redis伺服器的時候就會讀取對應名字的RDB檔案。
  •  RDB檔案存放路徑
  • 這個就是RDB持久化時間間隔的一些設定
  • 第一條表示如果900s內,如果至少有一個key進行了修改,就進行持久化操作
  • 第二條表示如果300s內,如果至少10key進行了修改,就進行持久化操作
  • 第三條表示如果60s內,如果至有10000個key進行了修改,就進行持久化操作
  •  
  •   aof是否開啟,yes表示是,no表示不是
  •  aof檔名
  •  
  • 這個是把操作命令寫入AOF檔案的設定
  • # appendfsync always   每次修改都sync,消耗效能
  • #appendfsync everysec 每秒執行一次sync,可能會丟失這一秒的資料
  • # appendfsync no 不執行sync,作業系統自己同步資料,速度最快
  •  如果AOF檔案大於64M,那麼就重寫

 

  • 其他

  • 關係型資料庫
  • 即一對一,一對多,多對多等關係模型,關係模型常見模型是二維表格模型,是表,行,列。比如Mysql。
  • 非關係型資料庫(Nosql)
  • 列模型資料庫 :Hbase 
  • 鍵值型 :Redis,MemcacheDB,
  • 文件型別 :MongoDB
  • MongoDB是bson格式,和json一樣。是一個基於分散式儲存的資料庫,C++編寫,主要用來處理大量的文件。
  • 是一個介於關係型資料庫和非關係型資料庫的中間產品,是非關係型資料庫中功能最豐富,最像關係型資料庫的。
  • 圖關聯式資料庫:Neo4j,Infogrid

知識參考https://www.bilibili.com/video/BV1S54y1R7SB?from=search&seid=1965327555807395680