Redis功能總結

原文鏈接:https://www.toutiao.com/i6713520017595433485

Redis 簡介

Redis 是完全開源免費的,遵守 BSD 協議,是一個高性能的 key - value 數據庫。

Redis 與 其他 key - value 緩存產品有以下三個特點:

Redis 支持數據持久化,可以將內存中的數據保存在磁盤中,重啓的時候可以再次加載進行使用。
Redis 不僅僅支持簡單的 key - value 類型的數據,同時還提供 list,set,zset,hash 等數據結構的存儲
Redis 支持數據的備份,即 master - slave 模式的數據備份

Redis 優勢

  • 性能極高 – Redis 讀的速度是 110000 次 /s, 寫的速度是 81000 次 /s 。
  • 豐富的數據類型 - Redis 支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操作。
  • 原子性 - Redis 的所有操作都是原子性的,意思就是要麼成功執行要麼失敗完全不執行。單個操作是原子性的。多個操作也支持事務,即原子性,通過 MULTI 和 EXEC 指令包起來。
  • 其他特性 - Redis 還支持 publish/subscribe 通知,key 過期等特性。

Redis 數據類型

Redis 支持 5 中數據類型:string(字符串),hash(哈希),list(列表),set(集合),zset(sorted set:有序集合),具體用法參見文檔:redis文檔

類型特性場景

  1. string(字符串)二進制安全可以包含任何數據,比如 jpg 圖片或者序列化的對象,一個鍵最大能存儲 521M
  2. Hash(哈希)鍵值對集合,即編程語言中的 Map 類型適合存儲對象,並且可以像數據庫中 update 一樣只修改某一項屬性值存儲、讀取、修改用戶屬性。
  3. List(列表)雙向鏈表增刪快,提供了操作某一段元素的 API 如: 最新消息排行等功能(朋友圈的時間線、消息隊列等。
  4. Set(集合)哈希表實現,元素不能重複添加刪除查找的複雜度都是 O(1);爲集合提供了求交集、並集、差集等操作共同好友;利用唯一性,統計訪問網站的所有獨立 ip;好友推薦時,根據 tag 求交集,大於某個閾值就可以推薦
  5. Zset(有序集合)將 Set 中的元素增加一個權重參數 score,元素按 score 有序排列數據插入集合時,已經進行天然排序排行榜;帶權重的消息隊列。

發佈訂閱

一般不用 Redis 做消息發佈訂閱。

Redis 發佈訂閱 (pub/sub) 是一種消息通信模式:發送者 (pub) 發送消息,訂閱者 (sub) 接收消息。
Redis 客戶端可以訂閱任意數量的頻道。

事務

redis 事務一次可以執行多條命令,服務器在執行命令期間,不會去執行其他客戶端的命令請求。

事務中的多條命令被一次性發送給服務器,而不是一條一條地發送,這種方式被稱爲流水線,它可以減少客戶端與服務器之間的網絡通信次數從而提升性能。

Redis 最簡單的事務實現方式是使用 MULTI 和 EXEC 命令將事務操作包圍起來。

批量操作在發送 EXEC 命令前被放入隊列緩存。
收到 EXEC 命令後進入事務執行,事務中任意命令執行失敗,其餘命令依然被執行。也就是說 Redis 事務不保證原子性。
在事務執行過程中,其他客戶端提交的命令請求不會插入到事務執行命令序列中。
一個事務從開始到執行會經歷以下三個階段:

  1. 開始事務。
  2. 命令入隊。
  3. 執行事務。

單個 Redis 命令的執行是原子性的,但 Redis 沒有在事務上增加任何維持原子性的機制,所以 Redis 事務的執行並不是原子性的。
事務可以理解爲一個打包的批量執行腳本,但批量指令並非原子化的操作,中間某條指令的失敗不會導致前面已做指令的回滾,也不會造成後續的指令不做。

持久化

Redis 是內存型數據庫,爲了保證數據在斷電後不會丟失,需要將內存中的數據持久化到硬盤上。

RDB 持久化

將某個時間點的所有數據都存放到硬盤上。

可以將快照複製到其他服務器從而創建具有相同數據的服務器副本。

如果系統發生故障,將會丟失最後一次創建快照之後的數據。

如果數據量大,保存快照的時間會很長。

AOF 持久化

將寫命令添加到 AOF 文件(append only file)末尾。

使用 AOF 持久化需要設置同步選項,從而確保寫命令同步到磁盤文件上的時機。這是因爲對文件進行寫入並不會馬上將內容同步到磁盤上,而是先存儲到緩衝區,然後由操作系統決定什麼時候同步到磁盤。

選項同步頻率

  • always每個寫命令都同步
  • eyerysec每秒同步一次
  • no讓操作系統來決定何時同步

always 選項會嚴重減低服務器的性能
everysec 選項比較合適,可以保證系統崩潰時只會丟失一秒左右的數據,並且 Redis 每秒執行一次同步對服務器幾乎沒有任何影響。
no 選項並不能給服務器性能帶來多大的提升,而且會增加系統崩潰時數據丟失的數量。

隨着服務器寫請求的增多,AOF 文件會越來越大。Redis 提供了一種將 AOF 重寫的特性,能夠去除 AOF 文件中的冗餘寫命令。

複製

通過使用 slave of host port 命令來讓一個服務器成爲另一個服務器的從服務器。

一個從服務器只能有一個主服務器,並且不支持主主複製。

連接過程

主服務器創建快照文件,即 RDB 文件,發送給從服務器,並在發送期間使用緩衝區記錄執行的寫命令。快照文件發送完畢之後,開始向從服務器發送存儲在緩衝區的寫命令。
從服務器丟棄所有舊數據,載入主服務器發來的快照文件,之後從服務器開始接受主服務器發來的寫命令。
主服務器每執行一次寫命令,就向從服務器發送相同的寫命令。

主從鏈

隨着負載不斷上升,主服務器無法很快的更新所有從服務器,或者重新連接和重新同步從服務器將導致系統超載。爲了解決這個問題,可以創建一箇中間層來分擔主服務器的複製工作。中間層的服務器是最上層服務器的從服務器,又是最下層服務器的主服務器。

在這裏插入圖片描述

哨兵

Sentinel(哨兵)可以監聽集羣中的服務器,並在主服務器進入下線狀態時,自動從從服務器中選舉處新的主服務器。

分片

分片是將數據劃分爲多個部分的方法,可以將數據存儲到多臺機器裏面,這種方法在解決某些問題時可以獲得線性級別的性能提升。

假設有 4 個 Redis 實例 R0, R1, R2, R3, 還有很多表示用戶的鍵 user:1, user:2, … , 有不同的方式來選擇一個指定的鍵存儲在哪個實例中。

最簡單的是範圍分片,例如用戶 id 從 0 ~ 1000 的存儲到實例 R0 中,用戶 id 從 1001 ~ 2000 的存儲到實例 R1中,等等。但是這樣需要維護一張映射範圍表,維護操作代價高。
還有一種是哈希分片。使用 CRC32 哈希函數將鍵轉換爲一個數字,再對實例數量求模就能知道存儲的實例。
根據執行分片的位置,可以分爲三種分片方式:

  • 客戶端分片:客戶端使用一致性哈希等算法決定應當分佈到哪個節點。
  • 代理分片:將客戶端的請求發送到代理上,由代理轉發到正確的節點上。
  • 服務器分片:Redis Cluster。

Codis是一個豌豆莢團隊開源的使用Go語言編寫的Redis Proxy使用方法和普通的redis沒有任何區別,設置好下屬的多個redis實例後就可以了,使用時在本需要連接redis的地方改爲連接codis,它會以一個代理的身份接收請求 並使用一致性hash算法,將請求轉接到具體redis,將結果再返回codis,和之前比較流行的twitter開源的Twemproxy功能類似,但是相比官方的redis cluster和twitter的Twemproxy還是有一些獨到的優勢,Codis官方功能對比圖如下:

Codis Twemproxy Redis Cluster
resharding without restarting cluster Yes no Yes
pipeline Yes Yes No
hash tags for multi-key operations Yes Yes Yes
multi-key operations while resharding Yes - No(details)
Redis clients supporting Any clients Any clients Clients have to support cluster protocol

從表中我們可以看出Codis一個比較大的優點是可以不停機動態新增或刪除數據節點,舊節點的數據也可以自動恢復到新節點。並且提供圖形化的dashboard,方便集羣管理。
codis架構圖:
在這裏插入圖片描述

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