1. 程式人生 > 實用技巧 >SpringBoot +必樂國際註冊Mybatis-plus=plus的一級快取、二級快取詳解

SpringBoot +必樂國際註冊Mybatis-plus=plus的一級快取、二級快取詳解

編者按:必樂國際指定註冊也當過面試官,面試過不少應聘者,因為是我自己招人自己用,所以我不會看應聘者造火箭的技術有多牛比,只看擰螺絲的手藝瓷不瓷實。畢竟以後是一個整體,拖了大家後腿團隊都很難受。面試的題目一般也不會太難,就像問Redis,我只是想確認他真正用過就夠了。Redis5種基礎資料結構和簡單操作要知道,最基本的要求,如果這個時候他會說出每種資料結構大致的應用場景,那麼這一定是加分的,起碼要比那些只會說出幾種資料結構後,在那乾瞪眼等我問下一個問題的強很多,千萬別冷場。

使用docker啟動一個AgileConfig例項

  1. sudo docker run --name agile_config -e adminConsole=true -e db:provider=sqlserver -e db:conn="Persist Security Info = False; User ID =dev; Password =dev@123,; Initial Catalog =agile_config_test; Server =." -p 5000:5000 kklldog/agile_config:latest

使用docker命令執行一個AgileConfig例項,這是最簡單的方法。當然你也可以拉原始碼下來編譯釋出使用IIS來執行它。
配置環境變數:
adminConsole=true 開啟控制檯功能
db:provider=sqlserver 資料庫為SqlServer
db:conn="Persist Security Info = False; User ID =dev; Password =dev@123,; Initial Catalog =agile_config_test; Server =." 配置資料庫連線
-p 5000:5000 容器的5000口對映本地的5000口

配置AgileConfig

第一次執行需要配置管理密碼

密碼配置完成後重新登入進系統,開始配置節點

在設計的時候節點跟控制檯是分開的,但是為了部署簡單最後節點跟控制檯被實現在一起了。所以採用單節點部署的時候,該例項既是節點又是控制檯,所以也需要把本節點的地址加入到節點列表裡,以便控制檯能管理到。

新增應用

AgileConfig的初始化完成了,現在我們開始新增應用。
新增“公共應用”

新增應用名稱,應用id,勾選“可被繼承”。點選確定完成公共的建立。系統只支援一層的繼承,可被繼承的應用不能再繼承其它應用。
建立完成後為公共應用新增配置項

為公共應用新增一個配置項:鍵為public_key_01 值為0001 。

新增“私有應用”

新增一個私有應用,不要選“可被繼承”。點選繼承應用欄的加號會彈出可以被的繼承應用列表,選擇“公共應用”。點選“確定”完成建立。

為私有應用建立配置項

為私有應用新增一個配置項:鍵為private_key_01 值為0002 。

注意:把所有的配置都上線,否則客戶端讀不到配置。

客戶端讀取配置

建立Asp.net Core WebApi專案

我們建立一個WebApi專案做為客戶端來演示如何讀取配置

使用nuget引用AgileConfig.Client

Install-Package AgileConfig.Client -Version 1.1.0

整合AgileConfig.Client

使用nuget安裝成功後,切換到Program.cs開始整合AgileConfigClient。

  1. public static IHostBuilder CreateHostBuilder(string[] args) =>
  2. Host.CreateDefaultBuilder(args)
  3. .ConfigureAppConfiguration((ctx,cfg)=> {
  4. var appId = "private_01";
  5. var secret = "1";
  6. var nodes = "http://localhost:5000";
  7. //new一個client例項
  8. var configClient = new ConfigClient(appId, secret, nodes);
  9. //使用AddAgileConfig配置一個新的IConfigurationSource
  10. cfg.AddAgileConfig(configClient);
  11. })
  12. .ConfigureWebHostDefaults(webBuilder =>
  13. {
  14. webBuilder.UseStartup<Startup>();

Redis基礎資料結構有哪些?

一、String(字串)

在任何一種程式語言裡,字串String都是最基礎的資料結構, 那你有想過Redis中儲存一個字串都進行了哪些操作嘛?

RedisString是可以修改的,稱為動態字串(Simple Dynamic String簡稱SDS)(快拿小本本記名詞,要考的),說是字串但它的內部結構更像是一個ArrayList,內部維護著一個位元組陣列,並且在其內部預分配了一定的空間,以減少記憶體的頻繁分配。

Redis的記憶體分配機制是這樣:

  • 當字串的長度小於 1MB時,每次擴容都是加倍現有的空間。

  • 如果字串長度超過 1MB時,每次擴容時只會擴充套件 1MB 的空間。

這樣既保證了記憶體空間夠用,還不至於造成記憶體的浪費,字串最大長度為512MB.。

以上圖片源自網路,如有侵權聯絡刪除

上圖就是字串的基本結構,其中content裡面儲存的是字串內容,0x\0作為結束字元不會被計算len中。

分析一下字串的資料結構

  1. struct SDS{

  2. T capacity; //陣列容量

  3. T len; //實際長度

  4. byte flages; //標誌位,低三位表示型別

  5. byte[] content; //陣列內容

  6. }

capacitylen兩個屬性都是泛型,為什麼不直接用int型別?因為Redis內部有很多優化方案,為更合理的使用記憶體,不同長度的字串採用不同的資料型別表示,且在建立字串的時候len會和capacity一樣大,不產生冗餘的空間,所以String值可以是字串、數字(整數、浮點數) 或者 二進位制。

1、應用場景:

儲存key-value鍵值對,這個比較簡單不細說了

2、字串(String)常用的命令:

  1. set [key] [value] 給指定key設定值(set 可覆蓋老的值)

  2. get [key] 獲取指定key 的值

  3. del [key] 刪除指定key

  4. exists [key] 判斷是否存在指定key

  5. mset [key1] [value1] [key2] [value2] ...... 批量存鍵值對

  6. mget [key1] [key2] ...... 批量取key

  7. expire [key] [time] 給指定key 設定過期時間 單位秒

  8. setex [key] [time] [value] 等價於 set + expire 命令組合

  9. setnx [key] [value] 如果key不存在則set 建立,否則返回0

  10. incr [key] 如果value為整數 可用 incr命令每次自增1

  11. incrby [key] [number] 使用incrby命令對整數值 進行增加 number


二、list(列表)

Redis中的listJava中的LinkedList很像,底層都是一種連結串列結構,list的插入和刪除操作非常快,時間複雜度為 0(1),不像陣列結構插入、刪除操作需要移動資料。

像歸像,但是redis中的list底層可不是一個雙向連結串列那麼簡單。

當資料量較少的時候它的底層儲存結構為一塊連續記憶體,稱之為ziplist(壓縮列表),它將所有的元素緊挨著一起儲存,分配的是一塊連續的記憶體;當資料量較多的時候將會變成quicklist(快速連結串列)結構。

可單純的連結串列也是有缺陷的,連結串列的前後指標prevnext會佔用較多的記憶體,會比較浪費空間,而且會加重記憶體的碎片化。在redis 3.2之後就都改用ziplist+連結串列的混合結構,稱之為quicklist(快速連結串列)

下面具體介紹下兩種連結串列

ziplist(壓縮列表)

先看一下ziplist的資料結構,

  1. struct ziplist<T>{

  2. int32 zlbytes; //壓縮列表佔用位元組數

  3. int32 zltail_offset; //最後一個元素距離起始位置的偏移量,用於快速定位到最後一個節點

  4. int16 zllength; //元素個數

  5. T[] entries; //元素內容

  6. int8 zlend; //結束位 0xFF

  7. }

int32 zlbytes: 壓縮列表佔用位元組數int32 zltail_offset: 最後一個元素距離起始位置的偏移量,用於快速定位到最後一個節點int16 zllength:元素個數T[] entries:元素內容int8 zlend:結束位 0xFF

壓縮列表為了支援雙向遍歷,所以才會有ztail_offset這個欄位,用來快速定位到最後一 個元素,然後倒著遍歷

以上圖片源自網路,如有侵權聯絡刪除

entry的資料結構:

  1. struct entry{

  2. int<var> prevlen; //前一個 entry 的長度

  3. int<var> encoding; //元素型別編碼

  4. optional byte[] content; //元素內容

  5. }

entry它的prevlen欄位表示前一個entry的位元組長度,當壓縮列表倒著遍歷時,需要通過這 個欄位來快速定位到下一個元素的位置。

1、應用場景:

由於list它是一個按照插入順序排序的列表,所以應用場景相對還較多的,例如:

  • 訊息佇列:lpoprpush(或者反過來,lpushrpop)能實現佇列的功能

  • 朋友圈的點贊列表、評論列表、排行榜:lpush命令和lrange命令能實現最新列表的功能,每次通過lpush命令往列表裡插入新的元素,然後通過lrange命令讀取最新的元素列表。

2、list操作的常用命名:

  1. rpush [key] [value1] [value2] ...... 連結串列右側插入

  2. rpop [key] 移除右側列表頭元素,並返回該元素

  3. lpop [key] 移除左側列表頭元素,並返回該元素

  4. llen [key] 返回該列表的元素個數

  5. lrem [key] [count] [value] 刪除列表中與value相等的元素,count是刪除的個數。 count>0 表示從左側開始查詢,刪除count個元素,count<0 表示從右側開始查詢,刪除count個相同元素,count=0 表示刪除全部相同的元素

  6. (PS: index 代表元素下標,index 可以為負數, index= 表示倒數第一個元素,同理 index=-2 表示倒數第二 個元素。)

  7. lindex [key] [index] 獲取list指定下標的元素 (需要遍歷,時間複雜度為O(n))

  8. lrange [key] [start_index] [end_index] 獲取list 區間內的所有元素 (時間複雜度為 O(n))

  9. ltrim [key] [start_index] [end_index] 保留區間內的元素,其他元素刪除(時間複雜度為 O(n))


三、hash (字典)

Redis中的Hash和 Java的HashMap更加相似,都是陣列+連結串列的結構,當發生 hash 碰撞時將會把元素追加到連結串列上,值得注意的是在RedisHashvalue只能是字串.