redis知識點筆記

来源:https://www.cnblogs.com/feifeisha/archive/2022/12/27/16157758.html
-Advertisement-
Play Games

Redis相關複習 知識點 相關知識點簡介 1 為什麼要使用redis(說redis優點)? 2 使用redis有什麼缺點? 3 單線程的redis為什麼這麼快? 4 redis的數據類型,以及每種數據類型的使用場景 5 redis的過期策略以及記憶體淘汰機制 6 redis和資料庫雙寫一致性問題 7 ...


Redis相關複習 知識點

 

相關知識點簡介

1 為什麼要使用redis(說redis優點)?

2 使用redis有什麼缺點?

3 單線程的redis為什麼這麼快?

4 redis的數據類型,以及每種數據類型的使用場景

5 redis的過期策略以及記憶體淘汰機制

6 redis和資料庫雙寫一致性問題

7 如何應對緩存穿透和緩存雪崩問題

8 如何解決redis的併發競爭問題

 


1 為什麼要使用redis?

在項目中使用redis,主要是從兩個角度去考慮:性能併發,redis還具備可以做分散式鎖等其他的功能,但是如果只是為了使用分散式鎖這些功能,還可以使用其它中間件來代替(如zookpeer等),並不是非要去使用redis。

 

  • 一. 性能:當我們碰到執行耗時很長時間,而且結果不頻繁變動的SQL語句,就特別適合將運行結果放入緩存資料庫裡面,這樣一來,後面的請求就全部去緩存裡面讀取,使得請求可以快速響應 (Tips:sql運行時間越短越好,用緩存是最快的方式)

 

  • 二. 併發:在數據量很大的時候,所有的請求直接訪問資料庫,mysql資料庫的壓力會特別大(mysql資料庫併發很小) 然後就會崩潰。

  • 這個時候,就需要使用redis資料庫進行一個中間緩存的操作,讓請求先去訪問reids,而不是去直接訪問mysql (請求過來之後首先先去redis資料庫裡面查數據,redis裡面沒有再去mysql裡面查查到之後放到redis裡面一份),這樣以來,redis解決了大部分的訪問問題,mysql資料庫的壓力就會小很多

Redis的特點:

  • 記憶體資料庫,速度快,也支持數據的持久化,可以將記憶體中的數據保存在磁碟中,重啟的時候可以再次載入進行使用。

  • Redis不僅僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。

  • Redis支持數據的備份,即master-slave模式的數據備份。

  • 支持事務

 命令行啟動redis的方法首先windows +r 輸入cmd 打開黑視窗輸入 redis-server   //第一步啟動客戶端
 
 然後另起一個黑視窗輸入redis-cli -h 資料庫ip       //第二步啟動服務端
 
 然後輸入密碼 即可   //輸入密碼
 
 ctrl + l 清屏

 


2 . 使用redis有什麼缺點

一共是四個問題

  • 緩存和資料庫雙寫一致性問題

  • 緩存雪崩問題

  • 緩存擊穿問題

  • 緩存的併發競爭問題

 


 

3 . 單線程的redis為什麼這麼快

這個問題是對redis內部機制的一個考察,主要是三個點

  • redis純記憶體操作

  • 單線程操作,避免了頻繁的上下文和線程切換,只去處理簡單的sql語句,不處理io操作

  • 採用了非阻塞I/O多路復用機制

題外話:我們現在要仔細的說一說I/O多路復用機制,因為這個說法實在是太通俗了,通俗到一般人都不懂是什麼意思。舉一個例子:張三在家開了一家快遞店,負責同城快送服務。張三因為資金限制,雇佣了一批快遞員(線程),然後張三發現資金不夠了,只夠買一輛車送快遞(只能每次執行一個操作車代表CPU核數)。

經營方式一 客戶每送來一份快遞,張三就讓一個快遞員盯著,然後快遞員開車去送快遞。慢慢的張三就發現了這種經營方式存在下述問題

  • 幾十個快遞員基本上時間都花在了搶車上了,大部分快遞員都處在閑置狀態,誰搶到了車,誰就能去送快遞(多個線程搶占線程鎖,很多線程都是空閑)

  • 隨著快遞的增多,快遞員也越來越多,張三發現快遞店裡越來越擠,沒辦法雇佣新的快遞員了

  • 快遞員之間的協調很花時間(多個線程每次執行之前都搶這一個鎖,浪費時間)

經營方式二 改善之後,小曲只雇佣一個快遞員(單線程)。然後呢,客戶送來的快遞,小曲按送達地點標註好,然後依次放在一個地方。最後,那個快遞員依次的去取快遞,一次拿一個,然後開著車去送快遞,送好了就回來拿下一個快遞(一次執行一個操作,執行完成之後執行其他的)。

 

總結:經營方式一就是傳統的併發模型,每個I/O流(快遞)都有一個新的線程(快遞員)管理。 經營方式二就是I/O多路復用。只有單個線程(一個快遞員),通過跟蹤每個I/O流的狀態(每個快遞的送達地點),來管理多個I/O流。

 

 

 


 

Redis的優勢:

  • 性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。

  • 豐富的數據類型 – Redis支持二進位案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操作。

  • 原子性 – Redis的所有操作都是原子性的,同時Redis還支持對幾個操作合併後的原子性執行。(事務)

  • 豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過期等等特性。

 

redis所有的操作都是原子性的,採用單線程處理所有業務,命令是一個一個執行的,因此無需考慮併發帶來的數據影響

 

五種類型與類比java的模型

  • string --> String

  • hash --> Hashmap

  • list --> LinkList

  • set --> HashSet

  • sorted_set --> TreeSet

     


二 .五大基本數據類型

1 .String類型語句

(典型應用場景: • 通用緩存、計數器(下載量、點擊量、線上人數等)等)

IO優化:合理使用mget、mset、pipeline等多值命令,提高批量操作的效率

• 命令處理時間通常小於網路傳輸時間,減少網路開銷的次數將會極大提高操作效率

• 批量操作的命令/KEY數量一次不易過多,否則會出現Redis處理阻塞或者網路延遲

不要將所有數據都放到Redis記憶體中,只放熱數據和有用的數據**

• 長字元串儘量壓縮存儲,控制在512位元組以內**

 String作為數值操作時的註意事項
 string在redis內部存儲預設就是一個字元串,當遇到增減類操作incr,decr時會轉成數值型進行計算
 redis所有的操作都是原子性的,採用單線程處理所有業務,命令是一個一個執行的,因此無需考慮併發帶來的數據影響。
 按數值進行操作的數據,如果原始數據不能轉成數值,或超過了redis數值上線範圍,將會報錯。9223372036854775807 (java中long型數據最大值,Long.MAX_VALUE)

 

 //spring語法格式
 
 //添加/修改數據
 set key value
 
 //獲取數據
 get key
 
 //刪除數據
 del key
 
 //設置一個有過期時間的鍵    
 set key value [ex 過期時間單位:秒] [px 過期時間單位:毫秒]    //ex跟px之間設置一個就可以了
 
 //設置一個string類型的name,它的過期時間是20秒    
 set name zhangsan ex 20
     
 //查看key的過期時間
 ttl key    
     
 //刪除過期時間的設置    
 persist key
 //也可以通過重新設置值 但是不加過期時間的方式來取消過期時間  
     
     
 //添加/修改多個數據語法格式
 mset key1 value key2 value2
     
 //獲取多個數據
 mget key1 key2
     
 //追加數據到值的尾部
 append key value    
     
 //獲取數據字元個數(字元串長度)
 strlen key  
     
  --------------------------  
 //設置數值數據增加指定範圍的值
 //key的值自增+1    
 incr key
   
 //key增加指定的數值 incrby age 10  
 incrby key increment
     
 //增加一個浮點數(小數)
 incrbyfloat key increment  
     
     
 //設置數值數據減少指定範圍的值
 decr key //自減1
 decrby key increment //減少指定數值  
     
 //清屏
  clear  
       

 


 

2. Hash(哈希)

相當於比string類型多了個對象,可以多個鍵值對存放在一個對象裡面,這就叫做hash

Ø 類型說明:

 哈希類型所存儲的鍵值本身又是一個鍵值對結構!

Ø 典型應用場景:

 對象信息,比如用戶基礎信息、商品信息等

對象類數據的存儲如果具有較為頻繁的更新需求,操作會顯得笨重,存容易,改麻煩。 為了區別與Redis中的鍵值對的稱呼,hash中的鍵成為field,而key特征Redis的鍵。

 

hash類型數據操作的註意事項

 單個hash類型成員個數不要過多

 hgetAll獲取所有成員謹慎使用,容易帶來性能問題(hscan)

hash類型下的value只能存儲字元串,不允許存儲其他類型數據,不存在嵌套現象。如果數據未獲取到,對應的值為(nil) 每個hash可以存儲2的32次方-1個鍵值對

hash類型十分貼近對象的數據存儲形式,並且可以靈活添加刪除對象屬性。但hash設計不是為了存儲大量對象的,切記不可濫用,更不可以將hash作為對象列表使用 hgetAll操作可以獲取全部屬性,如果內部fiekd過多,遍歷整體數據效率就會很低,有可能成為數據訪問瓶頸。

 //Hash基本操作
 
 //添加/修改數據                 對象 屬性 值
 hset key field value   // hset user name zhangsan
 
 //獲取數據
 hget key field         // hget user name          
     
 //根據key刪除數據
 hdel key field1 [field2]  
 // hdel user name  
     
 //根據對象名獲取所有鍵值對    
 hgetall key      
     
 //添加/修改多個數據
 hmset key field1 value1 field2 calue2  
 // hmset user name zhangsan age 15   //user 裡面設置了兩個鍵值對 name和age
 
 //獲取多個數據
 hmget key field1 field2 …    
 // hmget user name age     //獲取user中的name和age的值
     
 //獲取哈希表中欄位的數量
 hlen key  
 
 //獲取哈希表中是否存在指定的欄位
 hexists key field  
 //hexists user name   看user中有沒有name欄位
     
 //獲取哈希表中所有的欄位名和欄位值
 hkeys key //欄位名 獲取所有鍵
 hvals key //欄位值 獲取所有值  
     

 

3 . list 類型

數據存儲需求:存儲多個數據,並對數據進入存儲空間的順序進行區分 需要的存儲數據:一個存儲空間保存多個數據,且通過數據可以體現進入順序 list類型:保存多個數據,底層使用雙向鏈表存儲結構實現

lpush rpop 隊列先進先出(隊列像排隊一樣誰在前面誰先出去)

棧是先進後出(棧像一個水瓶一樣,先進來的最後才能出去)

 //-----------添加/修改/查詢數據----------------
 
 //從list的左邊添加進來  
 lpush key value1 [value2]
 //lpush student zhangsan lisi    
 
 //從list的右邊添加進來    
 rpush key value1 [value2]
 
 //將值 value 插入到列表 key 當中,位於值 pivot 之前或之後。 如果命令執行成功,返回插入操作完成之後,列表的長度。 如果沒有找到指定元素 ,返回 -1 。 如果 key 不存在或為空列表,返回 0
 linsert key BEFORE|AFTER pivot value  
 // linsert student before xiaoli zhangsan   在xiaoli前面添加一個值zhangsan
 
   
 //獲取從lilst左數第start到stop個元素,從0開始
 lrange key start stop
 //lrange student 0 3 獲取student中0到3的值
 
 //查詢第i個元素    
 lindex key index
 
 //獲取指定list的長度    
 llen key
 
 //規定時間內獲取並移除數據 blpop是從左邊移除數據 brpop是從右邊移除數據
 blpop key1 [key2] timeout
 brpop key1 [key2] timeout
 //阻塞式獲取,在規定時間內獲取這個值,規定時間內如果還沒有的時候可以等,直到有值就可以獲取到獲取超時獲取為空. 比如說現在設置了獲取超時時間是30秒,30秒內只要其他客戶端通過 lpush 添加進來數據就可以獲取到並刪除
 //開兩個客戶端,一個設置15s內獲取list1中的值,此時list1位空一直等待(阻塞),在15秒內另一個客戶端存入到list1中數據,此時就被獲取到。    
 
 
 
 //-----------獲取並移除數據-----------------
 
 //獲取並刪除list左邊第一個元素    
 lpop key
 
 //獲取並刪除list右邊第一個元素    
 rpop key    
 
 //移除指定數據 count為移除的數量,value為移除哪個值
 lrem key count value  
 

 


 

4 . Set類型

新的存儲需求:存儲大量的數據,在查詢方面提供更高的效率 需要的存儲結構:能夠保存大量的數據,高校的內部存儲機制,便於查詢 set類型:與hash存儲結構完全相同,僅存儲鍵,不存儲值(nil),並且值是不允許重覆的。也就是只有鍵沒有值的hash Set的基本操作

set類型不允許數據重覆,如果添加的數據在set中已經存在,將只保留一份 set雖然與hash的存儲結構相同,但是無法啟用hash中存儲值的空間

 //-----------添加數據-----------(可以同時添加多個值,用空格分開)
 sadd key menber1 [member2]
 //sadd 集合名 數據1...  
 
 //獲取全部數據
 smembers key
 //smembers 集合名
 
 //刪除指定的數據
 srem key member1 [member2]
 //srem 集合名 數據    
 
 //獲取集合數據總量
 scard key
 
 //判斷集合中是否包含指定數據
 sismember key member
     
     
  ----------------------------------------------------------------------------------  
  //業務場景-隨機操作數據
 //每位用戶首次使用進入頭條時候會設置3項愛好的內容,但是後期為了增加用戶的活躍度,興趣點,必須讓用戶對其他信息類別逐漸產生興趣,增加客戶留存度,如何實現? 使用set的集合隨機獲取就可以
 
 //業務分析
 //系統分析出各個分類的最新或最熱點信息條目並組織成set集合,隨機挑選其中部分信息
 //配合用戶關註的信息分類中的熱點信息放一塊的全部信息集合  
     
 
 //隨機獲取集合中指定數量的數據
 srandmember key [count]  
 //srandmember 集合名 數量
     
 //隨機獲取集合中指定數量的數據(如果不指定數量的話就可以像隨機數一樣)
 srandmember key [count]
     
 
 //隨機獲取集合中的某個數據並將該數據移出集合
 spop key  
     
     
     
 //---------求兩個集合的交、並、差集-----------
     
 //求兩個集合的交集 (比如找兩個人共同的好友)
 sinter key1 [key2]   //sinter 集合一 集合二
     
 //求兩個集合的並集   (兩個人全部的好友)
 sunion key1 [key2]  
     
 //求兩個集合的差集(key1有但是key2沒有的)    
 sdiff key1 [key2]  
     
     
     
 //將指定數據從原始集合移動到目標集合中
 smove source destination member  
 //smove 集合1 集合2 從集合1到集合2移動的數據
     

 


 

SpringBoot整合Redis

1 .首先導入redis對應的starter

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-redis</artifactId>
 </dependency>

2 接下來配置,在application.yml配置文件裡面加redis的數據源相關配置 url username password等

 

3 最後提供 註入redis介面對象RedisTemplate,通過Redisemplate操作redis資料庫

 @Autowired
 private RedisTemplate redisTemplate;
 
 @Test
 void set() {
     ValueOperations ops = redisTemplate.opsForValue();    //ops後面可以用各種類型的屬性 opsForValue是String類型
     ops.set("age",20);
 }
 
 @Test
 void get() {
     ValueOperations ops = redisTemplate.opsForValue();
     System.out.println(ops.get("age"));
 }
 
 
  //所有的Set設置
     @Test
     void AllSet() {
         stringRedisTemplate.opsForValue().set("love", "pig"); //設置String類型
         stringRedisTemplate.opsForSet().add("map","張三","李四","王五"); //設置set集合類型
    }
 
     //所有的Get獲取
     @Test
     void AllGet() {
         System.out.println(stringRedisTemplate.opsForValue().get("name"));
         System.out.println(stringRedisTemplate.opsForHash().get("eat", "fruit"));
    }

 

 


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

-Advertisement-
Play Games
更多相關文章
  • # In[1]# 2.3 字元串name = "ada loveada"print(name.title())print(name.upper())print(name.isupper())name = name.upper()print(name.isupper())print(name.lowe ...
  • #哈希表之單詞查找 英文文章,寫入一個文本文檔,作為基礎測試數據。 建立一個待查關鍵字文件,存儲待查詢的單詞。 輸入查詢的單詞,輸出該單詞的出現次數,及每個出現位置的上下文(前一句,單詞/短語所在的句子,下一句)。 目前只支持查詢一個單詞。 以下為代碼: #include <iostream> #i ...
  • 這次設計一個可以接收多位元組(通過修改例化時的位寬實現)的串口接收模塊。 當接收到9個位元組的數據,但是我們只需要8個位元組的數據時候,我們需要的是前八位的數據還是後八位的數據我們無法確定。 所以我們需要設定一種傳輸協議,這種協議我們可以自定義規則。我們就設定首碼為8'h55+8'hA5,尾碼為8'hF0 ...
  • 作者:smile_lg 來源:blog.csdn.net/smile_lg/article/details/71215619 用來迴圈容器的標簽forEach,查看例子 foreach元素的屬性主要有item,index,collection,open,separator,close。 item:集 ...
  • 哈嘍兄弟們,我總結了Python中十種新手常見的錯誤,每一個都可以用成語來形容,看看各位遇到過多少次了! 一、畫蛇添足 多餘的分號 Python語言與大多數編程語言不相同,它的語句後面不需要加分號結尾。有些 Python 新手具有編寫其它語言的豐富經驗,一時還適應不過來,經常習慣性的加上“分號”: ...
  • 摘要:Thread Dump是非常有用的診斷Java應用問題的工具。 本文分享自華為雲社區《調試排錯 - Java 線程分析之線程Dump分析》,作者:龍哥手記。 Thread Dump是非常有用的診斷Java應用問題的工具。每一個Java虛擬機都有及時生成所有線程在某一點狀態的thread-dum ...
  • 列表條件求和方法 list_data=[ [1.0, '配件', '522422', '鋁扣板用紐扣', '金色', '', 72.0, 'PC', ''], [2.0, '配件', '500031', '十字槽沉頭自鑽自攻螺釘4.2*45', '原色', '', 72.0, 'PC', ''], ...
  • Netty 概述 1、什麼是 Netty Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protoc ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...