吴忠躺衫网络科技有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

一文理解 Redis 的核心原理與技術

數(shù)據(jù)分析與開發(fā) ? 來源:何永康 ? 作者:何永康 ? 2021-05-28 10:49 ? 次閱讀

一、Redis 基礎數(shù)據(jù)結構

1. String

Redis 里的字符串是動態(tài)字符串,會根據(jù)實際情況動態(tài)調整。類似于 Go 里面的切片-slice,如果長度不夠則自動擴容。至于如何擴容,方法大致如下:當 length 小于 1M 的時候,擴容規(guī)則將目前的字符串翻倍;如果 length 大于 1M 的話,則每次只會擴容 1M,直到達到 512M。

e9ea5f1e-bf1a-11eb-9e57-12bb97331649.png

2. List

Redis 里的 List 是一個鏈表,由于鏈表本身插入和刪除比較塊,但是查詢的效率比較低,所以常常被用做異步隊列。Redis 里的 List 設計非常牛,當數(shù)據(jù)量比較小的時候,數(shù)據(jù)結構是壓縮鏈表,而當數(shù)據(jù)量比較多的時候就成為了快速鏈表。 可運用的場景:在業(yè)務中異步隊列使用 rpush/lpush 操作隊列,使用 lpop 和 rpop 出隊列,具體結構如下圖所示:

e9f5ba08-bf1a-11eb-9e57-12bb97331649.png

3. Set Redis 中的 set 是一個無序 Map,由于 Go 中沒有 set 結構,所以這里只能類比 Java 中的 HashSet 概念。Redis 的 set 底層也是一個 Map 結構,不同于 Java 的是:alue 是一個 NULL。由于 set 的特性,它可以用于去重邏輯,這一點在 Java 中也經(jīng)常使用。 可運用場景:活動抽獎去重。

4. Hash Redis 中的字典類型大家不陌生,也許其他語言都有這種結構(python,Java,Go), hash 的擴容 rehash 過程和 Go 里面的設計頗有類似,也就是維護了兩個 hash 結構,如果需要擴容的時候,就把新的數(shù)據(jù)寫入新字典中,然后后端起一個線程來逐步遷移,總體上來說就是采用了空間換時間的思想。 可運用場景:記錄業(yè)務中的不同用戶/不同商品/不同場景的信息:如某個用戶的名稱,或者用戶的歷史行為。

ea135022-bf1a-11eb-9e57-12bb97331649.png

5. Zset

Redis 中的 zset 是一個比較特殊的數(shù)據(jù)結構(跳躍列表),也就是我們了解到的跳表,底層由于 set 的特性保證了 value 唯一,同時也給了 value 一個得分,所謂的有序其實就是根據(jù)這個得分來排序。至于跳躍表如何插入,其實內部采用了一個隨機策略:L0:100%-L2:50%-L3:25%-。。。.Ln:(n-1)value/2%。 可運用場景:榜單,總榜,熱榜。

ea236d22-bf1a-11eb-9e57-12bb97331649.png

二、Redis 進階使用

1. 布隆過濾器

Redis 在 4.0 以后支持布隆過濾(準確的來說是支持了布隆過濾器的插件),給 Redis 提供了強大的去重功能。在業(yè)務中,我們可能需要查詢數(shù)據(jù)庫判斷歷史數(shù)據(jù)是否存在,如果數(shù)據(jù)庫的并發(fā)能力有限,這個時候我們可以采用 Redis 的 set 做去重。

如果緩存的數(shù)據(jù)過大,這個時候就需要遍歷所有緩存數(shù)據(jù),另外如果我們的歷史數(shù)據(jù)緩存寫不下了,終究要去查詢數(shù)據(jù)庫,這個時候就可以使用布隆過濾器。 當然布隆過濾器精確度不是 100% 準確(如果對數(shù)據(jù)準確度要求很高的話,這里不建議使用),因為對于存在的數(shù)據(jù)也許這個值不一定存在,當然如果不存在,那肯定 100% 不存在了。

(1)命令使用

bf.add #添加元素bf.exists #判斷元素是否存在bf.madd #批量添加bf.mexists #批量判斷是否存在

(2)原理

ea358660-bf1a-11eb-9e57-12bb97331649.png

布隆過濾的組成可以當作一個位數(shù)組和幾個計算結果比較均勻的 hash 函數(shù),每次添加 key 的時候,會把 key 通過多次 hash 來計算所得到的位置,如果當前位置不是 0 則表示存在。可以看到,這樣的計算存在一定誤差,這也正是它的不準確性問題的由來。

2. 分布式鎖

大家對分布式鎖也許也不會陌生,現(xiàn)在市面上主流的實現(xiàn)分布鎖的技術有 ZK 和 Redis;下文為大家簡單介紹一下 Redis 如何實現(xiàn)分布式鎖。

命令

setnx lock:mutex ture #加鎖del lock:mutex #刪除鎖 實現(xiàn)分布式鎖的核心就是:請求的時候 Set 這個 key,如果其他請求設置失敗的時候,即拿不到鎖。但是存在一個問題:如果業(yè)務 panic 或者忘記調用 del 的話,就會產生死鎖,這個時候大家很容易能想到:我們可以 expire 一個過期時間,這樣就可以保證請求不會一直獨占鎖且無法釋放鎖的邏輯了。

但是假設業(yè)務存在這樣一種情況:A 請求在獲取鎖后處理邏輯,由于邏輯過長,這個時候鎖到期釋放了,A 這個時候剛剛處理完成,而 B 又去改了這個數(shù)據(jù),這就存在一個鎖失效的問題。解決這種問題參考 CAS 的方式,對鎖設置一個隨機數(shù),可以理解為版本號,如果釋放的時候版本號不一致,則表示數(shù)字已經(jīng)在釋放那一刻改掉了。

三、深入原理

1. IO模型

Redis 是單線程模型(這里的單線程指的是 IO 和鍵值對的讀寫是一個線程完成的),當然如果嚴謹?shù)膩碚f還是可以理解為是多線程,不過這樣的多線程不過是在數(shù)據(jù)備份的時候會 fork 一個子進程對數(shù)據(jù)進行從磁盤讀取數(shù)據(jù)并組裝 RDB,然后同步給 slaver 節(jié)點的操作,當然包括備份和持久化也都是通過另外起線程完成的,所以我們可以把 Redis 認作為一個單線程模型。

那么問題來了,為什么單線程的模型能這么快?原因很簡單,因為 Redis 本身就是在內存中運算,而對于上游的客戶端請求,采用了多路復用的原理。Redis 會給每一個客戶端套接字都關聯(lián)一個指令隊列,客戶端的指令隊列通過隊列排隊來進行順序處理,同時 Reids 給每一個客戶端的套件字關聯(lián)一個響應隊列,Redis 服務器通過響應隊列來將指令的接口返回給客戶端。

ea6729ea-bf1a-11eb-9e57-12bb97331649.png

Redis IO 處理模型

2. 通信協(xié)議

Redis 采用了 Gossip 協(xié)議作為通信協(xié)議。Gossip 是一種傳播消息的方式,可以類比為瘟疫或者流感的傳播方式,使用 Gossip 協(xié)議的有:Redis Cluster、Consul、Apache Cassandra 等。Gossip 協(xié)議類似病毒擴散的方式,將信息傳播到其他的節(jié)點,這種協(xié)議效率很高,只需要廣播到附近節(jié)點,然后被廣播的節(jié)點繼續(xù)做同樣的操作即可。當然這種協(xié)議也有一個弊端就是:會存在浪費,哪怕一個節(jié)點之前被通知到了,下次被廣播后仍然會重復轉發(fā)。

3. 持久化

(1)RDB

RDB 是對當前 Redis 的存儲數(shù)據(jù)進行一次快照(具體原理和如何做,限于篇幅這里不做過多復述了)。

(2)AOF

日志只記錄 Redis 對內存修改的指令記錄,Redis 提供了一個 bgrewriteaif 的指令對 AOF 進行壓縮。原理就是:開辟一個子進程對內存進行遍歷后,轉換成一系列對 Redis 的操作指令,序列化到一個新的 AOF 日志文件中。系列化完成后再將發(fā)送的增量 AOF 日志追加到這個新的 AOF 日志中,追加完成后用新的 AOF 日志代替舊的。

(3)混合持久化

由于單純 RDB 的話,可能存在數(shù)據(jù)的丟失,而頻繁的 AOF 又會影響了性能,在 Redis 4.0 之后,支持了混合持久化,也就是每次啟動時候通過 RDB+增量的 AOF 文件來進行回復,由于增量的 AOF 僅記錄了開始持久化到持久化結束期間發(fā)生的增量,這樣日志不會太大,性能相對較高。

4. 主從同步

Redis 的同步方式有:主從同步、從從同步(由于全部都由 master 同步的話,會損耗性能,所以部分的 slave 會通過 slave 之間進行同步)。

同步過程:

建立連接,然后從庫告訴主庫:“我要同步啦,你給我準備好”,然后主庫跟從庫說:“收到”。

從庫拿到數(shù)據(jù)后,要把數(shù)據(jù)保存到庫里。這個時候就會在本地完成數(shù)據(jù)的加載,會用到 RDB 。

主庫把新來的數(shù)據(jù) AOF 同步給從庫。

5. Sentinel

Redis 的主從切換是通過哨兵來解決的。這里哨兵主要解決的問題就是:當 master 掛了的情況下,如果在短時間內重新選舉出一個新的 master 。

Sentinel 集群是一個由 3-5 個(可以更多)節(jié)點組成的,用來監(jiān)聽整個 Redis 的集群,如果發(fā)現(xiàn) master 不可用的時候,會關閉和斷開全部的與 master 相連的舊鏈接。這個時候 Sentinel 會完成選舉和故障轉移,新的請求則會轉到新到 master 中。

6. Redis集群工作原理

Redis 集群通過槽指派機制來決定寫命令應該被分配到那個節(jié)點。整個集群對應的槽是由 16384 大小的二進制數(shù)組組成,集群中每個主節(jié)點分配一部分槽,每條寫命令落到二進制數(shù)組中的某個位置,該位置被分配給了哪個節(jié)點,則對應的命令就由該節(jié)點去執(zhí)行。槽指派對應的二進制數(shù)組如下圖所示:

eae9ca30-bf1a-11eb-9e57-12bb97331649.png

從上圖可以看到:節(jié)點 1 只負責 執(zhí)行 0 - 4999 的槽位,而節(jié)點 2 負責執(zhí)行 5000 - 9999,節(jié)點 3 執(zhí)行 9999- 16383 。當進行寫的時候:

set key value 命令通過CRC16(key) & 16383 = 6789(假設結果),由于節(jié)點 2 負責 5000~9999 的槽位,則該命令的結果 6789 最終由節(jié)點 2 執(zhí)行。當然如果在節(jié)點 2 執(zhí)行一條命令時,假設通過 CRC 計算后得到的值為 567,則其應該由節(jié)點 1 執(zhí)行,此時命令會進行轉向操作,將要執(zhí)行的命令流轉到節(jié)點 1 上去執(zhí)行。

eb9a420c-bf1a-11eb-9e57-12bb97331649.png

集群節(jié)點同步:集群中每個主節(jié)點都會定時發(fā)送信息到其他主節(jié)點進行同步,如果其他主節(jié)點在規(guī)定時間內響應了發(fā)送消息的主節(jié)點,則發(fā)送消息的主節(jié)點認為響應了消息的主節(jié)點正常,反之則認為響應消息的主節(jié)點疑似下線,則發(fā)送消息的主節(jié)點在其節(jié)點上將其標記“疑似下線”。

當集群中超過一半以上的節(jié)點認為某個主節(jié)點被標記為“疑似下線”,則其中某個主節(jié)點將疑似下線節(jié)點標記為下線狀態(tài),并向集群廣播一條下線消息,當下線節(jié)點對應的從節(jié)點接收到該消息時,則從從節(jié)點中選舉出一個節(jié)點作為主節(jié)點繼續(xù)對外提供服務。

四、Redis為什么變慢了

業(yè)務場景中,不知道大家是否碰到過 Redis 變慢的情況:

執(zhí)行 SET、DEL 命令耗時也很久;

偶現(xiàn)卡頓,之后又恢復正常了;

在某個時間點,突然開始變慢了。

原因分析

查看慢查詢,由于筆者本身機器沒有慢查詢,所以這里看到是空(實在尷尬,這里沒有可用的例子~~)

ebcccf92-bf1a-11eb-9e57-12bb97331649.png

由于 Redis 在 IO 操作和對鍵值對的操作是單線程的,所以直接在客戶端 Redis-cli 上執(zhí)行的 Redis 命令有可能會導致操作延遲變大;

使用復雜的命令會讓 Redis的處理變慢,以及CPU過高,例如 SORT、SUNION、ZUNIONSTORE 聚合類命令(時間負責度O(N) );

查詢的數(shù)據(jù)量過大,使得更多時間花費在數(shù)據(jù)協(xié)議的組裝和網(wǎng)絡傳輸過程中;

大 key 查詢,比如對于一個很大的 hash、zset 等,這樣的對象對 Redis 的集群數(shù)據(jù)遷移帶來了很大的問題,因為在集群環(huán)境下,如果某個 key 太大,會導致數(shù)據(jù)遷移卡頓;

另外在內存分配上,如果一個 key 太大,那么當它需要擴容時,會一次性申請更大的一塊內存,這也會導致卡頓。如果這個大 key 被刪除,內存會一次性回收,卡頓現(xiàn)象會再一次產生。

集中過期,變慢的時間統(tǒng)一,所以業(yè)務中的 Key 過期時間盡量在統(tǒng)一的一個時間點加上一個隨機數(shù)時間;

內存使用達到上限,當內存達到內存上限的時候,就不許淘汰一些數(shù)據(jù),這個時候也可能導致 Redis 查詢效率低;

碎片整理,Redis 在 4.0 版本后會自動整理碎片(由于內存回收過程中存在大量的碎片空間,不整理會導致 Redis 的空間少量浪費),而在整理碎片的過程中會消耗 CPU 的資源,從而影響了請求得到性能;

網(wǎng)絡帶寬,Redis 集群和業(yè)務混部,或者并發(fā)量過大以及每次返回的數(shù)據(jù)也很大,網(wǎng)卡帶寬跑滿的情況容易導致網(wǎng)絡阻塞;

AOF 的頻率過高,由于 AOF 需要將全部的寫命令同步,如果同步的間隔比較短,也會影響到 Redis 的性能;

Redis 提供了 flushdb 和 flushall 指令,用來清空數(shù)據(jù)庫,這也是導致 Redis 緩慢的操作。

五、Redis安全

默認會監(jiān)聽 6379 端口,最好在 Redis 的配置文件中指定監(jiān)聽的 IP 地址,更進一步還可以增加 Redis 的 ACL 訪問控制,對客戶指定群組,并限限制用戶對數(shù)據(jù)的讀寫權限。 訪問 Redis 盡量走公司代理,由于 Redis 本身不支持 SSL 的鏈接,所以走公司代理可以保證安全。客戶端登陸 Redis 必須設置 Auth 秘密登陸。

編輯:jq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • cpu
    cpu
    +關注

    關注

    68

    文章

    10904

    瀏覽量

    213026
  • ACL
    ACL
    +關注

    關注

    0

    文章

    61

    瀏覽量

    12023
  • 網(wǎng)絡帶寬

    關注

    0

    文章

    42

    瀏覽量

    8360
  • sort
    +關注

    關注

    0

    文章

    5

    瀏覽量

    2632

原文標題:一文理解 Redis 的核心原理與技術

文章出處:【微信號:DBDevs,微信公眾號:數(shù)據(jù)分析與開發(fā)】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    華為云 Flexus X 加速 Redis 案例實踐與詳解

    Redis 加速鏡像,更是為開發(fā)者提供了極大的便利。本文將詳細介紹如何利用華為云 Flexus X 實例自帶的 Redis 鏡像,快速部署并配置 Redis,以及通過實際案例展示其便捷性和高效性。
    的頭像 發(fā)表于 01-23 17:52 ?78次閱讀
    華為云 Flexus X 加速 <b class='flag-5'>Redis</b> 案例實踐與詳解

    Redis Cluster之故障轉移

    1. Redis Cluster 簡介 Redis Cluster 是 Redis 官方提供的 Redis 集群功能。 為什么要實現(xiàn) Redis
    的頭像 發(fā)表于 01-20 09:21 ?211次閱讀
    <b class='flag-5'>Redis</b> Cluster之故障轉移

    華為云Flexus X實例,Redis性能加速評測及對比

    隨著云計算技術的飛速發(fā)展,Redis 作為種高性能的內存數(shù)據(jù)庫,在各種應用場景中發(fā)揮著越來越重要的作用。為了滿足不同用戶對 Redis 性能的高要求,華為云推出了 Flexus X
    的頭像 發(fā)表于 12-29 15:47 ?215次閱讀
    華為云Flexus X實例,<b class='flag-5'>Redis</b>性能加速評測及對比

    華為云 Flexus X 輕松實現(xiàn) Redis 主多從高效部署

    前言 ????????華為云 Flexus?X 是款專為高性能計算設計的云服務器實例,其搭載的 X-Turbo 加速技術和智能應用調優(yōu)算法,能夠大幅提升 Redis 的處理能力和響應速度。此外
    的頭像 發(fā)表于 12-27 13:45 ?242次閱讀
    華為云 Flexus X 輕松實現(xiàn) <b class='flag-5'>Redis</b> <b class='flag-5'>一</b>主多從高效部署

    Redis緩存與Memcached的比較

    Redis和Memcached都是廣泛使用的內存數(shù)據(jù)存儲系統(tǒng),它們主要用于提高應用程序的性能,通過減少對數(shù)據(jù)庫的直接訪問來加速數(shù)據(jù)檢索。以下是對Redis和Memcached的比較,涵蓋了它們的
    的頭像 發(fā)表于 12-18 09:33 ?241次閱讀

    文理解多模態(tài)大語言模型——下

    /understanding-multimodal-llms ? 《文理解多模態(tài)大語言模型 - 上》介紹了什么是多模態(tài)大語言模型,以及構建多模態(tài) LLM 有兩種主要方式之:統(tǒng)嵌入
    的頭像 發(fā)表于 12-03 15:18 ?201次閱讀
    <b class='flag-5'>一</b><b class='flag-5'>文理解</b>多模態(tài)大語言模型——下

    文理解多模態(tài)大語言模型——上

    利于中文讀者理解的目標,做了刪減、重構和意譯,并替換了多張不適合中文讀者的示意圖。 原文地址:https://magazine.sebastianraschka.com/p
    的頭像 發(fā)表于 12-02 18:29 ?467次閱讀
    <b class='flag-5'>一</b><b class='flag-5'>文理解</b>多模態(tài)大語言模型——上

    文理解2.5D和3D封裝技術

    隨著半導體行業(yè)的快速發(fā)展,先進封裝技術成為了提升芯片性能和功能密度的關鍵。近年來,作為2.5D和3D封裝技術之間的種結合方案,3.5D封裝技術逐漸走向前臺。
    的頭像 發(fā)表于 11-11 11:21 ?1751次閱讀
    <b class='flag-5'>一</b><b class='flag-5'>文理解</b>2.5D和3D封裝<b class='flag-5'>技術</b>

    家人工智能企業(yè)成功IPO,核心技術涉及感知、理解、執(zhí)行

    流程。主要服務于城市管理及行政、汽車及交通、通信、金融以及教育、醫(yī)療健康、電商及零售等行業(yè)。 ? 核心技術涉及感知、理解、執(zhí)行 ????????????????????????????????? 聲通科技核心技術包括交互式人工智
    的頭像 發(fā)表于 07-17 00:16 ?3159次閱讀

    Redis 開源協(xié)議調整,我們怎么辦?

    許可,時間點恰逢剛剛完成最新輪融資,宣布的時機耐人尋味。 Redis 協(xié)議調整,對云計算廠商的影響 Redis 協(xié)議調整聽起來可能沒什么,但在開源項目領域是個大問題。這并不是
    的頭像 發(fā)表于 05-09 22:59 ?474次閱讀
    <b class='flag-5'>Redis</b> 開源協(xié)議調整,我們怎么辦?

    Redis開源版與Redis企業(yè)版,怎么選用?

    Redis開源版,二者有何不同?該如何選擇?Redis企業(yè)版Redis企業(yè)版基于開源Redis構建,企業(yè)版將開發(fā)人員、架構師和DevO
    的頭像 發(fā)表于 04-04 08:04 ?1191次閱讀
    <b class='flag-5'>Redis</b>開源版與<b class='flag-5'>Redis</b>企業(yè)版,怎么選用?

    數(shù)據(jù)安全沒保障?GaussDB(for Redis) 為你保駕護航

    未知的 key,實際上可能面臨數(shù)據(jù)庫信息丟失和記錄篡改的風險。 作為個重視技術的團隊,我們始終將用戶信息安全和使用體驗放在第位。對于這次用戶使用開源 Redis 遇到的問題,我們盤
    的頭像 發(fā)表于 03-28 22:09 ?718次閱讀
    數(shù)據(jù)安全沒保障?GaussDB(for <b class='flag-5'>Redis</b>) 為你保駕護航

    GaussDB(for Redis) 特性揭秘:大 key 治理

    運行過程中悄悄產生的,讓人防不勝防。因此,款可隨時在線診斷,且能主動預警,防患于未然的 Redis 服務產品顯得尤為重要。 ? 作為由華為云精心打造的企業(yè)級 Redis,GaussDB
    的頭像 發(fā)表于 03-28 22:06 ?711次閱讀
    GaussDB(for <b class='flag-5'>Redis</b>) 特性揭秘:大 key 治理

    新版 Redis 不再“開源”,對使用者都有哪些影響?

    2024 年 3 月 20 日,Redis Labs 宣布從 Redis 7.4 開始,將原先比較寬松的 BSD 源碼使用協(xié)議修改為 RSAv2和 SSPLv1協(xié)議。該變化意味著 Redis
    的頭像 發(fā)表于 03-27 22:30 ?556次閱讀
    新版 <b class='flag-5'>Redis</b> 不再“開源”,對使用者都有哪些影響?

    Redis官方搜索引擎來了,性能炸裂!

    RediSearch 是Redis 模塊,為 Redis 提供查詢、二級索引和全文搜索功能。
    的頭像 發(fā)表于 02-21 10:01 ?2542次閱讀
    <b class='flag-5'>Redis</b>官方搜索引擎來了,性能炸裂!
    国际娱百家乐的玩法技巧和规则| 香格里拉县| 利澳百家乐官网娱乐城| 七胜百家乐娱乐平台| 绍兴县| 百家乐投注外围哪里好| 百家乐官网路单破解器| 信誉百家乐博彩网| 皇冠网vip小说| 百家乐桌蓝盾在线| 留坝县| 百家乐投注技巧公式| 澳盈| 罗盘24山珠宝火坑| 蓝盾百家乐| 百家乐h游戏怎么玩| 莎车县| 赌场百家乐玩法介绍| 百家乐官网有没有绝| 678百家乐博彩娱乐平台| 百家乐官网开户优惠多的平台是哪家| 赌博百家乐的玩法技巧和规则 | 大发888备用网址| 百家乐视频双扣下载| 百家乐官网视频麻将| 大中华百家乐的玩法技巧和规则| 百家乐官网送彩金网络| 大发888 大发888官网| 马牌百家乐官网的玩法技巧和规则 | 大发888娱乐城shouye| 百家乐官网双峰县| 淘金盈娱乐城| 最好的百家乐博彩公司| 百家乐官网在线赌场娱乐网规则| 永利国际娱乐| 百家乐博弈指数| 百家乐官网凯时赌场娱乐网规则| 百家博娱乐城| 新彩百家乐的玩法技巧和规则| 百家乐官网反缆公式| 中华娱乐城|