Redis简单介绍
一、Redis基礎信息
1.1 redis數據類型和底層數據結構的對應關系
1.2 數據結構的時間復雜度
1.3 為什么單線程Redis能那么快?
1.4 redis的持久化
a. AOF日志
優點: 1.寫后日志,避免記錄錯誤命令的情況2.不阻塞當前寫操作。 缺點:1.剛執行完一個命令,還沒有來得及記日志就宕機,有丟失數據風險。2.AOF雖然避免了對當前命令的阻塞,但可能會給下一個操作帶來阻塞風險。兩個風險都是和AOF寫回磁盤的時機相關,因此產生了三種回寫策略
Always:同步寫回,每個寫命令執行完,立馬同步的將日志寫回磁盤 Everysec: 每秒寫回,每個寫命令執行完,只是先把日志寫到AOF文件的內存緩沖區,每隔一秒把緩沖區的內容寫入磁盤 No: 操作系統控制的寫回,每個寫命令執行完,只是先把日志寫到AOF文件的內存緩沖區,由操作系統決定何時將緩沖區內容寫回磁盤回寫策略的優缺點
AOF重寫機制:
AOF重寫機制就是在重寫時,Redis根據數據庫的現狀創建一個新的AOF文件 作用:避免日志太大,不阻塞主線程由后臺線程bgrewriteaof子進程來完成b. RDB快照(內存快照)
1. 給那些內存數據做快照? Redis的數據都在內存中,為了提供所有數據的可靠性保證,執行的是全量快照,把內存中所有的數據都寫入磁盤中。 2. RDB文件的生成是否會阻塞主線程?a.save: 在主線程中執行,會導致阻塞;b.bgsave: 創建一個子進程,專門用于寫入RDB文件,避免了主線程的阻塞,這也是Redis RDB文件生成的默認配置。優點: 1.快照的恢復速度快 缺點:快照的頻率不好把握,太低可能丟失數據量大,太高產生額外的性能開銷 Redis 4.0中提出了一個混合使用AOF日志和內存快照1.5 數據同步
主從模式:
當我們啟動多個Redis實例的時候,它們相互之間就可以通過replicaof(Redis 5.0之前使用slaveof)命令形成主庫和從庫的關系,之后會按照三個階段完成數據的第一次同步
同步的耗時操作:
1. 生成RDB文件 2. 傳輸RDB文件主從從模式:
1.7 哨兵機制:主庫掛了,如何不間斷服務?
哨兵其實就是一個運行在特殊模式下的Redis進程,主從庫實例運行的同時,它也在運行。哨兵主要負責的就是三個任務:監控、選主(選擇主庫)和通知 。 哨兵機制實現了主從庫的自動切換:
監控主庫運行狀態,并判斷主庫是否客觀下線; 在主庫客觀下線后,選取新主庫; 選出新主庫后,通知從庫和客戶端客戶端只能把寫失敗的請求先緩存起來或寫入消息隊列中間件中,等哨兵切換完主從后,再把這些寫請求發給新的主庫,但這種場景只適合對寫入請求返回值不敏感的業務,而且還需要業務層做適配,另外主從切換時間過長,也會導致客戶端或消息隊列中間件緩存寫請求過多,切換完成之后重放這些請求的時間變長。
1.8 哨兵集群:哨兵掛了,主從庫還能切換嗎?
對于主從切換,當然不是哪個哨兵想執行就可以執行的,否則就亂套了。所以,這就需要哨兵集群在判斷了主庫“客觀下線”后,經過投票仲裁,選舉一個Leader出來,由它負責實際的主從切換,即由它來完成新主庫的選擇以及通知從庫與客戶端。
1.9 切片集群:數據增多了,是該加內存還是加實例
切片集群是一種保存大量數據的通用機制 在應對數據量擴容時,雖然增加內存這種縱向擴展的方法簡單直接,但是會造成數據庫的內存過大,導致性能變慢。Redis切片集群提供了橫向擴展的模式,也就是使用多個實例,并給每個實例配置一定數量的哈希槽,數據可以通過鍵的哈希值映射到哈希槽,再通過哈希槽分散保存到不同的實例上。這樣做的好處是擴展性好,不管有多少數據,切片集群都能應對。
2.0 String內存開銷大
除了記錄實際數據,String類型還需要額外的內存空間記錄數據長度、空間使用等信息,這些信息也叫作元數據。當實際保存的數據較小時,元數據的空間開銷就顯得比較大。
String類型就會用簡單動態字符串
buf:字節數組,保存實際數據。為了表示字節數組的結束,Redis會自動在數組最后加一個“\0”,這就會額外占用1個字節的開銷。
len:占4個字節,表示buf的已用長度。
alloc:也占個4字節,表示buf的實際分配長度,一般大于len。
2.1 集合統計
集合類型常見的四種統計模式,包括聚合統計、排序統計、二值狀態統計和基數統計
聚合統計(Set):Set的差集、并集和交集的計算復雜度較高,在數據量較大的情況下,如果直接執行這些計算,會導致Redis實例阻塞。所以,我給你分享一個小建議:你可以從主從集群中選擇一個從庫,讓它專門負責聚合計算,或者是把數據讀取到客戶端,在客戶端來完成聚合統計,這樣就可以規避阻塞主庫實例和其他從庫實例的風險了。排序統計(sorted set):有序集合List是按照元素進入List的順序進行排序的,而Sorted Set可以根據元素的權重來排序 二值狀態統計(BitMap):Bitmap本身是用String類型作為底層數據結構實現的一種統計二值狀態的數據類型指集合元素的取值就只有0和1兩種。在簽到打卡的場景中 基數統計():基數統計就是指統計一個集合中不重復的元素個數2.2 Redis的簡單事務
MULTI:表示一系列原子性操作的開始。收到這個命令后,Redis就知道,接下來再收到的命令需要放到一個內部隊列中,后續一起執行,保證原子性 EXEC:表示一系列原子性操作的結束。一旦Redis收到了這個命令,就表示所有要保證原子性的命令操作都已經發送完成了。 此時,Redis開始執行剛才放到內部隊列中的所有命令操作。2.3 基于redis實現消息隊列
消息隊列在存取消息的三個需求:
a. 基于List實現消息隊列解決方案
List本身就是按先進先出的順序對數據進行存取的,能滿足消息保序的需求. LPUSH:把要發送的消息依次寫入List RPOP: 從List的另一端依次讀取消息并進行處理 BRPOP: 阻塞式讀取,客戶端在沒有讀到隊列數據時,自動阻塞,直到有新的數據寫入隊列,再開始讀取新數據 BRPOPLPUSH: 讓消費者程序從一個List中讀取消息,同時,Redis會把這個消息再插入到另一個List(可以叫作備份List)留存。 這樣一來,如果消費者程序讀了消息但沒能正常處理,等它重啟后,就可以從備份List中重新讀取消息并進行處理了 List類型并不支持消費組的實現b. 基于Streams的消息隊列解決方案
Streams是Redis專門為消息隊列設計的數據類型,它提供了豐富的消息隊列操作命令。
2.4 Redis的阻塞點
a. 和客戶端交互時的阻塞點1. 集合全量查詢和聚合操作(復雜度通常為O(N))2. bigkey刪除操作就是Redis的第二個阻塞點 (釋放內存,把釋放掉的內存塊插入一個空閑內存塊的鏈表)3. 清空數據庫 b. 和磁盤交互時的阻塞點4. AOF日志同步寫 c. 主從節點交互時的阻塞點 5. 加載RDB文件 d. 切片集群實例交互時的阻塞點2.5 redis緩存的淘汰策略
noeviction: 寫滿了,再有寫請求來時,Redis不再提供服務 volatile-ttl: 根據過期時間的先后進行刪除 volatile-random: 設置了過期時間的鍵值對中,進行隨機刪除 volatile-lru: 使用LRU算法篩選設置了過期時間的鍵值對(最近最少使用) volatile-lfu: 使用LFU算法選擇設置了過期時間的鍵值對(最不經常使用) allkeys-random: 從所有鍵值對中隨機選擇并刪除數據 allkeys-lru: 使用LRU算法在所有數據中進行篩選 allkeys-lfu: 使用LFU算法在所有數據中進行篩選2.6 redis緩存常見問題及解決方案
2.7 緩存污染怎么辦?
1. 什么緩存污染? 有些數據被訪問的次數非常少,甚至只會被訪問一次。當這些數據服務完訪問請求后,如果還繼續留存在緩存中的話,就只會白白占用緩存空間 2. 如何解決緩存污染問題? 淘汰策略: LRU策略和LFU策略 隨機淘汰策略:避免緩存污染效果差2.8 Redis無鎖原子操作
1. 把多個操作在Redis中實現成一個操作,也就是單命令操作; 2. 把多個操作寫到一個Lua腳本中,以原子性方式執行單個Lua腳本。數據修改時可能包含多個操作,讀數據、數據增減、寫回數據三個操作,這顯然就不是單個命令操作。 1. Redis提供了INCR/DECR命令,把這三個操作轉變為一個原子操作 2. Lua腳本2.9 Redis實現分布式鎖
單命令操作實現加鎖SETNX: 在執行時會判斷鍵值對是否存在,如果不存在,就設置鍵值對的值,如果存在,就不做任何設置DEL命令刪除鎖變量 給鎖變量設置一個過期時間, 避免在處理業務時產生異常,無法釋放鎖變量。 基于多個Redis節點實現高可靠的分布式鎖: Redlock算法的基本思路,是讓客戶端和多個獨立的Redis實例依次請求加鎖,如果客戶端能夠和半數以上的實例成功地完成加鎖操作, 那么我們就認為,客戶端成功地獲得分布式鎖了,否則加鎖失敗3.0 Redis的事務實現
事務的ACID屬性是我們使用事務進行正確操作的基本要求
Redis的事務機制可以保證一致性和隔離性 無法保證持久性 當事務中使用的命令語法有誤時,原子性得不到保證,在其它情況下,事務都可以原子性執行。3.1 Redis6.0新特性
3.2 Redis與其他緩存數據庫比較
?
3.3 Redis的學習路線
redis學習推薦書籍
總結
- 上一篇: Scapy:局域网MAC地址扫描脚本
- 下一篇: mysql dbutil_DBUtil详