【Redis】Redis基础知识点
Redis基礎知識點
一、簡介
- 支持簡單數據類型
- 不支持數據持久化存儲
- 不支持主從
- 不支持分片
- 數據類型豐富
- 支持數據磁盤持久化存儲
- 支持主從
- 支持分片
- 完全基于內存,絕大部份請求是存粹的內存操作,執行效率高。
redis采取的是單進程單線程的數據庫,由C語言編寫,都是寫在內存里面,不回受硬盤的IO限制 - 數據結構簡單,對數據操作也簡單。
redis不使用表,不回強制要求對存儲的數據進行關聯,因此會比關系型數據庫高出一個量級,存儲結構就是一個鍵值對,時間復雜度都是O(1)的 - 采用單線程,單線程也能處理高并發請求,想多核也可啟動多實例
redis沒有采取線程池來處理業務,redis的單線程結構指的是主線程是單線程的,這里處理IO請求和IO相關請求的處理,正因為是單線程的設計,對客戶端的所有請求,都由一個主線程串行的處理,因此多個客戶端同時對一個鍵進行寫操作的時候,就不會有并發的問題 - 使用多路I/O復用模型,非阻塞IO
若是阻塞IO,會存讀取阻塞 - Redis采用的I/O多路復用函數:epoll(linux)/kqueue(macos)/evport/select
- 因地制宜,因為可能要運行的操作系統不同
- 優先選擇時間復雜度為O(1)的I/O多路復用函數作為底層實現
- 都是以時間復雜度為O(n)的select作為保底
- 基于react設計模式監聽I/O事件,這里不是很理解
二、數據類型
提供用戶使用的數據類型
- String: 最基本的數據類型,二進制安全,最大能存儲512M,可以包含JPG圖片和序列化的對象
- Hash: String元素組成的字典,適合用于儲存對象
- List: 列表,按照String元素插入順序排序
- Set: String元素組成的無序集合,通過哈希表實現,不允許重復
- Sorted Set: 通過分數來為集合中的成員進行從小到打的排序
- 用于技術的HyperLogLog,用于支持存儲地理位置信息的Geo
底層數據類型基礎
三、從海量Key里查詢某一固定前綴的key
3.1 首先注意細節
3.2 若是直接回答使用keys指令查詢的話,會遭埋伏
- Keys指令一次性返回所有匹配的key
- 鍵的數量過大會使服務卡頓
3.3 解決方法
SCAN cursor [MATCH pattern] [COUNT count]
- 是一個基于游標的迭代器,需要給予上一次游標延續之前的迭代過程
- 以0作為游標開始一次新的迭代,知道命令返回游標0完成一次遍歷
- 不保證每次執行都返回某個給定數量的元素,支持模糊查詢
- 一次返回的數量不可控,只能大概率的符合count參數
- 命令使用,scan 0 match k1* count 10,這樣就可以獲取到返回的值,每次會返回一個新的游標,下次查詢的時候可以將scan的游標添加為返回的游標
- 注意:這里可能會出現返回的key值里面出現重復的情況,需要在上層的業務代碼中添加一下去重的代碼。
- 可以在業務代碼中添加一個for循環,雖然這樣每次循環的總體時間要比直接keys的時間要長,但是不回造成服務卡頓
Java中有Jedis包來提供開發
四、實現分布式鎖
4.1 需要解決的問題
4.2 實現方式
但是這段程序會有風險,在剛剛setnx的時候就掛掉了,就會一致鎖住
4.3 大量的key同時過期的注意事項
五、使用Redis做異步隊列
5.1 List生產消費模式
- 缺點:只能供一個消費者消費
5.2 pub/sub 主題訂閱者模式
[外鏈圖片轉存失敗(img-rFlnrmMW-1563871653750)(https://i.loli.net/2019/07/07/5d21ff7d694c018910.png)]
六、Redis持久化
6.1 RDB(快照)持久化
6.1.1 配置
保存某個時間點的全量數據快照
在redis的根目錄下,查找redis.conf,一般情況下redis啟動的時候,redis會加載redis.conf的信息。
首先在redis.conf中找到save,有關于save的配置信息
stop-writes-on-bgsave-error配置選項,是為了保護數據持久化一致性的問題
rdbcompression壓縮配置,將rdb文件是否壓縮,一般設置為no
禁用RDB配置,直接在save的后面添加一個save ""即可
6.1.2 持久化
打開redis目錄下的src文件夾,里面會有rdb文件,dump.rdb文件是一個二進制文件
RDB文件可以通過兩個文件來生成
- 在調用bgsave命令的時候,會直接返回一個OK的返回碼
- lastsave,可以查看上一個save成功的時間戳,和刪除rdb文件不刪除沒有關系,只要執行了save相關命令,就可以使用lastsave查找
可以通過定時器之類的方法,定期的進行定時save操作,然后在通過腳本將dump.rdb文件轉存為dump+時間戳.rdb的形式保存,這樣就會看到不同時間點的快照了
自動化觸發RDB持久化
bgsave原理
[外鏈圖片轉存失敗(img-qZ10YXIf-1563871653752)(https://i.loli.net/2019/07/07/5d220fbabb3bf66017.png)]
Copy-on-Write
- 傳統方式下,fork()是直接講父進程的東西全部復制給子進程,這樣的效率低,復制的資源有的還可能用不上。
- 這種方式是,創建子進程時,內核只為子進程創建虛擬空間,父子兩進程使用的是相同的物理空間。只有父子進程發生更改時,才會為子進程分配獨立的物理空間
- 如果有多個調用者同時要求相同資源(如內存或磁盤上的數據存儲),它們會共同獲取相同的指針窒息那個相同過的資源,知道某個調用者試圖修改資源的內容時,系統才會真正復制一份專用的副本給該調用者,而其他的調用者見到的最初的資源仍保持不變。
redis的rdb流程
6.1.3 缺點
6.2 AOF(Append-Only-File)持久化
保存寫狀態,所有被寫入AOF的指令,都是以redis的協議格式來保存的
記錄下除了查詢以外的所有變更數據庫狀態的指令
以append的形式追加保存到AOF文件中(增量)
同樣是修改redis.conf里面的配置文件
隨著寫文件的增加,AOF文件大小不斷的增大,這就涉及到了重寫機制
手動觸發,執行bgrewriteaof命令直接觸發AOF重寫
自動觸發,在redis.conf配置文件配置
6.3 數據的恢復
[外鏈圖片轉存失敗(img-9hkmSAau-1563871653753)(https://macdown-picture.oss-cn-beijing.aliyuncs.com/WeChat1561204f33df75d672744f0c8fb0d94c.png?Expires=1562561423&OSSAccessKeyId=TMP.hXfVqAhXaq2oBbhe3N975vSH63KLKhBgHUyJRwJYLyhxvHGngQDv1WWBjXRq1R6VYmqZMFw57sbNntD1cRWhGqExdeVdiL19VJHfY11jgEzzSiyKQcXNi1DtokBTsS.tmp&Signature=ukFExDLpW8BsMLsb4atTM49cahI%3D)]
6.4 RDB和AOF優缺點
[外鏈圖片轉存失敗(img-6ZYWzFfI-1563871653754)(https://macdown-picture.oss-cn-beijing.aliyuncs.com/RDB-AOF.png?Expires=1562569857&OSSAccessKeyId=TMP.hXfVqAhXaq2oBbhe3N975vSH63KLKhBgHUyJRwJYLyhxvHGngQDv1WWBjXRq1R6VYmqZMFw57sbNntD1cRWhGqExdeVdiL19VJHfY11jgEzzSiyKQcXNi1DtokBTsS.tmp&Signature=Ly5UCR65r5%2FkLm8VvAsW28uzzto%3D)]
- BGSAVE做鏡像全量持久化,AOF做增量持久化
七、Pipeline及同步
7.1 使用Pipeline
7.2 Redis同步機制
主從同步原理理解
[外鏈圖片轉存失敗(img-NyfAcKkY-1563871653755)(https://macdown-picture.oss-cn-beijing.aliyuncs.com/tongbu.png?Expires=1562570415&OSSAccessKeyId=TMP.hXfVqAhXaq2oBbhe3N975vSH63KLKhBgHUyJRwJYLyhxvHGngQDv1WWBjXRq1R6VYmqZMFw57sbNntD1cRWhGqExdeVdiL19VJHfY11jgEzzSiyKQcXNi1DtokBTsS.tmp&Signature=M%2Fcc41Ufa2v9tyQsDsoEuQ6TzJw%3D)]
- 一般都是一個master用于寫的操作的,其他的若干個slave用來讀操作的,每個master和slave都代表了一個redis的server實例
- 定期的數據備份操作也是單獨選擇一個slave取完成的,這樣可以最大程度的發揮出redis的性能,為了使讓其支持數據的弱一致性,即最終一致性
- 不需要時時保證master和slave中間的數據是實時同步的,但是過了一段時間后,它們的數據是趨于同步的,這就是所謂的最終一致性,redis可以使用主從同步,也可以使用從從同步
- 第一次同步主節點做一次bgsave,并同時將后續的修改操作,記錄到內存的buffer中,待完成后,將rdb全量同步到從節點中。從節點接受同步后,將rdb的鏡像加載到內存中,再通知主節點,將其間修改的操作記錄和增量數據同步到從節點,進行寫入,這樣就完成了整個同步的過程
全同步過程(全量同步流程)
- Slave發送sync命令到master
- Master啟動一個后臺進程,將redis中的數據快照保存到文件中
- Master將保存數據快照期間收到的寫命令緩存起來
- Master完成寫文件操作后,將該文件發送給Slave
- 使用新的AOF文件替換掉舊的AOF文件
- Master將這期間的收集的增量寫命令發送給Slave端
增量同步過程
- Master接收到用戶的操作指令,判斷是否需要傳播到slave,一般讀就不用了
- 將操作記錄追加到AOF文件
- 將操作傳播到其他的Slave:1. 對齊主從庫;2. 往相應緩存寫入指令
- 將緩存中的數據發送給Slave
主從模式的弊端就是不具備高可用性,當Master掛掉之后,redis將不能對外提供寫入操作
7.3 Redis Sentinel(Redis 哨兵)
解決主從同步Master宕機后主從切換的問題
- 監控:檢查主從服務器是否運行正常
- 提醒:通過API向管理員或者其他應用程序發送故障通知
- 自動故障遷移:主從切換
Redis Sentinel是一個分布式的系統,一個架構中可以運行多個sentinel進程,采用流言協議,接收主服務器是否下線的信息,并使用投票協議,來決定是否執行自動故障遷移,以及決定那個從服務器作為新的主服務器。和Zookeeper比較類似
流言協議Gossip,在雜亂無章中尋求一致
- 在有界網絡中,每個節點都隨機的與其他節點通信,經過一番雜亂無章的通信之后,最終所有的節點的狀態都會達成一致。
- 種子節點定期隨機向其他節點發送節點列表以及需要傳播的消息,任何新加入的節點就很快的被其他節點所知道
- 不保證信息一定會傳遞給所有的節點,但是最終會趨于一致
八、Redis集群
8.1 如何從海量數據中快速找到所需
- 通過數據分片,減輕單個節點服務器的壓力
- RedisCluster采用無中心結構,每個節點保存數據和整個集群的狀態,每個節點都和其他節點連接,節點直接采用gossip協議傳播信息和發現新的節點
- 主要目的是將不同的key分散到不同的節點,通常做法就是獲取key的哈希值,然后根據節點數求模
8.2 一致性哈希算法
對2^32取模,將哈希值空間組織成虛擬的圓環
將數據key使用相同的函數Hash計算出哈希值
[外鏈圖片轉存失敗(img-jPU3lT4P-1563871653757)(https://macdown-picture.oss-cn-beijing.aliyuncs.com/WeChatb9b7a250a1ff96480246a9461b4f58f3.png?Expires=1562577818&OSSAccessKeyId=TMP.hXfVqAhXaq2oBbhe3N975vSH63KLKhBgHUyJRwJYLyhxvHGngQDv1WWBjXRq1R6VYmqZMFw57sbNntD1cRWhGqExdeVdiL19VJHfY11jgEzzSiyKQcXNi1DtokBTsS.tmp&Signature=Ky8Mucwoebm%2F9Fft7GJCZhbBJLM%3D)]
將各個服務器通過哈希進行一個哈希的變換,具體可以選擇服務器的ip或者主機名作為關鍵字進行哈希,這樣每臺服務器就能確定在哈希環上的位置。
對數據的key使用和剛剛和服務器ip一個相同的函數,去計算出哈希值,并確定此數據在環上的位置
沿著環順時針行走,第一臺遇到的就是數據目標存儲的服務器
這樣遇到其中的服務器宕機的情況,則受影響的數據僅僅是服務器到其環型空間前一臺服務器之間的數據,也就是逆時針行走遇到的第一代服務器之間的數據,其他的數據是不回受到影響的
新增服務器NodeX,影響的是新增服務器逆時針到上一臺服務器之間的數據
Hash環的數據傾斜問題,在節點很少的時候,容易因為節點分布不均勻,導致數據傾斜,指的是被緩存的對象大部分緩存在同一臺服務器上
[外鏈圖片轉存失敗(img-sLhFYWVd-1563871653758)(https://macdown-picture.oss-cn-beijing.aliyuncs.com/%E6%95%B0%E6%8D%AE%E5%80%BE%E6%96%9C.png?Expires=1562578635&OSSAccessKeyId=TMP.hXfVqAhXaq2oBbhe3N975vSH63KLKhBgHUyJRwJYLyhxvHGngQDv1WWBjXRq1R6VYmqZMFw57sbNntD1cRWhGqExdeVdiL19VJHfY11jgEzzSiyKQcXNi1DtokBTsS.tmp&Signature=UmonKd44swpXrpHs9jQ8%2FiuP4is%3D)]
針對數據傾斜引入了虛擬節點解決數據傾斜的問題。
[外鏈圖片轉存失敗(img-xc0mYzEO-1563871653759)(https://macdown-picture.oss-cn-beijing.aliyuncs.com/%E8%99%9A%E6%8B%9F%E8%8A%82%E7%82%B9.png?Expires=1562578743&OSSAccessKeyId=TMP.hXfVqAhXaq2oBbhe3N975vSH63KLKhBgHUyJRwJYLyhxvHGngQDv1WWBjXRq1R6VYmqZMFw57sbNntD1cRWhGqExdeVdiL19VJHfY11jgEzzSiyKQcXNi1DtokBTsS.tmp&Signature=FNX63%2BFB47U11Icusv7f6w4aAdw%3D)]
多個虛擬節點,即對每個服務器節點計算多個hash,計算結果位置都放置一個子服務器節點,可以在服務器ip或主機名后面增加編號來識別,通常將虛擬節點設置為32或者更大,就可以避免數據傾斜的問題。
使用主從同步和哨兵模式將redis設置為高可用性。
總結
以上是生活随笔為你收集整理的【Redis】Redis基础知识点的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一加6T手机Android10 root
- 下一篇: iOS 官网文档 地图周边关键字搜索