1. 程式人生 > 其它 >史上最全redis面試49題哨兵、複製、事務、叢集、持久化

史上最全redis面試49題哨兵、複製、事務、叢集、持久化

  • 哨兵、複製、事務、叢集、持久化

redis主要有哪些功能

  1. 哨兵和複製(sentinel and replication):
    sentinel可以管理多個redis伺服器,它提供監控、提醒、故障轉移等功能
    replication則是可以讓一個redis伺服器擁有一個或多個配備伺服器
    redis也是利用這兩個功能保證了服務的高可用性
  2. 事務:
    redis支援事務,但是又不完全支援,因為它沒有回滾機制
  3. LUA指令碼
    在事務的基礎上,如果我們需要一次性執行更復雜的操作(包含一些邏輯判斷),則lua就可以排上用場了
  4. 持久化
    redis的持久化指的是redis會把記憶體中的資料寫入到磁碟中,在redis重新啟動的時候載入這些資料,
    從而最大程度的降低快取丟失帶來的影響
  5. 叢集
    單臺伺服器的資源總是有限的,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的優勢

  1. redis是基於記憶體的,讀寫速度極快,類似於hashmap, 查詢和操作的時間複雜度是O(1)
  2. 有豐富的資料型別:string、list、set、zset、hash
  3. 支援事務
  4. 豐富的特性:可用於快取,訊息,設定key的過期時間, 過期後自動刪除

redis單點吞吐量

單點TPS達到8萬/s, QPS達到10萬/s
什麼是QPS:每秒鐘處理的請求數量
什麼是TPS: 每秒鐘處理的事務數量(一個事務在分散式系統中,可能對應多個請求)

redis相比Memcached有哪些優勢

  1. memcached所有的值均是簡單的字串,redis支援豐富的資料型別
  2. redis比memcached速度快很多
  3. redis支援資料的持久化
  4. redis支援資料備份,即master-slaver模式

redis有哪幾種資料淘汰策略

  1. noeviction: 當redis的maxmemory達到最大值繼續寫入時,不會刪除鍵,直接返回錯誤
  2. allkeys-lru: 當redis的maxmemory達到最大值繼續寫入時, 隨機選取maxmemory-examples個key, 然後刪除最近最少使用的key
  3. allkey-random: 當redis的maxmemory達到最大值繼續寫入時, 隨機選取maxmemory-examples個key, 然後隨機刪除一個key
  4. volatile-lru: 當redis的maxmemory達到最大值繼續寫入時, 從帶有過期時間的key中隨機選取maxmemory-examples個key, 刪除最近最少使用的key
  5. volatile-random: 當redis的maxmemory達到最大值繼續寫入時, 從帶有過期時間的key中隨機選取maxmemory-examples個key, 隨機刪除一個key
  6. volatile-ttl: 當redis的maxmemory達到最大值繼續寫入時, 從帶有過期時間的key隨機選取maxmemory-examples個key, 刪除最先過期的key
    redis淘汰資料時還會同步到aof

redis叢集方案應該怎麼做,都有哪些方案?

  1. twemproxy
  2. codis, 目前用的最多的叢集方案,和twemproxy基本一致,但它支援在節點數量改變的情況下,就節點資料可以恢復到新hash節點
  3. 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常見的效能問題和解決方案

  1. master最好不要做任何持久化工作,如RDB記憶體快照或AOF日誌檔案
  2. 為了主從複製的速度與穩定性,master和slaver最好字啊同一個區域網內
  3. 儘量避免在壓力很大的主庫上增加從庫
  4. 主從複製不要用圖狀結構,最好用單向連結串列結構更穩定

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共享(單點登入)
頁面快取
訊息佇列
排行榜/計數器
釋出/訂閱