共計 7057 個字符,預計需要花費 18 分鐘才能閱讀完成。
本篇內容介紹了“Redis 持久化實例分析”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓丸趣 TV 小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
面試官:小伙子,談談對 Redis 的看法。
我:啊,看法呀,坐著看還是躺著看。Redis 很小?很快?但很持久?
面試官:一本正經的說,我懷疑你在開車,不僅開開車還搞顏色。
我:。。。
面試官:去去去,我時間有限,別瞎扯淡。回到正題,你對 Redis 了解有多少。
我:輕量體積小、基于內存非常快、RDB 配合 AOF 持久化讓其一樣堅挺持久。
面試官:說點具體的。
我:請看正文。
正文
簡介
Redis 是一個開源的、高性能的、基于鍵值對的緩存與存儲系統,通過提供多種鍵值數據類型來適應不同場景下的緩存與存儲需求。與此同時,Redis 的諸多高層級功能讓其可以勝任消息隊列、任務隊列等不同的角色。除此之外,Redis 還支持外部模塊擴展,在某些特定的場景下可以作為主數據庫使用。
由于內存的讀寫速度遠快于硬盤,就算現在的固態盤思維估計也是朝著內存那個思維模式發展的,大概也許我是個外行,但是長久存儲還是使用機械盤。所以 Redis 數據庫中的所有數據都存儲在內存中那是相當快的。也有一定的風險,會導致丟失數據,但配合 RDB 以及 AOF 持久化會減少風險。
一、初識 Redis1、linux 下安裝(Redhat7 系列)1.1、安裝
此處準備的是源碼包,版本不在于最新,在于穩定適用。
其余版本在官網獲取,或者在其托管的平臺 github 上獲取,如下為 Redis 的官網下載地址。
https://redis.io/download
redis-6.0.8.tar.gz#安裝 tar -zxvf redis-6.0.8.tar.gz# 編譯 make make install
1.2、排查錯誤
make[1]: *** [server.o] 錯誤 1
1.3、解決方案
1.3.1、安裝依賴環境
yum -y install centos-release-scl
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
1.3.2、加環境變量并生效
scl enable devtoolset-9 bashecho /opt/rh/devtoolset-9/enable /etc/profile
重新讀取環境變量配置文件
source /etc/profile
重新編譯解決問題
# 切換到 Redis 的安裝目錄, 一般源碼包安裝會放在 /usr/local/ 下面,看個人使用習慣 cd /opt/redis-6.0.8/
#編譯 make make install
常用基本命令練習可以參考菜鳥教程
https://www.runoob.com/redis/redis-commands.html
1.4、啟動與登錄
啟動 redis-server 服務端
# 啟動 redis 服務 nohup /opt/redis-6.0.8/src/redis-server
登錄 redis-cli 客戶端
# 登錄 redis-cli/opt/redis-6.0.8/src/redis-cli
測試驗證,此時 linux 下的 redis 正式啟動成功,下面會帶來基本用法介紹。
pingpong
1.5、設置密碼
默認是沒有開放密碼設置的,需要手動開啟注釋掉的參數配置。
# 編輯配置文件 vim /opt/redis-6.0.8/redis.conf
#原本的被注釋掉, 復制一行改成你設置的密碼即可
#requirepass foobaredrequirepass 123456
2、Windows 下安裝 2.1、安裝
Redis-x64-3.2.100.zip
2.1.1、Windows 下解壓或者 msi 直接安裝即可。
2.1.2、設置服務命令(注冊為服務形式,自啟)
安裝服務
redis-server --service-install redis.windows-service.conf --loglevel verbose
卸載服務
redis-server --service-uninstall
2.2、啟動與關閉
redis-server redis.windows.conf
2.2.1、開啟服務
redis-server --service-start
2.2.2、停止服務
redis-server --service-stop
2.3、啟動 redis 服務
# 同樣在 redis 解壓的或者安裝的目錄以管理員身份運行 cmdredis-server --service-start
2.4、cmd 下運行測試登錄
# 在 redis 解壓的或者安裝的目錄以管理員身份運行 cmdredis-cli.exe -h 127.0.0.1 -p 6379
#或者直接執行 redis-cli
#執行 redis-cli
#登錄測試 ping
5、Windows 下的管理工具 rdm,是可視化界面
https://redisdesktop.com/download
二、基礎知識 1、面試常問到
面試官:redis 中的數據類型有哪些,能聊聊嗎?
我:string(字符串類型)、hash(哈希類型)、list(列表類型)、set(集合類型)、zset(有序集合類型)、stream(流類型)
stream 是 redis5.0 新增的特性支持。
面試官:嚯,小伙子有點東西啊,知道的還不少嘛,連 stream 流類型都知道。
我:一臉懵逼…
三、進階 1、持久化
面試官:Redis 的一些高級特性了解嗎?
我:略有了解。
面試官:能具體談談嗎?
我:飛速在大腦搜索者以前看書總結的。緩存、持久化迎面而來。
將 Redis 作為緩存服務器,但緩存被穿透后會對性能照成較大影響,所有緩存同時失效緩存雪崩,從而使服務無法響應。
我們希望 Redis 能將數據從內存中以某種形式同步到磁盤中,使之重啟以后根據磁盤中的記錄恢復數據。這一過程就是持久化。
面試官:知道 Redis 有哪幾種常見的持久化方式嗎?
我:Redis 默認開啟的 RDB 持久化,AOF 持久化方式需要手動開啟。
Redis 支持兩種持久化。一種是 RDB 方式,一種是 AOF 方式。前者會根據指定的規則“定時”將內存中的數據存儲到硬盤上,而后者在每次執行命令后將命令本書記錄下來。對于這兩種持久化方式,你可以單獨使用其中一種,但大多數情況下是將二者緊密結合起來。
此時的面試官一臉期待,炯炯有神的看向了我,請繼續。
2、RDB 方式
繼續介紹,RDB 采取的是快照方式,默認設置自定義快照【自動同步】,默認配置如下。
同樣可以手動同步
# 不推薦在生產環境中使用 SAVE
# 異步形式 BGSAVE
# 基于自定義快照 FLASHALL
3、AOF 方式
當使用 Redis 存儲非臨時數據時,一般需要打開 AOF 持久化來降低進程終止導致數據的丟失。AOF 可以將 Redis 執行的每一條命令追加到硬盤文件中,著這個過程中顯然會讓 Redis 的性能打折扣,但大部分情況下這種情況可以接受。這里強調一點,使用讀寫較快的硬盤可以提高 AOF 的性能。
默認沒有開啟,需要手動開啟 AOF,當你查看 redis.conf 文件時也會發現 appendonly 配置的是 no
appendonly yes
開啟 AOF 持久化后,每次執行一條命令會會更改 Redis 中的數據的目錄,Redis 會將該命令寫入磁盤中的 AOF 文件。AOF 文件的保存位置和 RDB 文件的位置相同,都是通過 dir 參數設置,默認的文件名是 appendonly.aof,可以通過 appendfilename 參數修改。
appendfilename appendonly.aof
實際上 Redis 也正是這樣做的,每當達到一定的條件時 Redis 就會自動重寫 AOF 文件,這個條件可以通過 redis.conf 配置文件中設置:
auto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mb
在啟動時 Redis 會逐行執行 AOF 文件中的命令將硬盤中的數據加載到內存中,加載的速度相比 RDB 會慢一些。
雖然每次執行更改數據庫內容的操作時,AOF 都將命令記錄在 AOF 文件中。但事實上,由于操作系統的緩存機制,數據并沒與真正寫入硬盤,而是進入了操作系統的硬盤緩存。在默認情況下,操作系統每 30 秒會執行一次同步操作,以便將硬盤緩存中的內容寫入硬盤。
在 Redis 中可以通過 appendfsync 設置同步的時機:
# appendfsync always
#默認設置為 everysecappendfsync everysec
# appendfsync no
Redis 允許同時開啟 AOF 和 RDB。這樣既保證了數據的安全,又對進行備份等操作比較友好。此時重新啟動 Redis 后,會使用 AOF 文件來恢復數據。因為 AOF 方式的持久化,將會丟失數據的概率降至最小化。
4、Redis 復制
通過持久化功能,Redis 保證了即使服務器重啟的情況下也不會丟失(少部分遺失)數據。但是數據庫是存儲在單臺服務器上的,難免不會發生各種突發情況,比如硬盤故障,服務器突然宕機等等,也會導致數據遺失。
為了盡可能的避免故障,通常做法是將數據庫復制多個副本以部署在不同的服務器上。這樣即使有一臺出現故障,其它的服務器依舊可以提供服務。為此,Redis 提供了復制(replication)功能。即實現一個數據庫中的數據更新后,自動將更新的數據同步到其它數據庫上。
此時熟悉 MySQL 的同學,是不是覺得與 MySQL 的主從復制很像,以開啟二進制日志 binlog 實現同步復制。
而 Redis 中使用復制功能更為容易,相比 MySQL 而言。只需要在從庫中啟動時加入 slaveof 從數據庫地址。
# 在從庫中配置 slaveof master_database_ip_addr
#測試, 加了 nohup 與 是放入后臺,并且輸出日志到 /root/ 目錄下的 nohup.outnohup /opt/redis-6.0.8/src/redis-server --6380 --slaveof 192.168.245.147 6379
4.1、原理
復制初始化。這里主要原理是從庫啟動,會向主庫發送 SYNC 命令。同時主庫接收到 SYNC 命令后會開始在后臺保存快照,即 RDB 持久化的過程,并將快照期間接收的命令緩存起來。當快照完成后,Redis 會將快照文件和所有緩存的命令發送給從數據庫。從數據庫收到后,會載入快照文件并執行收到的緩存命令。
復制同步階段會貫穿整個主從同步過程,直到主從關系終止為止。在復制的過程中快照起到了至關重要的作用,只要執行復制就會進行快照,即使關閉了 RDB 方式的持久化,通過刪除所有 save 參數。
4.2、樂觀復制
Redis 采用了樂觀復制(optimistic replication)的復制策略。容忍在一定時間內主從數據庫的內容是不同的,但是兩者的數據最終是會同步的。具體來講,Redis 在主從數據庫之間復制數據的過程本身是異步的,這就意味著,主數據庫執行完客戶端請求的命令會立即將命令在主數據庫的執行結果反饋給客戶端,并異步的將數據同步給從庫,不會等待從數據庫接收到該命令在返回給客戶端。
當數據至少同步給指定數量的從庫時,才是可寫,通過參數指定:
# 設置最少限制 3min-slaves-to-write 3
#設置允許從數據最長失去連接時間 min-slaves-max-lag 10
4.3、增量復制
基于以下三點實現
從庫會存儲主庫的運行 ID(run id)。每個 Redis 運行實例均會擁有一個唯一運行 ID,每當實例重啟后,就會自動生成一個新的運行 ID。類似于 MySQL 的從節點配置的唯一 ID 去識別。
在復制同步階段,主庫一條命令被傳送到從庫時,會同時把該命令存放到一個積壓隊列(backlog)中,記錄當前積壓隊列中存放的命令的偏移量范圍。
從庫接收到主庫傳來的命令時,會記錄該命令的偏移量。
4.4、注意
當主數據庫崩潰時,情況略微復雜。手動通過從數據庫數據庫恢復主庫數據時,需要嚴格遵循以下原則:
在從數據庫中使用 SLAVEOF NO ONE 命令將從庫提升為主庫繼續服務。
啟動之前崩潰的主庫,然后使用 SLAVEOF 命令將其設置為新的主庫的從庫。
注意:當開啟復制且數據庫關閉持久化功能時,一定不要使用 supervisor 以及類似的進程管理工具令主庫崩潰后重啟。同樣當主庫所在的服務器因故障關閉時,也要避免直接重新啟動。因為當主庫重啟后,沒有開啟持久化功能,數據庫中所有數據都被清空。此時從庫依然會從主庫中接收數據,從而導致所有從庫也被清空,導致數據庫的持久化開了個寂寞。
手動維護確實很麻煩,好在 Redis 提供了一種自動化方案:哨兵去實現這一過程,避免手動維護易出錯的問題。
5、哨兵(sentinel)
從 Redis 的復制歷中,我們了解到在一個典型的一主多從的 Redis 系統中,從庫在整個系統中起到了冗余備份以及讀寫分離的作用。當主庫遇到異常中斷服務后,開發人員手動將從升主時,使系統繼續服務。過程相對復雜,不好實現自動化。此時可借助哨兵工具。
哨兵的作用
監控 Redis 系統運行情況
監控主庫和從庫是否正常運行
主庫 gg 思密達,自動將從庫升為主庫,美滋滋
當然也有多個哨兵監控主從數據庫模式,哨兵之間也會互相監控,如下圖:
首先需要建立起一主多從的模型,然后開啟配置哨兵。
# 主庫 sentinel monitor master 127.0.0.1 6379 1
#建立配置文件,例如 sentinel.confredis-sentinel /opt/path/to/sentinel.conf
關于哨兵就介紹這么多,現在大腦中有印象。至少知道有那么回事,可以和美女面試官多掰扯掰扯。
6、集群(cluster)
從 Redis3.0 開始加入了集群這一特性。
即使使用哨兵,此時的 Redis 集群的每個數據庫依然存有集群中的所有數據,從而導致集群的總數據存儲量受限于可用內存最小的數據庫節點,繼而出現木桶效應。正因為 Redis 所有數據都是基于內存存儲,問題已經很突出,尤其是當 Redis 作為持久化存儲服務時。
有這樣一種場景。就擴容來說,在客戶端分片后,如果像增加更多的節點,需要對數據庫進行手動遷移。遷移的過程中,為了保證數據的一致性,需要將進群暫時下線,相對比較復雜。
此時考慮到 Redis 很小,啊不口誤,是輕量的特點。可以采用預分片(presharding)在一定程度上避免問題的出現。換句話說,就是在部署的初期,提前考慮日后的存儲規模,建立足夠多的實例。
從上面的理論知識來看,哨兵和集群類似,但哨兵和集群是兩個獨立的功能。如果要進行水平擴容,集群是不錯的選擇。
配置集群,開啟配置文件 redis.conf 中的 cluster-enabled
cluster-enabled yes
配置集群每個節點配置不同工作目錄,或者修改持久化文件
cluster-config-file nodes-6379.conf
集群測試大家可以執行配置,參考其他書籍亦可,實現并不難。只要是知其原理。
四、Redis for Java
示例
package com.jedis;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import redis.clients.jedis.JedisPoolConfig;public class Test {
@org.junit.Test
public void demo() {Jedis jedis = new Jedis( 127.0.0.1 , 6379);
jedis.set( name , sky
String params = jedis.get( jedis
System.out.println(params);
jedis.close();
@org.junit.Test
public void config() {
// 獲取連接池的配置對象
JedisPoolConfig config = new JedisPoolConfig();
// 設置最大連接數
config.setMaxTotal(30);
// 設置最大空閑連接數
config.setMaxIdle(10);
// 獲取連接池
JedisPool pool = new JedisPool(config, 127.0.0.1 , 6379);
// 獲得核心對象
Jedis jedis = null;
try {
// 通過連接池獲取連接
jedis = pool.getResource();
// 設置對象
jedis.set( poolname , pool
// 獲取對象
String pools = jedis.get( poolname
System.out.println(values: +pools);
} catch (Exception e) {e.printStackTrace();
}finally{
// 釋放資源
if(jedis != null){jedis.close();
if(pool != null){pool.close();
}}
“Redis 持久化實例分析”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注丸趣 TV 網站,丸趣 TV 小編將為大家輸出更多高質量的實用文章!