三、 redis進階篇

来源:https://www.cnblogs.com/Qsunshine/archive/2019/02/27/10420070.html
-Advertisement-
Play Games

1. redis事務 使用方法:方法為先發送multi命令告訴redis,下麵所有的命令屬於同一個事務,先不要執行,而是把他們暫時存起來,redis返回OK,然後後面執行需要放在同一個事務里的命令,可以看到每個命令都會返回QUEUED表示這幾條命令已經進入等待執行的事務隊列中了,當需要在同一個事務中 ...


1. redis事務

  使用方法:方法為先發送multi命令告訴redis,下麵所有的命令屬於同一個事務,先不要執行,而是把他們暫時存起來,redis返回OK,然後後面執行需要放在同一個事務里的命令,可以看到每個命令都會返回QUEUED表示這幾條命令已經進入等待執行的事務隊列中了,當需要在同一個事務中執行的命令發送完畢後,使用exec命令告訴redis將等待執行的事務隊列中的所有命令按照發送順序依次執行,exec命令的返回值就是這些命令的返回值組成的列表,返回值順序和命令執行順序一樣。

  性質:redis保證一個事務中的所有命令要麼都執行,要麼都不執行。如果在發送exec命令之前客戶端斷線了,則redis會清空事務隊列,事務中所有命令都不會執行。而一旦客戶端發送了exec命令,所有的命令都會被執行,即使客戶端斷線也沒有關係,因為redis中已經記錄了所有要執行的命令。

  使用場景:在需要都執行或者都不執行的情況下,或者希望執行哪幾條命令不被插入也可以使用事務。

  錯誤處理:分以下兩種情況

  (1)語法錯誤:語法錯誤指命令不存在或者命令參數不對,這種情況當執行exec命令後redis就會直接返回錯誤,連語法正確的命令也不會執行。(其實在輸入錯誤命令時就已經返回錯誤了,只不過不會退出隊列,所以出現錯誤時直接返回重新來就行了,因為後面就算都對執行exec後也是沒法執行的)

  (2)運行錯誤:運行錯誤是指在命令執行的時候出現的錯誤,比如用散列類型的命令操作集合類型的鍵,這種錯誤在實際執行之前redis是無法發現的,所以在事務里這樣的命令是會被redis接受並執行的,如果事務里的一條命令出現了運行錯誤,事務里的其他命令依然會被執行(包括出錯命令之後的命令)。

  缺點:就是沒有關係型資料庫事務提供的回滾功能,所以如果出現事務執行錯誤必須自己解決後續問題。

  優點:由於redis不支持回滾功能,所以redis在事務上可以保持簡潔和快捷。

  watch命令:可以監控一個或多個鍵,一旦其中一個鍵被修改或刪除,之後的事務就不會執行,監控一直持續到exec命令(事務中的命令是在exec之後才執行的,所以在multi命令後可以修改watch監控的鍵值。這裡的修改只是說向事務發送這個命令不會報錯,但其實並沒有修改,因為實際修改操作是在exec命令之後,但這個時候事務里的命令其實並沒有執行,exec命令也會返回空結果)。由於watch命令的作用只是當被監控的鍵值被修改後阻止後一個事務的執行,而不能保證其他客戶端不修改這一鍵值。執行exec命令後會取消對所有鍵的監控,如果不想執行事務中的命令也可以使用unwatch命令來取消監控

2. 生存時間

expire  key  seconds   給鍵設置生存時間,到期自動刪除,seconds秒數,返回1表示設置成功,返回0表示設置失敗或鍵不存在

ttl  key    查看鍵還有多少時間會被刪除,返回值是剩餘的秒數,如果返回-1說明鍵永久存在,返回-2說明鍵不存在

persist  key   取消鍵的生存時間,即將鍵恢覆成永久的,如果生存時間被成功清除則返回1,否則返回0(因為鍵不存在或者本身就是永久的)

  使用set或getset命令為鍵賦值也會同時清除鍵的生存時間,使用expire命令會重新設置鍵的生存時間,其他只對鍵值進行操作的命令(如incr、lpush、hset、zrem)均不會影響鍵的生存時間。

  expire命令的seconds參數必須是整數,如果想要更精確的控制鍵的生存時間應該使用pexpire命令,兩者唯一區別就是這個seconds參數是毫秒,同樣可以使用pttl命令以毫秒為單位返回鍵的剩餘時間。

  如果使用watch命令監測一個擁有生存時間的鍵,該鍵時間到期自動刪除並不會被watch命令認為該鍵被改變。

  還有兩個相關命令expireat和pexpireat,這兩個命令與原命令的差別在於這兩個seconds參數是unix時間,表示鍵的生存時間的截止時間。

  過期時間這一屬性可以把redis用作緩存,比如登錄功能,登錄成功放入緩存中,設置一個過期時間,如有則認為已經登錄,如果過期刪除則需要重新登錄。

  實際開發中如果緩存鍵生存時間太長會導致redis占滿記憶體,如果太短可能導致緩存命中率太低並且大量記憶體被白白的閑置,為此可以限制redis能夠使用的最大記憶體,並讓redis按照一定的規則淘汰不需要的緩存鍵,這種方式在只將redis用作緩存系統時非常實用。

  具體設置方法為:修改配置文件的maxmemory參數,限制redis最大可用記憶體大小(單位是位元組),當超出了這個限制時redis會根據maxmemory-policy參數指定的策略來刪除不需要的鍵,直到redis占用的記憶體小於指定記憶體。maxmemory-policy支持的規則如下:(LRU演算法即"最長時間未被使用的",LFU演算法即"一段時間使用最少的")

  volatile-lru      使用LRU演算法刪除一個鍵(只對設置了生存時間的鍵)

  volatile-lfu      使用LFU演算法刪除一個鍵(只對設置了生存時間的鍵)

  volatile-random   隨機刪除一個鍵(只對設置了生存時間的鍵)

  allkeys-lru      使用LRU演算法刪除一個鍵(所有)

  allkeys-lfu      使用LFU演算法刪除一個鍵(所有)

  allkeys-random   隨機刪除一個鍵(所有)

  volatile-ttl       從設置了過期時間的鍵中選擇過期時間最早的鍵刪除

  noeviction     不刪除鍵,只返回錯誤

  使用maxmemory-poliy參數刪除鍵時redis並不會準確的從整個資料庫中查找,而是每次隨機取3個鍵並刪除這三個鍵中符合條件的,3這個數字可以通過redis的配置文件中的maxmemory-samples參數設置。

3. 排序

基本排序:

sort  key  [alpha]  [desc]  [limit start end]  該命令可以給集合和有序集合進行排序,當給有序集合排序時會忽略元素的分數,只針對元素本身的值進行排序。如果要按照ASCLL碼排序非數字元素,需要加上"alpha",倒序需要加上desc,分頁需要加上limit,方法和mysql資料庫一樣。

by參數:

  有時候排序不一定完全按照集合中的元素值本身排序,而是會根據別的元素作為相關鍵進行排序,這時候就用到了by參數。

  by參數的語法"by參考鍵",其中參考鍵可以是字元串類型鍵或者是散列類型鍵的某個欄位(表示為鍵名->欄位名)。如果提供了by參數,sort命令將不再依據元素自身的值進行排序,而是對每個元素使用元素的值替換參考鍵中的第一個"*"並獲取其值,然後依據該值對元素排序。

  當參考鍵名不包含"*"時(即常量鍵名,與元素值無關),sort命令將不會執行排序操作,因為redis認為這種情況是沒有意義的(因為所有要比較的值都一樣)。

  在不需要排序但是需要藉助sort命令獲得與元素相關聯的數據時,常量鍵名是很有用的。

  如果幾個元素的參考鍵值相同,則sort命令會再比較元素本身的值決定元素的順序。

  當某個元素的參考鍵不存在時,會預設參考鍵的值為0。

  參考鍵雖然支持散列類型,但是"*"只能在"->"符號前面(即鍵名部分)才有用,在後面(即欄位名部分)會被當成欄位名本身而不會作為占位符被元素的值替換,即常量鍵名,這樣的結果就是依舊會按照元素本身的值進行排序,因為參考鍵如果是常量redis不會進行排序,但是檢測是否是常量的方法是判斷參考鍵中是否含有"*",上面顯然含有,所以不會被當成常量不排序,而排序的話每個元素的參考值是相通的,所以redis會按照元素本身的大小排序。

get參數:

  get參數可以指定排序後返回的鍵值。get參數不影響排序,它的作用是使sort命令的返回結果不再是元素自身的值,而是get參數中指定的鍵值,get參數的規則和by參數的一樣,get參數也支持字元串類型和散列類型的鍵,並使用"*"作為占位符。一個sort命令中可以有多個get參數,在後面直接加就可以了。如果還需要返回原來的元素值,可以使用"get #"。

store參數:

  預設情況下sort會直接返回排序後的結果,如果希望保存排序結果可以使用store參數。後面加命令"store key"即可保存在key中,保存後的鍵的類型為列表類型,如果鍵已經存在則會覆蓋它,加上store參數後sort命令的返回值為結果的個數。

性能優化:

  sort命令是redis中最強大最複雜的命令,使用不好容易成為性能瓶頸,redis在排序前會建立一個長度等同於要排序的集合中的元素個數的容器來存儲待排序的元素,雖然是一個臨時的過程,但如果同時進行較多的大數據量排序操作則會嚴重影響性能。所以開發中使用sort命令時需要註意以下幾點:

  (1)儘可能減少待排序鍵中元素的數量;

  (2)儘量使用limit參數只獲取需要的數據;

  (3)如果要排序的數據數量較大,儘可能使用store參數將結果緩存。

4. 消息通知

使用redis實現任務隊列:

  (1)簡單隊列概念

  使用loush和rpop命令可以實現隊列的概念,但是這樣即使隊列中沒有任務也會一直調用rpop命令查看是否有新任務,最好可以實現有新任務加入隊列時通知調用者就好了。這裡再介紹一個命令brpop。

  brpop命令接收兩個參數,第一個是鍵名,第二個是超時時間,單位是秒。當超過了此時間仍然沒有獲得新元素的話就會返回nil。如果超時時間設置為0的話,表示不限制等待時間,即如果沒有新元素加入隊列就會永遠阻塞下去。

  除了brpop名另外,還有blpop命令,即從左取元素。

  (2)隊列優先順序問題

  brpop命令可以同時接收多個鍵,其完整的命令格式為"blpop key1 [key2...] timeout",意思是同時檢測多個鍵,如果所有鍵都沒有元素則阻塞,如果其中有一個鍵有元素則會從該鍵中彈出元素。如果多個鍵都有元素,則會按照從左到右的順序取第一個鍵中的一個元素。這樣如果想要設置優先順序,比如先取哪個隊列中的元素,只要把它放在blpop前面的參數即可,這樣只要第一個鍵里有元素,不管第二個鍵里有多少個元素都會先從第一個鍵中取出。

  (3)發佈/訂閱模式

  發佈訂閱模式中包含兩種角色,分別是發佈者和訂閱者。訂閱者可以訂閱一個或多個頻道,而發佈者可以向指定的頻道發送消息,所以訂閱此頻道的訂閱者都會收到此消息。

  發佈者發佈消息的命令是publish,用法是publish channel message,該命令返回值表示收到這條消息的訂閱者數量。發出的消息不會被持久化,也就是說客戶端訂閱某頻道之後只能收到後續發佈的該頻道的消息,之前發送的就收不到了。

  subscribe channel [channel...] 訂閱頻道,可以多個

  執行過訂閱命令後客戶端會進入訂閱狀態,處於此狀態下客戶端不能使用除subscribe/unsubscribe/psubscribe/punsubscribe這四個屬於發佈訂閱模式的命令之外的命令,否則會報錯。

  進入訂閱狀態後客戶端可能收到三種類型回覆,每種類型回覆都包含三個值,第一個值是消息的類型,根據消息類型不同,第二、三個值的含義也不同。消息類型可能的值有:

  Subscribe。表示訂閱成功的反饋信息。第二個值是訂閱成功的頻道名稱,第三個值是當前客戶端訂閱的頻道數量。

  message。這個類型的回覆是我們最關心的,它表示接收到的消息,第二個值表示產生消息的頻道名稱,第三個值是消息的內容。

  unsubscribe。表示成功取消訂閱某個頻道。第二個值是對應的頻道名稱,第三個值是當前客戶端訂閱的頻道數量,當此值為0時客戶端會退出訂閱狀態,之後就可以執行其他非發佈訂閱模式的命令了。

  unsubscribe  [channel  [channel ...]]    取消訂閱指定頻道,如果不指定則會取消訂閱所有頻道。

  (4)按照規則訂閱

  可以使用psubscribe命令訂閱指定的規則,規則支持glob風格通配符格式。

  當使用psubscribe命令訂閱時,收到的message類型回覆會有所改變,一共四個值,第一個是pmessage而不是message,第二個是訂閱時使用的通配符,第三個值表示實際收到消息的頻道命令,第四個值則表示消息內容。

  使用psubscribe命令可以重覆訂閱一個頻道,如某客戶端執行了psubscribe channel.? channel.?*,這時向channel.2發佈消息後該客戶端會收到兩條消息,而同時publish命令返回的值也是2而不是1。同樣的,如果另一個客戶端執行了subscribe channel.10,和psubscribe channel.?*的話,向channel.10發送命令該客戶端也會收到兩條消息(但是是兩種類型,message和pmessage),同時publish命令會返回2。

  punsubscribe命令可以退訂指定的規則,用法是punsubscribe [pattern [pattern ...]],如果沒有參數會退訂所有的規則。

  使用punsubscribe命令只能退訂通過psubscribe命令訂閱的規則,不會影響直接通過subscribe命令訂閱的頻道;同樣unsubscribe命令也不會影響通過psubscribe命令訂閱的規則。另外容易出錯的一點是使用punsubscribe命令退訂某個規則時不會將其中的通配符展開,而是進行嚴格的字元串匹配,所以punsubscribe *無法退訂channel.*規則,而是必須使用punsubscribe channel.*才能退訂。


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

-Advertisement-
Play Games
更多相關文章
  • 安裝包鏈接:https://pan.baidu.com/s/1WsQTeEQClM88aEqIvNi2ag 提取碼:s241 rlwrap-0.37-1.el6.x86_64.rpm 和 rlwrap-0.37-1.el6.i686.rpm,安裝perl依賴後如果還提示需要安裝perl,實則需要安裝 ...
  • 一、SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". 這個報警告的原因簡單來說時因為slf4j的版本和log4j的版本不匹配。 解決辦法: 1.在你的maven庫中查找你的slf4j版本,若有兩個,最後選版本低的,因為本 ...
  • 筆記記錄自林曉斌(丁奇)老師的《MySQL實戰45講》 4) --深入淺出索引(上) 一句話簡單來說,索引的出現其實就是為了提高數據查詢的效率,就像書的目錄一樣。 索引的常見模型 哈希表:哈希表是一種以Key-Value存儲數據的結構,只要輸入key,就可以找到對應的value。哈希的思路很簡單, ...
  • 1、通過information_schema.COLUMNS表 查詢該表可得到所需欄位信息 如下圖所示: 2、示例 下麵截圖是示例: SQL語句如下 3、導出Excel 點擊導出結果即可導出 ...
  • 在https://www.cnblogs.com/loverwangshan/p/10415937.html中我們有講到委托的非同步方法,Thread,ThreadPool,然後今天來講一下Task, ThreadPool相比Thread來說具備了很多優勢,但是ThreadPool卻又存在一些使用上的 ...
  • 同一個賬號,不同客戶端登錄,可以根據user()來記錄IP、判斷是誰在操作。 ...
  • 設計SQL後,應使用explain命令檢查SQL,看是否使用到索引,是否存在filesort,重點檢查檢索的行數(rows)是否太大。 一般來說. 1.rows<1000,是在可接受的範圍內的。 2.rows在1000~1w之間,在密集訪問時可能導致性能問題,但如果不是太頻繁的訪問(頻率低於1分鐘一 ...
  • 資料庫索引,到底是什麼做的? 問題1. 資料庫為什麼要設計索引? 圖書館存了1000W本圖書,要從中找到《架構師之路》,一本本查,要查到什麼時候去? 於是,圖書管理員設計了一套規則: (1)一樓放歷史類,二樓放文學類,三樓放IT類… (2)IT類,又分軟體類,硬體類… (3)軟體類,又按照書名音序排 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...