史上最全redis面試49題哨兵、複製、事務、叢集、持久化
- 哨兵、複製、事務、叢集、持久化
redis主要有哪些功能
- 哨兵和複製(sentinel and replication):
sentinel可以管理多個redis伺服器,它提供監控、提醒、故障轉移等功能
replication則是可以讓一個redis伺服器擁有一個或多個配備伺服器
redis也是利用這兩個功能保證了服務的高可用性 - 事務:
redis支援事務,但是又不完全支援,因為它沒有回滾機制 - LUA指令碼
在事務的基礎上,如果我們需要一次性執行更復雜的操作(包含一些邏輯判斷),則lua就可以排上用場了 - 持久化
redis的持久化指的是redis會把記憶體中的資料寫入到磁碟中,在redis重新啟動的時候載入這些資料,
從而最大程度的降低快取丟失帶來的影響 - 叢集
單臺伺服器的資源總是有限的,CPU資源和IO資源我們可以通過主從複製,讀寫分離,把一部分CPU和IO的壓力轉移到從伺服器上,這有點類似mysql資料庫的主從同步
單臺例項記憶體容量也是有限的,可以通過將資料按照一定的規則分配到多臺伺服器上,橫向擴充套件記憶體容量
redis支援哪幾種資料型別
string:最基本的資料型別,二進位制安全的字串,最大512M
list:按照新增順序保持順序的字串列表
set:無序的字串集合,不包含重複的元素
zset:已排序的字串集合
hash:key-value對的一種集合
redis常用命令
-
keys 鍵命令
- keys 查詢所有key
- type 查詢key的型別
- del 刪除一個key
- expire 給key設定過期時間
- ttl 查詢key還有多長時間過期
- exists 查詢key是否存在
-
string 字串命令
- set 設定一個字串
- setex 設定一個帶過期時間的字串
- mset 設定多個字串
- get 獲取一個字串
- mget 獲取多個字串
- append 給字串追加內容
-
list 列表命令---有序的
- lpush 從列表頭部插入
- rpush 從列表尾部插入
- linsert 從列表中間插入
- llen 統計列表長度
- lindex 按索引取出一個元素
- lrange 取出多個元素
- lset 按索引更新鍵對應的值
- lrem 按照值刪除指定個數的元素
- lpop 從列表頭部彈出一個元素
- rpop 從列表尾部彈出一個元素
- lpushx 從已有的列表頭部插入一個元素,列表不存在不會建立
- rpushx 從已有的列表尾部插入一個元素,列表不存在不會建立
- ltrim 從列表中擷取一部分
-
set 集合命令---無序的,member不可以重複
- sadd 向集合中新增元素
- smembers 顯示所有集合成員
- srem 刪除集合成員
- sismember 判斷某個元素是否是集合中的成員
- srandmember 從集合中隨機選取一個成員
-
zset 有序集合命令---score可以重複,member不可以重複
- zadd 向有序集合中新增元素
- zrange 從有序集合中獲取元素
- zrangebyscore 從有序集合中通過score獲取元素
- zrem 從有序集合中刪除元素
- zremrangebyscore 按照score刪除元素
- zrank 獲取有序結合中元素的索引
- zremrangebyrank 按照索引刪除元素
- zrevrange 反轉有序集合
-
hash 雜湊命令
- hset 設定雜湊值的單個鍵值對
- hmset 設定雜湊值的多個鍵值對
- hget 獲取雜湊值的單個鍵值對
- hmget 獲取雜湊值的多個鍵值對
- hdel 刪除雜湊值中鍵值對
- hkeys 獲取雜湊值中的所有鍵
- hvals 獲取雜湊值中的所有值
- hexists 檢視雜湊值中的某個鍵是否存在
- hgetall 獲取雜湊值中的所有鍵值
- hlen 獲取雜湊中的鍵值對個數
- hsetnx 和hset有點類似,不同之處在於當key對應的field存在時就不做操作了,只有field不存在時才會增加
redis是單程序單執行緒的?
redis是單程序單執行緒的,redis利用佇列技術將併發訪問變為序列訪問,消除了傳統資料庫序列控制的開銷
redis為什麼是單執行緒的?
多執行緒會涉及到鎖,而且多執行緒的上下文切換會消耗CPU資源,CPU不是redis的瓶頸,
redis的瓶頸最有可能是機器記憶體和網路寬頻,單執行緒無法發揮多核CPU效能,可以通過在單機開啟多個redis例項來解決
其它開源軟體模型
Nginx: 多程序單執行緒模型
Memcached: 單程序多執行緒模型
使用redis的優勢
- redis是基於記憶體的,讀寫速度極快,類似於hashmap, 查詢和操作的時間複雜度是O(1)
- 有豐富的資料型別:string、list、set、zset、hash
- 支援事務
- 豐富的特性:可用於快取,訊息,設定key的過期時間, 過期後自動刪除
redis單點吞吐量
單點TPS達到8萬/s, QPS達到10萬/s
什麼是QPS:每秒鐘處理的請求數量
什麼是TPS: 每秒鐘處理的事務數量(一個事務在分散式系統中,可能對應多個請求)
redis相比Memcached有哪些優勢
- memcached所有的值均是簡單的字串,redis支援豐富的資料型別
- redis比memcached速度快很多
- redis支援資料的持久化
- redis支援資料備份,即master-slaver模式
redis有哪幾種資料淘汰策略
- noeviction: 當redis的maxmemory達到最大值繼續寫入時,不會刪除鍵,直接返回錯誤
- allkeys-lru: 當redis的maxmemory達到最大值繼續寫入時, 隨機選取maxmemory-examples個key, 然後刪除最近最少使用的key
- allkey-random: 當redis的maxmemory達到最大值繼續寫入時, 隨機選取maxmemory-examples個key, 然後隨機刪除一個key
- volatile-lru: 當redis的maxmemory達到最大值繼續寫入時, 從帶有過期時間的key中隨機選取maxmemory-examples個key, 刪除最近最少使用的key
- volatile-random: 當redis的maxmemory達到最大值繼續寫入時, 從帶有過期時間的key中隨機選取maxmemory-examples個key, 隨機刪除一個key
- volatile-ttl: 當redis的maxmemory達到最大值繼續寫入時, 從帶有過期時間的key隨機選取maxmemory-examples個key, 刪除最先過期的key
redis淘汰資料時還會同步到aof
redis叢集方案應該怎麼做,都有哪些方案?
- twemproxy
- codis, 目前用的最多的叢集方案,和twemproxy基本一致,但它支援在節點數量改變的情況下,就節點資料可以恢復到新hash節點
- redis cluster3.0自帶的集,特點在於它的分散式演算法不是一致性hash,而是hash槽的概念,以及自身節點設定從節點
redis讀寫分離模型
通過增加slave DB的數量,讀的效能可以線性增長,為了避免master DB單點故障,叢集一般都會採用兩臺master DB做雙機熱備
所以整個叢集讀和寫的可用性都非常高
讀寫分離架構的缺陷在於,不管是master還是slaver,每個節點都需要儲存完整資料,如果資料量很大的情況下,
叢集的擴充套件能力還是受限於單個節點的儲存能力,而且對於write-intensive的應用,讀寫分離的架構並不合適
redis資料分片模型
為了解決讀寫分離模型的缺陷,可以將資料分片模型應用進來,
可以將每個節點都看成獨立的master,然後通過業務實現資料分片
- 結合上面兩種模型,可以將每個master設定成由一個master多個slaver組成的模型
- 通過讀寫分離模型+資料分片模型大大增強了redis叢集的資料儲存能力和讀寫併發能力
redis提供了哪幾種持久化方式
RDB持久化方式能夠在指定的時間間隔對你的資料進行快照儲存
AOF持久化方式是記錄每次對伺服器的寫操作,當伺服器重啟的時候會重新執行這些命令恢復原始資料
當然也可以同時開啟這兩種持久化方式,當吳福氣重啟的時候會有限載入AOF檔案來恢復原始資料
因為通常情況下AOF檔案儲存的資料要比RDB中的資料要完整
redis常見的效能問題和解決方案
- master最好不要做任何持久化工作,如RDB記憶體快照或AOF日誌檔案
- 為了主從複製的速度與穩定性,master和slaver最好字啊同一個區域網內
- 儘量避免在壓力很大的主庫上增加從庫
- 主從複製不要用圖狀結構,最好用單向連結串列結構更穩定
redis雜湊槽的概念
redis cluster3.0沒有使用一致性hash,而是使用了hash槽,當需要在redis叢集中放入一個key-value時
根據CRC16(key) mod 16384的值,決定將一個key放入哪個桶中
redis叢集最大節點個數是多少
redis叢集預先分佈好16384個桶(雜湊槽)
redis叢集會有寫操作丟失嗎?為什麼
redis並不能保證資料的強一致性,在實際中叢集有可能會有寫丟失操作
redis叢集之間是如何複製的
非同步複製
redis如何做記憶體優化
儘可能使用散列表(hash型別),散列表使用的記憶體非常小,所以應該儘可能將資料模型抽象到散列表裡面
比如web系統中的一個使用者物件,不要將使用者名稱、姓氏、郵箱、密碼都設定單獨的key
而是把這個使用者的所有資訊儲存到一張散列表裡面, 大大節省記憶體
redis的回收程序如何工作的
一個客戶端運行了新命令,添加了新資料,檢查redis的記憶體使用達到maxmemory最大值時,
就會使用預設的LRU演算法進行最近最少使用進行淘汰回收
redis回收使用的什麼演算法
LRU演算法
redis有哪些應用場景
session共享(單點登入)
頁面快取
訊息佇列
排行榜/計數器
釋出/訂閱