1. 程式人生 > 實用技巧 >Good Bye 2020 E

Good Bye 2020 E

redis筆記總結

1.什麼是redis?
它是一個非關係型資料庫,不同於傳統的資料庫,是存在記憶體當中的。基於鍵值對的NoSQL資料庫。

redis還可以實現分散式鎖。
1.1如何實現分散式鎖?
setnx?有點看不太懂,因為給的都是應用場景,光看程式碼,有點不懂。
1.2為什麼能實現分散式鎖?

2.為什麼要用redis?
高效能:假如你每次訪問資料都需要去查詢資料庫,而資料庫是存在磁碟當中的,你去查資料庫,又要去遍歷磁碟,這樣耗費的時間就會比較多,如果,你把資料快取到redis裡邊,你每次訪問資料直接從redis裡邊取就好了,redis又是直接在記憶體裡邊的,這樣又會更加快。
高併發:直接操作快取能夠承受的請求遠遠大於操作磁碟,所以可以把資料庫裡的部分資料放到快取當中去。這樣的話,使用者的一部分請求可以直接從快取中獲取,而不用經過資料庫。

3.redis基本資料型別有哪些,能舉例一下他們的應用場景嗎?
String 簡單的key-value,value不僅僅可以是String也可以是數字。應用場景:快取狀態,利用其他資料庫做儲存,redis實現快取;
共享使用者session,使用者重新重新整理一次介面,可能需要重新登入一下,每次都要去資料庫裡邊查,是很耗費時間和資源的,把他放到快取裡是很適合的。利用redis統一集中管理使用者session。但是redis得高可用才能保證使用者session能夠快速獲取和更新資料。
什麼是高可用?
一個服務掛了,可以自動切換到另一個服務上。
如何保證高可用?
redis主從複製
上圖
在這裡插入圖片描述
主節點負責讀寫,從節點負責讀

1.當master和slave正常連線的時候:master會發送一連串的命令來保證對slave的更新,便於將自身的改變(客戶端的寫入,過期時間等等)賦值給slave;
2.當兩者斷開連線:主從意識到連線超時,slave會嘗試重連,slave會進行部分同步,會嘗試獲取在斷開連線的這段時間丟失的命令流。
3.當無法進行部分同步時,slave會請求進行全量重同步,master要建立所有資料的快照,將其傳送給slave,之後在資料集更新時持續傳送命令流給slave。
全量和增量?
資料同步一般分為全量和增量。
全量:每天定時或週期性地把資料從一個地方拷貝到另一個地方。
增量:抓取某個時刻以後的資料來進行更新。
redis叢集
提到了session,談談對session的瞭解吧。
什麼是session?
session物件儲存特定使用者所需的屬性和配置資訊。
整個使用者會話中一直存活下去。
瀏覽器和伺服器會話過程中,伺服器分配的一塊儲存空間。
伺服器通過session_id來表示不同的使用者和瀏覽器。
舉例說一下session的使用?
我們在登入某些網站的時候,輸入了使用者名稱密碼,登入以後再開啟新的頁面時,自動顯示的是已登入的狀態,不需要再次重新登入。這裡就是session功能的一個小小的體現。
通過sessionid去查session表。
session工作原理
舉個具體的例子來說吧
新增商品到購物車
首先通過瀏覽器向伺服器傳送新增商品到購物車請求,查詢cookie攜帶過來的Sessionid,去查詢本地的session表,如果沒有的話則生成新的,儲存購物車商品到此sessionid對應的記憶體集合中。將sessionid放在cookie中返回給瀏覽器。
session生命週期
當session超過一定時間沒有被進行訪問時,服務端就認為客戶端已經停止活動。然後將這個session刪除。
當用戶關閉瀏覽器時,sessionid的資訊丟失,雖然session伺服器還在,但是已經訪問不到資料了。

Zset 有序
語法:ZINCRBY key increment member
使用場景:實現排行榜 例如微博熱搜排序,key就可以是小時榜/天榜/月榜,member是某一條熱搜詞條,incrementScore就是這個詞條熱度增量/權重增量

List 雙向列表
使用場景:list型別的lrange命令可以分頁檢視佇列中的資料。可將每隔一段時間計算一次的排行榜儲存在list型別中,如學校每次月考學生的成績排名。只有定時計算的排行榜才適合使用list型別儲存。對於頻繁更新的列表,list型別的分頁可能導致列表元素重複或漏掉。
Set 自動去重
在微博應用中,可以將一個使用者所有的關注人存在一個集合中,將其所有粉絲存在一個集合。

4.關於redis的快取穿透和快取雪崩?
什麼是快取穿透?
大量請求的key不存在DB和redis中,請求直接打在了資料庫上,造成壓力過大。
場景解釋:比如id是從1-10,這個時候去查詢id=1000,肯定是查不到的。(id根本就沒包括id=1000的,即使你讓快取區快取這條記錄,他也是不存在的呀?)
如何解決?
1.快取不存在的key
2.布隆過濾器
布隆過濾器實現原理
什麼是布隆過濾器?
一個很長的二進位制向量(位陣列)
一系列隨機函式(雜湊)
空間和時間查詢效率高
有一定的誤判率(雜湊表是精確匹配)
為什麼用它?
當你從一個特別多的資料集裡邊去判斷某一元素是否存在在當前集合中,使用一些常見的操作都是比較耗資源和低效的。
此時布隆過濾器就應運而生。
當一個元素加入到布隆過濾器中進行如下操作:
1.使用布隆過濾器中的雜湊函式對元素值進行計算,得到雜湊值(有幾個雜湊函式得到幾個雜湊值)
2.根據得到的雜湊值,在位陣列中把對應下標的值置為 1。
判斷一個元素是否存在布隆過濾器
1.對給定元素再次進行相同的雜湊計算;
2.得到值之後判斷位陣列中的每個元素是否都為 1,如果值都為 1,那麼說明這個值可能在布隆過濾器中,如果存在一個值不為 1,說明該元素一定不在布隆過濾器中。
3.設定過期時間(比如簡訊驗證碼還有一些其他資料是有時間限制的)
過期時間到了要怎麼刪除呢?
定期刪除和惰性刪除。
分別說說什麼是定期和惰性?
如果通過以上兩種方式還有一些過期key沒被刪除怎麼辦?
資料淘汰機制:
為什麼要用?
保證mysql裡資料量很大的時候,redis裡邊存的都是熱點資料
是什麼?
volatile-Iru:從已設定過期時間的資料集(serverdb[il.expires)中挑選最近最少使用的資料液汰
volatile-ttl:從已設定過期時間的資料集(serverdb[il.expires)中挑選將要過期的資料淘汰
volatile-random:從已設定過期時間的資料集(serverdb[ilexpires)中任意選擇資料淘汰
allkeys-lru:當記憶體不足以容納新寫入資料時,在鍵空間中,移除最近最少使用的key(這個是最常用的)
allkeys-random:從資料集(serverdb[ildict)中任意選擇資料淘汰
no-eviction:禁止驅逐資料,也就是說當記憶體不足以容納新寫入資料時,新寫入操作會報錯。
4.0版本後增加以下兩種:volatile-lfu:從已設定過期時間的資料集(serverdb[ilexpires)中挑選最不經常使用的資料淘汰
allkeys-lfu:當記憶體不足以容納新寫入資料時,在鍵空間中,移除最不經常使用的key

什麼是快取雪崩?
同一時間內,redis出現大面積的資料失效,大量的請求直接打在DB上,造成DB伺服器壓力過大,崩潰。
實際場景:搶購(00:00-00:30),放很多快取讓使用者去查,到時間清除。
雪崩:直接影響(因為redis是共享的):redis,間接:系統,mysql
如何解決?
1.熱點資料失效時間分散
2.增加Redis伺服器的數量
3.資料庫降級處理,不要然過多請求一次性打在DB上,可以返回一些預設值,比如“系統繁忙,請稍後重試”。

5.redis屬於什麼執行緒模型?
單執行緒模型。因為他內部使用檔案事件處理器,而這個檔案事件處理器就是單執行緒的。
檔案事件處理器構成
在這裡插入圖片描述
檔案事件是對套接字操作的抽象,每當一個套接字準備好執行連線應答(accept)、寫入(write)、讀取(read)、關閉(close)等操作時,就會相應產生一個檔案事件。
I/O多路複用器負責通過loop迴圈監聽多個套接字,同時將一系列套接字按循序儲存到一個佇列中,由佇列向檔案事件分派器傳送佇列中套接字,套接字是有序的。
檔案事件分配器接受佇列中的套接字並根據套接字產生的事件型別,相應呼叫不同的事件處理器。

6.redis為什麼要使用單執行緒模型?
因為不需要來回進行執行緒的切換,節省資源。

7.redis支援事務嗎?
redis是支援事務的。
那聊聊redis的事務吧。
redis事務就是一次性、順序性、排他性的執行一個佇列中的一系列命令。
Redis 是單程序程式,並且它保證在執行事務時,不會對事務進行中斷,事務可以執行直到執行完所有事務佇列中的命令為止。因此,Redis 的事務是總是帶有隔離性的。
不保證原子性,單條命令保證原子性,但是事務不保證原子性。

8.談談你對redis中的RDB和AOF認識。
redis如何實現持久化?
為什麼要進行持久化,因為redis資料是放在記憶體當中的,如果沒有進行持久化,計算機一重啟,資料就全部消失了。
RDB
在指定的時間間隔,將記憶體中的資料集快照寫到磁碟上。其實是fork一個子程序,先把資料集寫入臨時檔案,寫入成功後,再替換掉原來的檔案,然後用二進位制壓縮儲存。
AOF
以日誌的形式記錄伺服器所處理的每一個讀,刪除操作。以文字的方式記錄。
比較一下二者吧
採用RDB的話,整個資料庫只包含一個檔案,適用於災難性恢復。每隔一個時間間隔,會進行復制,會生成多個檔案。適合做冷備。把這種完整的資料檔案傳送到遠端服務做好安全儲存。
當資料遇到丟失時, 你可以很方便的從不同的備份粒度(版本)來恢復資料集。
效能最大化。
資料集很大,RDB啟動效率更高。
想保證資料高可用,它不是很好的選擇,因為一旦宕機的話,他還沒來得及寫入磁碟的資料就丟失了。
如果資料集比較大,會導致整個伺服器停止服務幾百毫秒甚至1秒。
存放的是指令日誌,做資料恢復的時候,是要進行回放和執行所有的日誌指令。
而RDB就是資料檔案,所以他比較快。
AOF
更好的儲存檔案,每隔一秒就進行fsync(同步記憶體中所有已修改的檔案資料到儲存裝置。);
日誌檔案即使過大,也不會對客戶端造成影響。
redis預設的是RDB。

9.redis有哪些優缺點?
讀寫效能優異, Redis能讀的速度是110000次/s,寫的速度是81000次/s;
支援事務,單個Redis執行的命令是原子性的,redis的事務不是原子性的,單執行緒;
支援主從複製;
資料結構豐富;
缺點:
資料庫容量受到實體記憶體限制;
不具備自動容錯和恢復功能;
較難支援線上擴容。

10.為什麼要用redis?
在多例項情況下,各例項共用一份快取資料,快取具有一致性。
Java自帶的 map 或者 guava 實現的是本地快取,而且不具有一致性。

11.redis的過期時間和永久有效如何設定
EXPIRE和PERSIST命令。

12redis記憶體用完會發生什麼
如果達到設定的上限,Redis的寫命令會返回錯誤資訊(但是讀命令還可以正常返回。)

13.redis如何做記憶體優化
使用散列表。

14.redis事務開始的三個階段
事務開始MULTI
命令入隊
事務執行EXEC