Redis 相關知識點匯總


一、關於 Redis

1.Redis 是什么

  Redis 是一個開放源代碼(BSD 許可)的內存中數據結構存儲,可用作數據庫,緩存和消息代理,是一個基於鍵值對的 NoSQL 數據庫。

2.Redis 特性有哪些

  • 速度快
  • 基於鍵值對的數據結構服務器
  • 豐富的功能、豐富的數據結構
  • 簡單穩定
  • 客戶端語言多
  • 持久化
  • 主從復制
  • 高可以 & 分布式

3.Redis 合適的應用場景

  • 緩存
  • 排行榜
  • 計數器
  • 分布式會話
  • 分布式鎖
  • 社交網絡
  • 最新列表
  • 消息系統

4.除了 Redis 以外的 NoSQL 數據庫

  MongoDB、MemcacheDB、Cassandra、CouchDB、Hypertable、Leveldb。

5.Redis 和 Memcache 區別

  • 支持的存儲類型不同,memcached 只支持簡單的 k/v 結構。redis 支持更多類型的存儲結構類型(詳見問題6)。
  • memcached 數據不可恢復,redis 則可以把數據持久化到磁盤上。
  • 新版本的 redis 直接自己構建了 VM 機制 ,一般的系統調用系統函數的話,會浪費一定的時間去移動和請求。
  • redis 當物理內存用完時,可以將很久沒用到的 value 交換到磁盤。

6.Redis 的幾種數據類型

   基礎:字符串(String)、哈希(hash)、列表(list)、集合(set)、有序集合(zset)。

   還有HyperLogLog、流、地理坐標等。

7.Redis 的高級功能

  消息隊列、自動過期刪除、事務、數據持久化、分布式鎖、附近的人、慢查詢分析、Sentinel 和集群等多項功能。

 

二、Redis 啟動和執行

1.Redis 幾個比較主要的可執行文件

 

 

 

2.啟動 Redis 的幾種方式

  1. 默認配置 : ./redis-server
  2. 運行啟動: redis-server 加上要修改配置名和值(可以是多對),沒有配置的將使用默認配置。例如: redis-server ———port 7359
  3. 指定配置文件啟動: ./redis-server/opt/redis/redis.conf

3.Redis 配置自定義配置

  redis 目錄下有一個 redis.conf 的模板配置。只需要復制模板配置然后修改即可。

  一般來說大部分生產環境都會用指定配置文件的方式啟動redis。

4.Redis 客戶端命令執行的方式

  • (1)交互方式:
    redis-cli -h 127.0.0.1 -p 6379
    # 連接到redis后,后面執行的命令就可以通過交互方式實現了。
  • (2)命令行方式:
    redis-cli -h 127.0.0.1 -p 6379 get value

5.停止 Redis 服務

  1. Kill-9 pid (粗暴,請不要使用,數據不僅不會持久化,還會造成緩存區等資源不能被優雅關閉)。
  2. 可以用 redis 的 shutdown 命令,可以選擇是否在關閉前持久化數據。
    redis-cli shutdown nosave|save

6.如何查看當前鍵是否存在?

  exists key

7.如何刪除數據?

  del key

 

三、Redis 注意事項

1.Redis 為什么快

  • redis 使用了單線程架構和 I/O 多路復用模型模型。
  • 純內存訪問。
  • 由於是單線程避免了線程上下文切換帶來的資源消耗。
  •  C語言實現,優化過的數據結構,基於幾種基礎的數據結構,redis做了大量的優化,性能極高

C語言實現,優化過的數據結構,基於幾種基礎的數據結構,redis做了大量的優化,性能極高

2.為什么 Redis6.0 是想用多線程

  redis 使用多線程並非是完全摒棄單線程,redis 還是使用單線程模型來處理客戶端的請求,只是使用多線程來處理數據的讀寫和協議解析,執行命令還是使用單線程。

  這樣做的目的是因為 redis 的性能瓶頸在於網絡 IO 而非 CPU,使用多線程能提升 IO 讀寫的效率,從而整體提高 redis 的性能。

3.字符串最大不能超過多少

  512MB。

4.Redis 默認分多少個數據庫

  16個。

5.Redis 持久化的幾種方式?

  RDB、AOF、混合持久化。

 

四、RDB 持久化

  RDB(Redis DataBase)持久化是把當前進程數據生成快照保存到硬盤的過程。

  Tips:是以二進制的方式寫入磁盤。

1.RDB 的持久化是如何觸發的?

  1. 手動觸發:
    • save :阻塞當前 Redis 服務器,直到 RDB 過程完成為止,如果數據比較大的話,會造成長時間的阻塞,線上不建議。
    • bgsave:redis 進程執行 fork 操作創作子進程,持久化由子進程負責,完成后自動結束,阻塞只發生在fork階段,一半時間很短。 
  2. 自動觸發:
    • savexsecends n: 表示在 x 秒內,至少有 n 個鍵發生變化,就會觸發 RDB 持久化。也就是說滿足了條件就會觸發持久化。
    • flushall:主從同步觸發

2.RDB 的優點

  • rdb 是一個緊湊的二進制文件,代表 Redis 在某個時間點上的數據快照。
  • 適合於備份,全量復制的場景,對於災難恢復非常有用。
  • Redis 加載 RDB 恢復數據的速度遠快於 AOF 方式。

3.RDB的缺點

  • RDB 沒法做到實時的持久化。中途意外終止,會丟失一段時間內的數據。
  • RDB 需要 fork() 創建子進程,屬於重量級操作,可能導致 Redis卡頓若干秒。

4.如何禁用持久化

  一般來說生成環境不會用到,了解一下也有好處的。

config set save ""

 

五、AOF 持久化

  AOF(appendonly file)為了解決 rdb 不能實時持久化的問題,aof 來搞定。以獨立的日志方式記錄把每次命令記錄到 aof 文件中。

1.如何查詢 AOF 是否開啟

config get appendonly

2.如何開啟 AOF

  • 命令行方式:實時生效,但重啟后失效。
    config set appendonly
  • 配置文件:需要重啟生效,重啟后依然生效。
    appendonly yes

3.AOF 的工作流程

  1. 所有寫入命令追加到 aof_buf 緩沖區。
  2. AOF 緩沖區根據對應的策略向硬盤做同步操作。
  3. 隨着 AOF 文件越來越大,需要定期對 AOF 文件進行重寫,達到壓縮的目的。
  4. 當 redis 服務器重啟時,可以加載 AOF 文件進行數據恢復。

4.為什么 AOF 要先把命令追加到緩存區(aof_buf)中

  Redis 使用單線程響應命令,如果每次寫入文件命令都直接追加到硬盤,性能就會取決於硬盤的負載。如果使用緩沖區,redis提供多種緩沖區策略,在性能和安全性方面做出平衡。

5.AOF 持久化如何觸發的

  • 自動觸發:滿足設置的策略和滿足重寫觸發。策略:(在配置文件中配置

     

  • 手動觸發:(執行命令)
    bgrewriteaof 

6.AOF 優點

  • AOF 提供了 3 種保存策略:每秒保存、跟系統策略、每次操作保存。實時性比較高,一般來說會選擇每秒保存,因此意外發生時頂多失去一秒的數據。
  • 文件追加寫形式,所以文件很少有損壞問題,如最后意外發生少寫數據,可通過 redis-check-aof 工具修復。
  • AOF 由於是文本形式,直接采用協議格式,避免二次處理開銷,另外對於修改也比較靈活。

7.AOF 缺點

  • AOF 文件要比 RDB 文件大。
  • AOF 冷備沒 RDB 迅速。
  • 由於執行頻率比較高,所以負載高時,性能沒有 RDB 好。

 

六、混合持久化

  一般來說線上都會采取混合持久化。redis4.0 以后添加了新的混合持久化方式。

1.優點:

  在快速加載的同時,避免了丟失過更多的數據。

2.缺點:

  • 由於混合了兩種格式,所以可讀性差。
  • 兼容性,需要 4.0 以后才支持。

 

七、緩存

1. 緩存穿透

  正常情況下,我們去查詢數據都是存在。那么請求去查詢一條數據庫中根本就不存在的數據,也就是緩存和數據庫都查詢不到這條數據,但是請求每次都會打到數據庫上面去。這種查詢不存在數據的現象稱為緩存穿透。

  緩存穿透產生大量的請求到數據庫去查詢。可能會導致數據庫由於壓力過大而宕機。

解決方案:在緩存中將該鍵對應的值為設置為 null,配置過期時間

2.緩存擊穿

  在平常高並發的系統中,大量的請求同時查詢一個 key 時,此時若這個 key 正好失效了,就會導致大量的請求都打到數據庫上面去。這種現象即緩存擊穿。

解決方案:緩存擊穿的現象是多個線程同時去查詢數據庫的同一條數據,可以在第一個查詢數據的請求上使用一個互斥鎖來鎖住它。其他的線程走到這一步拿不到鎖就等着,等第一個線程查詢到了數據,然后做緩存。后面的線程進來發現已經有緩存了,就直接走緩存。

3.緩存雪崩

  當某一時刻發生大規模的緩存失效的情況。比如緩存服務宕機或集中過期,會有大量的請求直接打到DB上。結果 DB 稱不住,掛掉。

解決方案

  • 事前:使用集群緩存,保證緩存服務的高可用。如果是使用 Redis,可以使用 主從+哨兵 ,Redis Cluster 來避免 Redis 全盤崩潰的情況。

  • 事中:使用 ehcache 本地緩存 + Hystrix 限流&降級 ,避免 MySQL 被打死的情況發生。使用 Hystrix 進行 限流 & 降級 ,比如一秒來了5000個請求,可以設置假設只能有一秒 2000 個請求能通過這個組件,那么其他剩余的 3000 請求就會走限流邏輯,然后去調用降級組件(降級)。比如設置的一些默認值呀之類的。以此來保護最后的 MySQL 不會被大量的請求給打死。

  • 事后:開啟 Redis 持久化機制,盡快恢復緩存集群

4.緩存預熱

  系統上線后,提前將相關數據加載到緩存系統,避免用戶先查庫,然后在緩存。

八、其他

1.安裝 Redis 步驟

  • 下載 Redis 指定版本源碼安裝包壓縮到當前目錄。
  • 解壓縮 Redis 源碼安裝包。
  • 建立一個 redis 目錄軟鏈接,指向解壓包。
  • 進入 redis 目錄
  • 編譯
  • 安裝

  或者:docker pull redis。

2.Redis 事務

  事務提供了一種將多個命令請求打包,一次性、按順序的執行多個命令的機制。並且在事務執行期間,服務器不會中斷事務而改去執行其他客戶端命令請求,它會

3.Redis 事務開始到結束的幾個階段?

  • 開啟事務
  • 命令入隊
  • 執行事務/放棄事務

4.Redis 中 key 的過期操作?

# 設置key的生存時間為n秒:
expire key nseconds

# 設置key的生存時間為nmilliseconds:
pxpire key milliseconds

# 設置過期時間為timestamp所指定的秒數時間戳:
expireat key timespamp

# 設置過期時間為timestamp毫秒級時間戳:
pexpireat key millisecondsTimestamp

5.Redis 過期鍵刪除策略?

  • 定時刪除:在設置的過期時間同時,創建一個定時器在鍵的過期時間來臨時,立即執行隊鍵的操作刪除。
  • 惰性刪除:放任過期鍵不管,但每次從鍵空間中獲取鍵時,都檢查取得的鍵是否過期,如果過期就刪除,如果沒有就返回該鍵。
  • 定期刪除:每隔一段時間執行一次刪除過期鍵操作,並通過先吃刪除操作執行的時長和頻率來減少刪除操作對 CPU 時間的影響。

定期+惰性都沒有刪除怎么辦

假設 redis 每次定期隨機查詢 key 的時候沒有刪掉,這些 key 也沒有做查詢的話,就會導致這些key一直保存在 redis 里面無法被刪除,這時候就會走到 redis 的內存淘汰機制。

  1. volatile-lru:從已設置過期時間的key中,移出最近最少使用的key進行淘汰
  2. volatile-ttl:從已設置過期時間的key中,移出將要過期的key
  3. volatile-random:從已設置過期時間的key中隨機選擇key淘汰
  4. allkeys-lru:從key中選擇最近最少使用的進行淘汰
  5. allkeys-random:從key中隨機選擇key進行淘汰
  6. noeviction:當內存達到閾值的時候,新寫入操作報錯

6.Pipeline

  命令批處理技術,對命令進行組裝,然后一次性執行多個命令。可以有效的節省 RTT(Round Trip Time 往返時間)。

經過測試驗證:

  • pipeline 執行速度一般比逐條執行快。
  • 客戶端和服務的網絡延越大,pipeline 效果越明顯。

7.如何獲取當前最大內存?如何動態設置?

# 獲取最大內存:
config get maxmemory

# 設置最大內存:
config set maxmemory 1GB

8.Redis 內存溢出控制

  當 Redis 所用內存達到 maxmemory 上限時,會出發相應的溢出策略。

9.Redis 內存溢出策略

  • noeviction(默認策略):拒絕所有寫入操作並返回客戶端錯誤信息(error) OOM command not allowed when used memory,只響應讀操作。
  • volatile-lru:根據 LRU 算法刪除設置了超時屬性(expire)的鍵,直到騰出足夠空間為止。如果沒有可刪除的鍵對象,回退到noeviction策略。
  • allkeys-lru:根據 LRU 算法刪除鍵,不管數據有沒有設置超時屬性, 直到騰出足夠空間為止。
  • allkeys-random:隨機刪除所有鍵,直到騰出足夠空間為止。
  • volatile-random:隨機刪除過期鍵,直到騰出足夠空間為止。
  • volatile-tth 根據鍵值對象的 ttl 屬性,刪除最近將要過期數據。如果沒有,回退到 noeviction 策略。

10.Redis 高可用方案

  RedisSentinel(哨兵)能自動完成故障發現和轉移。

  哨兵功能比單純的主從架構全面,它具備自動故障轉移、集群監控、消息通知等功能。

  哨兵可以同時監視多個主從服務器,並且在被監視的master下線時,自動將某個slave提升為master,然后由新的master繼續接收命令。整個過程如下:

  1. 初始化 sentinel,將普通的 redis 代碼替換成 sentinel 專用代碼
  2. 初始化 masters 字典和服務器信息,服務器信息主要保存 ip:port,並記錄實例的地址和 ID
  3. 創建和 master 的兩個連接,命令連接和訂閱連接,並且訂閱 sentinel:hello 頻道
  4. 每隔 10 秒向 master 發送 info 命令,獲取 master 和它下面所有 slave 的當前信息
  5. 當發現 master 有新的 slave 之后,sentinel 和新的 slave 同樣建立兩個連接,同時每個 10 秒發送 info 命令,更新 master 信息
  6. sentinel 每隔 1 秒向所有服務器發送 ping 命令,如果某台服務器在配置的響應時間內連續返回無效回復,將會被標記為下線狀態
  7. 選舉出領頭 sentinel,領頭 sentinel 需要半數以上的 sentinel 同意
  8. 領頭 sentinel 從已下線的的 master 所有 slave 中挑選一個,將其轉換為 master
  9. 讓所有的 slave 改為從新的 master 復制數據
  10. 將原來的 master 設置為新的 master 的從服務器,當原來 master 重新回復連接時,就變成了新 master 的從服務器

sentinel 會每隔 1 秒向所有實例(包括主從服務器和其他 sentinel)發送 ping 命令,並且根據回復判斷是否已經下線,這種方式叫做主觀下線。當判斷為主觀下線時,就會向其他監視的 sentinel 詢問,如果超過半數的投票認為已經是下線狀態,則會標記為客觀下線狀態,同時觸發故障轉移。

11.Redis 集群方案

  Twemproxy、Redis Cluster、Codis。

  如果說依靠哨兵可以實現 redis 的高可用,如果還想在支持高並發同時容納海量的數據,那就需要 redis 集群。redis集群是 redis 提供的分布式數據存儲方案,集群通過數據分片 sharding 來進行數據的共享,同時提供復制和故障轉移的功能。

一個redis集群由多個節點 node 組成,而多個 node 之間通過 cluster meet 命令來進行連接,節點的握手過程:

  1. 節點A收到客戶端的 cluster meet 命令
  2. A 根據收到的 IP 地址和端口號,向 B 發送一條 meet 消息
  3. 節點 B 收到 meet 消息返回 pong
  4. A 知道 B 收到了 meet 消息,返回一條 ping 消息,握手成功
  5. 最后,節點 A 將會通過 gossip 協議把節點 B 的信息傳播給集群中的其他節點,其他節點也將和 B 進行握手

12.RedisCluster 槽

  范圍:0~16383

  redis 通過集群分片的形式來保存數據,整個集群數據庫被分為 16384 個槽,集群中的每個節點可以處理 0-16384 個槽,當數據庫16384個槽都有節點在處理時,集群處於上線狀態,反之只要有一個槽沒有得到處理都會處理下線狀態。通過 cluster addslots 命令可以將槽指派給對應節點處理。

  槽是一個位數組,數組的長度是 16384/8=2048,而數組的每一位用 1 表示被節點處理,0 表示不處理,如圖所示的話表示 A 節點處理 0-7 的槽。

  當客戶端向節點發送命令,如果剛好找到槽屬於當前節點,那么節點就執行命令,反之,則會返回一個 MOVED 命令到客戶端指引客戶端轉向正確的節點。(MOVED 過程是自動的)

  如果增加或者移出節點,對於槽的重新分配也是非常方便的,redis 提供了工具幫助實現槽的遷移,整個過程是完全在線的,不需要停止服務。

13.Redis 鎖實現思路

  • setnx(set if not exists),如果創建成功則表示獲取到鎖。
  • setnxlock true 創建鎖
  • dellock 釋放鎖

  如果中途崩潰,無法釋放鎖?此時需要考慮到超時時間的問題。比如 :expire lock 300。由於命令是非原子的,所以還是會死鎖,如何解決?Redis支持 set 並設置超時時間的功能。比如: set lock true ex 30 nx。

14.布隆過濾器

  是1970年由布隆提出的。它實際上是一個很長的二進制向量和一系列隨機映射函數。布隆過濾器可以用於檢索一個元素是否在一個集合中。它的優點是空間效率和查詢時間都比一般的算法要好的多,缺點是有一定的誤識別率和刪除困難。

  Tips:當判斷一定存在時,可能會誤判,當判斷不存在時,就一定不存在。

 

 

 

 

 

 

參考:https://mp.weixin.qq.com/s?__biz=MzA5MzY4NTQwMA==&mid=2651019247&idx=3&sn=806af61723b1eee62fb463b9110bed49

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM