redis基礎

原文鏈接:https://blog.csdn.net/a745233700/article/details/80931516

一、什麼是Redis:
Redis是一款開源的內存中的數據結構存儲系統,是一個基於內存運行的高性能,並支持持久化的key-value分佈式NoSQL數據庫。它可以用作:數據庫、緩存、消息中間件。

Redis的優秀之處不僅僅是性能,Redis最大的魅力是支持保存多種數據結構,Redis支持的數據結構有:String、List、Set、Hash、Sorted Set。一個字符串類型的值能存儲最大容量是512M。

因此Redis可以用來實現很多有用的功能:比方說用List來做FIFO雙向鏈表,實現一個輕量級的高性 能消息隊列服務,用他的Set可以做高性能的tag系統等等。另外Redis也可以對存入的Key-Value設置expire時間,因此也可以被當作一個功能加強版的memcached來用。

Redis的主要缺點是數據庫容量受到物理內存的限制,不能用作海量數據的高性能讀寫,因此Redis適合的場景主要侷限在較小數據量的高性能操作和運算上。

Redis也提供了持久化的選項,這些選項可以讓用戶將自己的數據保存到磁盤上面進行存儲。根據實際情況,可以每隔一定時間將數據集導出到磁盤(快照),或者追加到命令日誌中(AOF只追加文件),他會在執行寫命令時,將被執行的寫命令複製到硬盤裏面。當然也可以關閉持久化功能,將Redis作爲一個高效的網絡的緩存數據功能使用。

Redis不使用表,他的數據庫不會預定義或者強制去要求用戶對Redis存儲的不同數據進行關聯。

數據庫的工作模式按存儲方式可分爲:硬盤數據庫和內存數據庫。Redis 將數據儲存在內存裏面,讀寫數據的時候都不會受到硬盤 I/O 速度的限制,所以速度極快。

(1)硬盤數據庫的工作模式: 

(2)內存數據庫的工作模式:

總而言之:

Redis是一款基於內存運行的高性能,並支持持久化的key-value分佈式NoSQL數據庫,因爲基於內存,所以存寫速度非常快,因此被廣泛應用於緩存方向。

支持的數據結構有:String、List、Set、Hash、Sorted Set。一個字符串類型的值能存儲最大容量是512M。Redis不使用表,他的數據庫不會預定義或者強制去要求用戶對Redis存儲的不同數據進行關聯。

Redis是單進程單線程的:redis利用隊列技術將併發訪問變爲串行訪問,消除了傳統數據庫串行控制的開銷。

Redis的主要缺點是數據庫容量受到物理內存的限制,不能用作海量數據的高性能讀寫,因此Redis適合的場景主要侷限在較小數據量的高性能操作和運算上。

 

二、爲什麼使用Redis:
主要從“高性能”和“高併發”這兩點來看待這個問題。

(1)高性能:

假如用戶第一次訪問數據庫中的某些數據。這個過程會比較慢,因爲是從硬盤上讀取的。將該用戶訪問的數據存在數緩存中,這樣下一次再訪問這些數據的時候就可以直接從緩存中獲取了。操作緩存就是直接操作內存,所以速度相當快。如果數據庫中的對應數據改變的之後,同步改變緩存中相應的數據即可。

(2)高併發:

直接操作緩存能夠承受的請求是遠遠大於直接訪問數據庫的,所以我們可以考慮把數據庫中的部分數據轉移到緩存中去,這樣用戶的一部分請求會直接到緩存這裏而不用經過數據庫。

 

三、Redis爲什麼這麼快:
(1)完全基於內存,數據存在內存中,絕大部分請求是純粹的內存操作,非常快速。

(2)採用單線程,避免了不必要的上下文切換和競爭條件,也不存在多進程或者多線程導致的切換而消耗 CPU,不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作,沒有因爲可能出現死鎖而導致的性能消耗。

(3)數據結構簡單,對數據操作也簡單,Redis中的數據結構是專門進行設計的

(4)使用非阻塞IO多路複用機制。

多路I/O複用模型是利用 select、poll、epoll 可以同時監察多個流的 I/O 事件的能力,在空閒的時候,會把當前線程阻塞掉,當有一個或多個流有 I/O 事件時,就從阻塞態中喚醒,於是程序就會輪詢一遍所有的流(epoll 是隻輪詢那些真正發出了事件的流),並且只依次順序的處理就緒的流,這種做法就避免了大量的無用操作。

這裏“多路”指的是多個網絡連接,“複用”指的是複用同一個線程。採用多路 I/O 複用技術可以讓單個線程高效的處理多個連接請求(儘量減少網絡 IO 的時間消耗),且 Redis 在內存中操作數據的速度非常快,也就是說內存內的操作不會成爲影響Redis性能的瓶頸,主要由以上幾點造就了 Redis 具有很高的吞吐量。

(5)使用底層模型不同,它們之間底層實現方式以及與客戶端之間通信的應用協議不一樣,Redis直接自己構建了VM 機制 ,因爲一般的系統調用系統函數的話,會浪費一定的時間去移動和請求;

 

四、redis和memchached的區別:
(1)redis支持更豐富的數據類型,支持更復雜的應用場景:Redis不僅僅支持簡單的k/v類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。memcache支持簡單的數據類型,String。

(2)redis可以存儲的單個鍵值可以存儲的容量更大,一個字符串類型的值能存儲最大容量是512M。

(3)redis支持持久化,可以將內存中的數據保存在磁盤中,重啓的時候可以再次加載進行使用,而memcached把所有數據全部存儲在內存中。

(4)集羣模式:memcached沒有原生的集羣模式,需要依靠客戶端來實現往集羣中分片寫入數據;但是 redis 目前是原生支持 cluster 模式的。

(5)網絡IO模型:Memcached是多線程,非阻塞IO複用的網絡模型;Redis使用單線程的多路 IO 複用模型。

 

五、Redis 的適用場景:
(1)會話緩存(Session Cache):

最常用的一種使用Redis的情景是會話緩存(session cache)。用Redis緩存會話比其他存儲(如Memcached)的優勢在於:Redis提供持久化。當維護一個不是嚴格要求一致性的緩存時,如果用戶的購物車信息全部丟失,大部分人都會不高興的,

(2)全頁緩存(FPC):

除基本的會話token之外,Redis還提供很簡便的FPC平臺。回到一致性問題,即使重啓了Redis實例,因爲有磁盤的持久化,用戶也不會看到頁面加載速度的下降,

(3)隊列:

Reids在內存存儲引擎領域的一大優點是提供 list 和 set 操作,這使得Redis能作爲一個很好的消息隊列平臺來使用。

(4)排行榜/計數器:

Redis在內存中對數字進行遞增或遞減的操作實現的非常好。集合(Set)和有序集合(Sorted Set)也使得我們在執行這些操作的時候變的非常簡單。

(5)發佈/訂閱(Publish, Subscribe):

 

 六、Redis的相關問題:
1、Redis回收進程如何工作的?

一個客戶端運行了新的命令,添加了新的數據。Redi檢查內存使用情況,如果大於maxmemory的限制, 則根據設定好的策略進行回收。一個新的命令被執行,等等。所以我們不斷地穿越內存限制的邊界,通過不斷達到邊界然後不斷地回收回到邊界以下。如果一個命令的結果導致大量內存被使用(例如很大的集合的交集保存到一個新的鍵),不用多久內存限制就會被這個內存使用量超越。

2、 Redis裏面有1億個key,其中有10w個key是以某個固定的已知的前綴開頭的,如何將它們全部找出來?

使用keys指令可以掃出指定模式的key列表。 如果這個redis正在給線上的業務提供服務,由於redis關鍵的一個特性:redis的單線程的。keys指令會導致線程阻塞一段時間,線上服務會停頓,直到指令執行完畢,服務才能恢復。這個時候可以使用scan指令,scan指令可以無阻塞的提取出指定模式的key列表,但是會有一定的重複概率,在客戶端做一次去重就可以了,但是整體所花費的時間會比直接用keys指令長。

3、使用過Redis做異步隊列麼,你是怎麼用的?

(1)一般使用list結構作爲隊列,rpush生產消息,lpop消費消息。當lpop沒有消息的時候,要適當sleep一會再重試。 或者list還有個指令叫blpop,在沒有消息的時候,它會阻塞住直到消息到來。

(2)一次消費多次?使用pub/sub主題訂閱者模式,可以實現1:N的消息隊列。

pub/sub有什麼缺點?在消費者下線的情況下,生產的消息會丟失,得使用專業的消息隊列如rabbitmq等。

(3)redis如何實現延時隊列?使用sorted set,拿時間戳作爲score,消息內容作爲key調用zadd來生產消息,消費者用zrangebyscore指令獲取N秒之前的數據輪詢進行處理。

4、爲什麼redis需要把所有的數據放到內存中?

Redis爲了達到最快的讀寫速度將數據都讀到內存中,並通過異步的方式將數據寫入磁盤。所以redis具有快速和數據持久化的特徵。如果不將數據放在內存中,磁盤I/O速度爲嚴重影響redis的性能。

5、Redis支持的Java客戶端都有哪些?官方推薦用哪個?

Redisson、Jedis、lettuce等等,官方推薦使用Redisson。

6、Redis key的過期時間和永久有效分別怎麼設置?

EXPIRE和PERSIST命令。

7、redis哈希槽的概念:

Redis集羣沒有使用一致性hash,而是引入了哈希槽的概念,Redis集羣有16384個哈希槽,每個key通過CRC16校驗後對16384取模來決定放置哪個槽,集羣的每個節點負責一部分hash槽。

8、redis常見性能問題和解決方案:

(1) Master最好不要做任何持久化工作:如RDB內存快照和AOF日誌文件,特別是不要啓用內存快照做持久化,如果數據比較關鍵,某個Slave開啓AOF備份數據,策略爲每秒同步一次。Master寫內存快照,save命令調度rdbSave函數,會阻塞主線程的工作,當快照比較大時對性能影響是非常大的,會間斷性暫停服務,所以Master最好不要寫內存快照。

(2) 在Master AOF持久化的情況下,如果不重寫AOF文件,這個持久化方式對性能的影響是最小的,但是AOF文件會不斷增大,AOF文件過大會影響Master重啓的恢復速度。

(3) 儘量避免在壓力很大的主庫上增加從庫。

(4) 主從複製不要用圖狀結構,用單向鏈表結構更爲穩定,即:Master <- Slave1 <- Slave2 <- Slave3...這樣的結構方便解決單點故障問題,實現Slave對Master的替換。如果Master掛了,可以立刻啓用Slave1做Master,其他不變。

(5) 爲了主從複製的速度和連接的穩定性,Master和Slave最好在同一個局域網內。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章