1. 程式人生 > >redis 基礎(一)

redis 基礎(一)

Redis 的特點

  • 效能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
  • Redis支援資料的持久化,可以將記憶體中的資料儲存在磁碟中,重啟的時候可以再次載入進行使用。
  • Redis支援資料的備份,即master-slave模式的資料備份。
  • 豐富的資料型別 – Redis支援二進位制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 資料型別操作。
  • 原子 – Redis的所有操作都是原子性的,意思就是要麼成功執行要麼失敗完全不執行。單個操作是原子性的。多個操作也支援事務,即原子性,通過MULTI和EXEC指令包起來。
  • 高可用和分散式:哨兵機制實現高可用,保證redis節點故障發現和自動轉移
  • 豐富的特性 – Redis還支援 publish/subscribe, 通知, key 過期等等特性。

Redis 的五種資料型別

string

string 資料型別是最常用、簡單的key-value型別,普通的key/value 儲存都可以歸為此類。value不僅可以是字串,也可以是數字,圖片(base64),物件(序列化);

使用場景 :

  • 做快取資料的功能 spring-boot-starter-data-redis

  • 儲存 session 資訊 spring-session-data-redis

  • 做分散式鎖 Redisson

    # ex:秒級過期時間,nx:鍵不存在時才能設定成功,xx鍵存在時才能設定成功
    set key value [ex seconds] [px milliseconds] [nx|xx]
  • 全域性唯一 Id ,這比使用 uuid 會高效,使用的命令為

    # key 在每次執行 incr 會增加 1 
    incr key
    # 如果應用系統每次獲取 id 時,都發一次命令,會對 redis 造成很大的壓力,一般的做法是應用系統每次取一定量的 id ,然後儲存在本地記憶體,然後內部使用鎖或原子數來增加 
    incrby key count 
  • 計數,也是使用 incr 命令;常見的場景有點贊數,閱讀數

  • 介面防刷,比如驗證碼,如果有人用程式不停的呼叫的你的驗證碼介面,可以用 redis 的 key 的過期時間解決

    # 驗證碼,單個手機號,一分鐘過期 ,一分鐘之內只能傳送一次
    set shortMsg:checkCode:${phoneNum} ex 60 nx 

hash

使用場景 :

  • hash 可以用來儲存結構化資料,比如使用者資訊
  • 非業務表可以使用 hash 來做資料快取,比如字典表就很符合 hash 的資料結構

list

list 在 redis 中的實現是雙向連結串列,可以在兩端進行插入和彈出,還可以在一定範圍內取出元素,列表中的元素有序,可重複,是一種比較靈活的資料結構。

使用場景 :

  • 列表資料快取;

    一個專案中的真實案例,有 100 萬個裝在車上的裝置,然後裝置的每一段里程都會上報,由另一個部門資料部門進行統計,我們業務部門有一個統計報表需要知道車輛一個時間段內的里程資訊,會呼叫資料部門的介面,由於資料部門的資料是每一小時會儲存一份(考慮到最小統計單位是小時),所以如果時間跨度比較大的話,資料部門會有大量的統計比較耗時,當時使用的是 list 做資料快取,用查詢時間段做為 key

  • 阻塞佇列

    brpop 命令有個特性,可以在有訊息的時候彈出,在沒有訊息的時候阻塞

  • 可以使用 lpush 和 lpop 實現棧

  • 可以使用 lpush 和 rpop 實現佇列

set

集合是一種無序,不允許重複元素,很類似於數學中的集合,可以用它來求交集,並集,差集,補集等問題; 相比於 org.apache.commons.collections.CollectionUtils 來說,它對於更大資料量的交集運算會更合適一點。

使用場景 :常用在社交軟體中

  • 共同關注,共同愛好
  • 可能認識的人

zset

排序的集合,不能有重複的元素,而且還可以排序,它和列表使用索引下標作為排序依據不同的是,它給每個元素設定一個分數(score)作為排序的依據,我們可以使用自定義的規則計算一個分值,並分配給元素。

使用場景 :

  • 部落格排名 ,像 csdn 的排名
  • 排行榜,計算統合得分

持久化 AOF 和 RDB

RDB 方式指生成快照的方式,以二進位制形式儲存全部資料。

AOF 會定時將寫入命令追加到 aof_buf 緩衝區,然後使用 sync 非同步刷到磁碟。

RDB 持久化方式

執行 bgsave 命令時,redis 程序執行 fork 建立子程序完成持久化,是 save 命令的優化,save 會阻塞當前程序

在 redis-cli 執行 shutdown 命令時,如果沒有啟 aof ,將自動執行 bgsave

優點:適合於做資料冷備,恢復速度快,檔案體積小

缺點:如果兩臺伺服器的 redis 版本不一致,存在相容性問題,無法實時持久化

相關配置

# 表示在多少秒內,有幾次改變,將執行 rdb 持久化; 如果只配置了 save "" 將關閉 rdb 持久化
save <seconds> <changes>
# 是否啟用壓縮,一般都需要啟用
rdbcompression yes
# 資料庫檔案,預設就行
dbfilename dump.rdb
# 資料檔案目錄,自已玩預設就行
dir ./

AOF 持久化方式

需要開啟配置 appendonly yes

寫入命令會追加到一個緩衝區,然後定時向磁碟做 sync 同步

當檔案越來越大時需要優化重寫 aof 檔案來壓縮,使用 bgrewriteaof 機制,fork 子程序來進行 aof 檔案的重寫

redis 重啟時可載入 aof 檔案進行資料恢復。

優點:實時持久化,可儘可能的恢復資料

缺點:文字格式,體積過大,恢復速度慢

相關配置

# 開啟 aof 
appendonly yes
# aof 檔名,預設就行
appendfilename "appendonly.aof"
# 每秒一次 flush 操作,預設就行
appendfsync everysec

# 在 aof 檔案重寫的時候是否不刷資料到磁碟,而是留在快取區
no-appendfsync-on-rewrite  yes 
# aof 檔案大小比上次重寫增加 100% 進行重寫
auto-aof-rewrite-percentage 100 
# 超過 64m 時進行重寫
auto-aof-rewrite-min-size 64mb

AOF 檔案格式

下面是一個命令的例子,簡單的在0 庫的一個 set 命令 set sanri mm

*2
$6
SELECT
$1
0
*3
$3
set
$5
sanri
$2
mm
  • 資料或指令都會獨佔一行
  • * 表示一個命令的開始 ,*2 表示接下來的命令有 2 個佔位,select 0
  • $6 表示接下來的資料或指令有 6 個字元

基於 aof 的檔案格式,可以從資料庫導資料到 redis

其實就是拼接成 aof 的檔案格式的資料,然後恢復進 redis 庫

  1. 寫好拼裝的 sql 指令碼,比如 vehicle.sql

  2. 執行 sql ,插入redis 的 2 號資料庫 ,使用 pipe 方式

    mysql -uroot -p123456 newgps --skip-column-names --default-character-set=utf8 --raw < vehicle.sql | redis-cli -a hhxredis --pipe -n 2

具體實現可以參照我的另一篇文章 匯出 mysql 資料到 redis

Redis 重啟時恢復載入 AOF 和 RDB 的順序及流程

  1. 當 AOF 和 RDB 檔案同時存在時,優先載入 AOF
  2. 若關閉了 AOF ,載入 RDB 檔案
  3. 載入AOF/RDB成功,redis重啟成功
  4. AOF/RDB存在錯誤,redis啟動失敗並列印錯誤資訊

Springboot 整合 Redis

引入 maven 依賴

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

配置 redis 和連線池

spring.redis.host=192.168.163.100
spring.redis.port=6379
#spring.redis.password=
spring.redis.database=0
# 連線超時時間(毫秒)
spring.redis.timeout=5000

# 連線池最大連線數(使用負值表示沒有限制)
spring.redis.pool.max-active=1000
# 連線池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.pool.max-wait=-1
# 連線池中的最大空閒連線
spring.redis.pool.max-idle=10
# 連線池中的最小空閒連線
spring.redis.pool.min-idle=2

配置序列化工具

預設情況下,SpringBoot 已經配置好了兩個模板工具

  • RedisTemplate 鍵和值都使用 Jdk 序列化
  • StringRedisTemplate 鍵和值都使用 String 序列化

jdk 序列化存在體積大,還容易因為修改了類的屬性而存在反序列化異常,需要一個 serialVersionUID 等問題,一般都自定義序列化工具,常見的序列化工具可以是 fastjsonkryoHessianProtostuff,見文章 序列 化工具效能對比

看網上大多是重新定義 RedisTemplate 類來修改序列化,但個人不建議這麼做,你可能把別人用的給打亂了,或者專案已經有舊資料在 redis 上,用的 jdk 序列化,如果改動會造成很大的影響,應該新建一個類,重新在 IOC 容器註冊一個新類的例項,來使用新的序列化。相關原始碼

一點小推廣

創作不易,希望可以支援下我的開源軟體,及我的小工具,歡迎來 gitee 點星,fork ,提 bug 。

Excel 通用匯入匯出,支援 Excel 公式
部落格地址:https://blog.csdn.net/sanri1993/article/details/100601578
gitee:https://gitee.com/sanri/sanri-excel-poi

使用模板程式碼 ,從資料庫生成程式碼 ,及一些專案中經常可以用到的小工具
部落格地址:https://blog.csdn.net/sanri1993/article/details/98664034
gitee:https://gitee.com/sanri/sanri-tools-ma