redis 簡單使用總結

来源:http://www.cnblogs.com/wangiqngpei557/archive/2017/07/29/7256096.html
-Advertisement-
Play Games

最近一段時間與redis接觸比較頻繁。發現有些東西還是工作中經常會用到的,自己也花了點時間鞏固下。本篇文章主要是以總結性的方式梳理,因為redis的主題很大,任何一個技術點展開都是幾篇文章的量。也可以說這篇文章是個概覽。 ...


最近一段時間與redis接觸比較頻繁。發現有些東西還是工作中經常會用到的,自己也花了點時間鞏固下。本篇文章主要是以總結性的方式梳理,因為redis的主題很大,任何一個技術點展開都是幾篇文章的量。也可以說這篇文章是個概覽。

1.redis基本數據結構與短結構壓縮

瞭解redis的數據結構有助於瞭解每種數據結構的優劣勢,方便設計合理的cache結構。

1.1.redis提供5種數據結構

1.STRING:可以存儲字元串、浮點型、整型,如果是字元串可以執行字元串操作,如果是浮點型、整型也可以執行加減操作。redis會識別出它的具體類型。

2.LIST:鏈表,鏈表中的每個NODE包含一個字元串。可以對鏈表進行兩端推入、彈出操作。

3.SET:無序集合,不會存在相同的集合元素,集合的交集、並集、差集運算。

4.HASH:鍵值對的無需散列,增、刪、獲取鍵值。

5.ZSET:有序集合,根據一個浮點數分值來排序。

這幾種數據類型用起來場景還是比較明顯的,遇到複雜的cache場景我們需要結合這幾種數據結構一起來設計。

比如,購物車場景,我們首先需要兩個HASH來存儲,第一個HASH是用戶與購物車之間的關係,第二個HASH是購物車中的商品列表。

先通過userId獲取到shoppingCartId,然後再通過shoppingCartId就可以獲取到用戶購物車的ProductIds。然後再通過ProductIds就可以非同步讀取用戶購物車的商品信息。

通過userId獲取shoppingCartId,再通過shoppingCartId獲取ProductIds,這看似兩個步驟可以在一個redis command中執行完成。(藉助redis的pipeline管道。)

圖1:

1

設計cache的時候,可以稍微綜合的考慮下這幾種結構,如果沒有理想的結構再擴展下,將這幾種結構混搭下可以滿足複雜的cache結構。有一個平衡點就是過期時間的把握,集合沒有辦法設置具體item的過期時間,所以具體的數據對象還是需要設置expire,保證數據的新鮮度,比如,這裡的STRING:p100商品。

1.2.壓縮表與集合的整數集合編碼

redis為列表、集合、散列、有序集合提供了壓縮存儲的方式,在存儲數據不多的情況下用redis提供的短結構, 可以換來極大的存儲壓縮比。

redis的數據類型對應的短結構實現:list、zset、hash,這三個將使用ziplist,set使用集合整數編碼。

預設的存儲結構是以entry node 鏈表來存儲數據的。然而,entry node 是一個結構化的存儲。就拿list來說,entry node 前後包含了一個指針,形成雙向鏈表,中間是包含的數據。數據節點包含三個部分,當前字元串所用空間,當前字元串所剩空間,當前字元串的值。

這些鬆散性的結構帶來了一定的存儲開銷。redis提供了一個ziplist(壓縮表)的功能,一旦開啟壓縮表那麼原本用entry node的存儲結構將使用序列化的位元組序列來存儲。這有優勢也有劣勢,優勢就是存儲空間少了,劣勢就是不靈活了。存儲空間少了,不僅帶來空間利用率高,還有一個大的優勢就是執行master\slave repliaction 或者BGSAVE的時候都是有好處,存儲或者帶寬都會消耗小。

set背後使用hash來保證不會存在重覆的可以。當對set使用短結構存儲的時候,redis將使用整數集合編碼進行存儲。

還有一點,如果我們設置的最大壓縮限制超過之後redis將恢復entry node鏈表的是方式存儲。因為,如果你的壓縮表數據太多,讀取或者修改就會很影響性能。可能需要對整個壓縮列表進行解碼、編碼操作,等等。

2.redis 事務

redis 提供transaction 功能,你可以使用事務來處理一些數據一致性要求比較敏感的場景。redis的事務是沒有所謂的隔離級別這一說的,性能是才是它追求的目的。事務所包含的所有command,是一個接著一個被執行,這執行結束之前其他客戶端的所有請求都被block住。

使用redis事務比較簡單,它有一個表示事務開始的命令 multi,然後使用exec提交。

有兩點需要註意,在沒有執行exec的時候所有在multi之後的命令都不會被執行。預設情況下,redis收到multi命令之後會將用戶接下來的提交都暫時性的存放在一起queue里,直到接收到exec命令才會去執行queue里的所有命令。還有一點,有些redis客戶端為了提高性能,會將multi與exec的所有命令都暫時存在redis客戶端本地,然後一次性提交。這其實基於的是redis的pipeline 。

你也可以單獨使用pipeline,而不使用multi、exec事務。只是為了減少redis key的傳輸次數而已。如果不會產生數據一致性問題是可以這麼做的。

說到redis事務就不得不提redis事務的性能問題,所以現在結合redis來開發分散式事務來提供性能也是很常見的方案:https://github.com/Plen-wang/redis-lock 供參考。

3.redis兩種持久化原理(RDB、AOF)

redis支持兩種方式來持久化數據,第一種:snapshotting(鏡像或快照)也稱RDB、第二種:AOF(append-only file 文件追加)。

RDB:鏡像模式就是將某個時間段的所有記憶體數據直接寫入硬碟。

AOF:將執行的寫命令增量複製到硬碟裡面。

這兩種其實就是不同的側重,RDB是數據持久化,AOF是命令持久化,數據持久化比較直接,還原的時候直接恢複數據即可。命令持久化恢復的話需要執行一遍命令才行。

redis執行持久化操作取決於兩方面:預設是根據持久化配置來執行,還有就是用戶手動觸發。手動觸發有兩個命令:

SAVE:會block所有的用戶操作,知道持久化結束。

BGSAVE:後臺子進程執行,linux中使用fork命令開啟一個子進程副本,這個子進程副本與主進程共用一套記憶體空間,直到主進程或子進程對記憶體進行修改,被修改之後的記憶體區域將被子進程複製出來單獨使用。

RDB持久化的問題是會存在丟失數據的可能,AOF持久化最多丟失一秒內的命令。所以持久化結合這兩種來執行會在數據完整性和性能之間取的平衡。

4.redis 主從複製的基本原理

redis提供複製功能,這有很多好處。容災、擴展讀寫性能。

有兩個點需要註意:從伺服器一旦進行同步數據時會清空自己的所有數據。redis不支持主主複製。

複製過程大致如下:

1.從伺服器連接主伺服器,發送SYNC命令。

2.主伺服器執行BGSAVE,並使用緩存區記錄BGSAVE之後執行的所有寫命令。

3.BGSAVE執行完畢之後,向從伺服器發送快照文件。從節點丟棄所有本實例數據。載入主伺服器發送過來的快照數據。

4.快照發送完畢之後開始發送緩存區中的寫命令。從節點開始向常規的操作一樣執行增量複製。

5.開始進入常規的複製操作。

有個問題需要分享下,redis一旦占用的記憶體哪怕我們清楚了key,這部分記憶體還是無法還給操作系統的,這是redis的設計策略。雖然從redis info命令中查看的記憶體大小是沒用占用的,但是操作系統無法使用這部分記憶體。

還有個問題,所有redis伺服器如果要被覆制數據,也就是要執行BGSAVE,那麼至少需要保留30%-45%的空餘記憶體。因為BGSAVE執行的時候可能需要copy key出來,如果這個時候寫命令過多還需要給緩存區留有點空間。

5.redis 擴展讀性能

有了主從複製功能之後實際上擴展讀性能是比較容易的。利用主從鏈,將同步操作分派給同步節點,這樣主節點就可以專門只負責寫命令處理。

圖2:

2

複製節點專門處理複製功能,最下游的讀節點專門來接受讀請求。如果考慮主節點宕機問題,可以開啟複製節點的持久化功能,或者開啟讀節點的部分節點也行。主要是為了防止宕機可以快速恢復master。如果是異地雙活,可以把左右兩邊的所有讀節點開啟持久化,左邊一個機房,右邊一個機房,既可以雙活也可以恢復。(實際情況沒有這麼簡單,只是個思路)

讀節點是不能夠執行寫入命令的,這個才能保證將來的數據複製。

6.redis HA方案(sentinel)

redis 的高可用方案基於自己的一套sentinel 集群來管理。

圖3:

3

sentinel cluster 保持對redis集群的監控,如果sentinel-1發現master在某個時間段內沒有響應ping命令,就主觀斷定是可能宕機了。sentinel-2、sentinel-3如果都發現master是無響應的,那麼三個投票斷定master是客觀宕機了,做一次master、slave切換。同時會通過sentinel-sh腳本進行一些通知操作。

當然,redis-HA方案有好幾種,我們也可以用keepalived、VIP來實現,將master、backup、slave分離開來,master、backup自動VIP切換。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ArrayList是java中使用頻率非常高的一個集合類,它的底層採用數組來實現,本文主要來探究一下其源碼,幫助記憶和理解。 ...
  • import tornado.ioloop import tornado.web class MainHanlwe(tornado.web.RequestHandler): def get(self): login_user=self.get_secure_cookie('login_user',N... ...
  • username = "Anker" passward = "Abc123" number =2 for i in range(1,4,1): _username = input("username:") _passward = input("passward:") if _username==us ...
  • 一直都想寫點什麼,卻一直停滯……主要是因為有點懶,同時又想對所發的任何一篇博文都有很高的要求。 在學Python包括其擴展庫的過程中記錄過很多筆記,只是按自己的習慣所記,直接貼出來其他人不一定看得懂。在這裡發文畢竟都是要給別人看的,所以覺得發出來至少也得條理清晰,邏輯嚴密,才不至於誤導了閱讀我的博文 ...
  • 繼承PagingAndSortingRepository 我們可以看到,BlogRepository定義了這樣一個方法:Page<Blog> findByDeletedFalse(Pageable pageable);,我們主要關註它的參數以及返回值。 Pageable 是Spring Data庫中 ...
  • CrudRepository 的主要方法 1. 新建一個類 CurdEmployeeRespository 繼承CrudRepository 裡面實現了大量的增刪改查方法 2. 編寫service實現類 編寫測試類 測試結果 因為我測試前把數據全部都刪除了 ...
  • ★★★ 輸入文件:bjrabbit.in 輸出文件:bjrabbit.out 簡單對比時間限制:1 s 記憶體限制:162 MB Description Source: Beijing2006 [BJOI2006] 八中OJ上本題鏈接:http://www.lydsy.com/JudgeOnline/ ...
  • 類定義,I 開頭的抽象類大多數只是為了定義一下,因為需要單元間交叉引用,但是又不想都是定義為TObject,寫介面又沒必要,只能這麼寫了。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...