Redis 基礎知識點總結

萌新J發表於2020-12-19

關係型資料庫 VS 非關係型資料庫(NoSQL)

關係型資料庫

我們過去使用的 mysql、Oracle 都屬於關係型資料庫。關係型資料庫的特點是資料表之間可以存在聯絡,表內每列資料也存在關聯,同時支援事務、複雜的鎖機制,這樣可以支援複雜操作,在查詢時也可以很快得到與之相關聯的資料,但同時這些也成為限制資料庫速度的因素,在儲存大資料的表中進行查詢、擴充表時會格外消耗時間。在過去受硬體水平的限制,系統架構往往比較簡單,併發量也比較小,但隨著硬體水平的提高,系統變得越拉越龐大,需要儲存的資料量也越來越大,很多業務都需要在海量資料中快速查詢到所需要的資料,此時靠關係型資料庫已經無法滿足了,所以提出了非關係型資料庫的概念。

 

非關係型資料庫

非關係型資料庫中的資料間沒有關聯關係,資料結構簡單,在資料的增刪改查時速度都比較快,缺點是不能支援複雜的操作,比如事務的ACID、複雜的鎖機制,也因為資料間沒有關聯關係所以在查詢符合條件的資料會很慢。所以我們通常只使用 NoSQL 來儲存一些簡單、不需要複雜操作的資料,如某個使用者的粉絲數,某個部落格的點贊數、字數等。

 

四種聚合模型

 

總結

傳統的關係型資料庫因為內部功能多,資料間存在關聯,導致在資料量過大時操作起來比較困難。非關係型資料庫則與之相反從而得到了很好的效能,在日益要求效能的今天起到了很好的作用,但是因為其不能實現複雜功能,所以對於一些需要複雜操作(讀寫鎖、事務、多表聯查等)還是使用關係型資料庫,而對於一些簡單資料,不需要太複雜操作的可以使用非關係型資料庫。

 

Redis 

redis 是一個單執行緒(底層使用IO多路複用模型)分散式資料庫,也是一個典型的 NoSQL,它的執行效率非常高,其原因主要有以下幾點:

1、是非關係型資料庫,資料結構簡單,且沒有複雜的關聯關係。

2、單執行緒操作,避免了多執行緒之間切換和競爭,並通過IO多路複用模型來避免傳統 BIO 的低效執行。

3、資料儲存在記憶體,讀取時直接從記憶體中讀取。

基礎知識

1、在安裝後相應的執行命令和配置檔案預設在 /usr/local/bin/ 目錄下

2、redis 預設有 16個資料庫,0-15,預設是0號資料庫,可以通過 " select 資料庫號"  來切換資料庫。資料庫個數可以在 redis.conf 中配置。

3、redis 是統一密碼管理,預設情況下沒有開啟密碼,可以在配置檔案 redis.conf 中配置開啟

4、預設埠是 6379。

5、啟動伺服器:redis-server  配置檔案全路徑。配置檔案可以是自定義的配置檔案。啟動客戶端:redis -cli -p  6379。

 

五大基本資料型別及常用方法

String

最基本的資料型別,雖然為 String 型別,但是其 value 可以為 string 也可以為 int 型別。其可以用於實現計數器,也可以用於進行 json 格式的物件儲存。

常用方法:

set / get / del / append / strlen :  設值 / 獲值 / 刪值 / 末尾新增值 / 獲取長度

Incr / decr / incrby key n / decrby key n:  自增 / 自減 / 增加 n / 減去 n

getrange  n1  n2 / setrange  n1  n2  val:  擷取下標n1,n2之間的值(從0開始,兩邊都是閉區間) / 設定下標n1,n2區間的值

setex  key  time  val / setnx  key  val:  設值並指定過期時間(單位為秒) / 在 val 不存在或者已過期時設值

mset / mget / msetnx:  批量(進行設定  /  獲值 / 非空設值)

 

List

底層是連結串列結構,方法名開頭的 l 表示 left,r 表示 right。可以用於實現訊息佇列。

常用方法:

lpush / rpush / lrange n1 n2:  左添 / 右添 / 從左開始擷取下標n1,n2之間的內容(0開始,兩邊都是閉區間)

lpop / rpop:  類似於訊息佇列和棧的出棧操作,分別是 (左出棧 / 右出棧)

lindex:  從左邊計算獲取指定下標的值

lrem key n  value:  對 key 對應的 list 資料從左邊開始刪除 n 個 value

ltrim  key  n1  n2:  獲取 key 對應的 list 值,擷取 n1 到 n2 之間的值再賦值覆蓋當前的 list 值。

rpoplpush  list1  list2:  將list1中的右邊尾部資料移到 list2 的左邊頭部 

lset  key  index  value:  左邊開始修改指定索引上的值

linsert  key  before/after  val1  val2:  從左開始,獲取第一個 val1,在其 (左 / 右) 插入 val2   

 

Set

和 java 中的 Set 集合一樣,唯一無需的結構。可以用來儲存好友,然後計算共同好友

常用方法:

sadd / smembers / sismember key val:  新增(可以批量新增) / 顯示所有值 / 檢視是否存在val

scard key:  獲取集合中元素的個數

srem key val:  刪除某個元素

scrandmember  key  n:  隨機出 n 個元素

spop key:  隨機出棧一個元素

smove key1  key2  key1中的某個值val:  將 key1 對應集合中的某個值val 移入 key2 對應的集合中

sdiff  key1  key2...:  獲取存在與於key1 對應集合中但不存在後面所有key對應集合中的元素

sinter key1  key2...:  獲取存在於 key1 對應的集合中且存在於後面所有key對應集合中的元素

sunion  key1  key2...:  獲取存在於 key1 對應的集合中或者存在於後面所有key對應集合中的元素

 

Hash

類似於 java 中的 Map 結構,可以用於儲存物件。

常用方法:

hset / hget / hmset / hmget / hgettall  key/ hdel  key  key(hash):  設值 / 獲值 / 批量設值 / 批量獲取 / 獲取 key 對應所有的鍵值對資料 / 刪除 key 對應 hash 結構中的 key(hash) 對應的值。

hlen  key :  獲取元素個數

hexists  key  key(hash):  檢視 key 對應 hash 結構的 key(hash) 對應的值是否存在

hkeys key / hvals key:  獲取 key 對應 hash 結構所有(key 值 / val 值)

hincrby key  key(hash)  val / hincrbyfloat  key  key(hash)  val:  對 key 對應 hash 結構中的 key(hash) 對應的值新增(整數 / 小數) val

hsetnx  key  key(hash)  val:  不存在時賦值

 

ZSet

每個資料關聯一個分數,排序時會按分數升序排列,相當與一個有序 Set。可以用於實現各種排行榜。

常用方法:

zadd  key  score  val / zrange  key  n1  n2  withscores:  新增 / 獲取所有值

zrangebysorce key score1 score2:  查詢 score1 與 score2 之間的資料

zrem key val:  刪除某個值

zcard key / zcount key score1  score2 / zrank key value / zscore key value:  獲取資料數 / 統計在 score1 與 score2 之間元素的個數 / 獲取指定資料所在下標 / 獲取指定資料的分數

zrevrant key value:  逆序獲取指定值的下標

zrevrangebyscore key score1 score2:  逆序獲取 score1 與 score2 之間的資料

 

Key 及其他操作方法

keys  *:  獲取所有的key

exists  key:  檢視是否存在key,返回1是存在,0不存在

expire key  時間:  為 key 設定過期時間,單位是秒

ttl  key:  檢視 key 還有多久過期,-1表示永不過期,-2表示已過期。

type  key:  檢視 key 是什麼型別

Dbsize:  檢視當前資料的 key 數量

Flushdb:  清除當前庫中的所有資料

Flushall:  清除所有庫中的所有資料

 

配置檔案 redis.conf(Linux)

下面列出的各個配置可能存在多出,因為參考了多個版本的配置檔案,同時可能存在遺漏,請見諒。修改配置檔案的原則是不要動預設的配置檔案,應該將預設配置檔案複製一份到指定目錄,然後去處理,防止修改錯誤無法恢復。

Units:配置大小單位,可以用於自定義一些度量單位,底層單位只支援 bytes,大小寫不敏感。

includes:可以來引入其他配置檔案

general:

  Daemonize:  是否以守護程式的方式執行,預設為no,也就是伺服器視窗關閉後就會關閉伺服器,如果需要後臺執行可以設定為 yes。

  protected-mode:  保護模式是否開啟,預設是 yes。關閉其他任何ip 地址都可以來訪問連線,關閉後必須通過 bind 來配置相應的 ip 後,其才能連線。

  Pidfile:  如果 redis 以守護程式的方式執行時,系統就會將這個守護程式的 id 記錄下來,記錄的位置就是通過 Pidfile 來配置,預設是 /var/run/redis.pid

  Port:  埠埠號

  Tcp-backlog:  設定 tcp 的連線佇列長度,其值 = 未完成三次握手佇列 + 已完成三次握手佇列。預設是 511,如果併發量比較大時可以設定為 2048。

  timeout:  設定最大空閒時間,也就是多久沒有操作伺服器就會自動斷開。預設是0,也就是永不斷開。

  Bind:  設定允許訪問的 ip 地址,在 protected-mode 為 yes 時使用。

  tcp-keepalive:  伺服器會檢測客戶端是否還在使用,如果一段時間內客戶端沒有操作,那麼 redis 伺服器就會釋放這條連線,tcp-keepalive 就是設定客戶端的最大空閒時間的,預設是0,也就是永不斷開,而官方推薦是 60,也就是超過60秒沒操作伺服器就會回收這一條的連線。

  loglevel:  日誌級別。從高到低分別為 warning、notice、verbose、debug。預設是 notice。

  logfile:  日誌檔案存放位置。

  Syslog-enable:  是否把輸出日誌儲存到日誌檔案中。預設關閉

  Syslog-ident:  設定日誌中的日誌標識。

  Syslog-facility:  指定輸出 syslog 的裝置,可以為 user 或 local0-local7。

  Databases:  設定資料庫個數。預設16

  always-show-logo:  是否總是顯示 logo,預設 yes。

REPLICATION(主從複製相關):

  一般配置主從複製時,需要自己手動通過 salveof 命令來配置從機,而如果各機器事先就決定好角色,可以直接在配置檔案中配置來避免手動配置。

  masterip:  主機的 ip 地址

  masterport:  主機的埠號

  masterpassword:  主機的密碼

SNAPAHOTTING快照(RDB相關):

  save :  設定RDB自動備份的時間間隔,save 配置的格式是 "save  時間間隔  次數",預設配置是

    save  900  1

    save  300  10

    save  60  10000

從第一行開始作用分別是在 900s 內執行了一次寫操作就會觸發一次備份;300s 內執行了 10次寫操作就會觸發一次備份;60s 內執行了10000次寫操作就會觸發一次備份。

一般來說使用預設配置就可以,如果想要禁用自動備份可以將其刪除或者改成 save ""。

  Stop-writes-on-bgsave-error:  通過bgsave備份出錯時,主執行緒是否繼續工作。

  rdbcompression:  是否壓縮 rdb檔案,需要消耗一些 cpu 資源。壓縮會使檔案佔用空間減小。

  rdbchecknum:  儲存快照後是否進行資料校驗。如果想要提高執行效率可以關閉。

  dbfilename:  備份的檔名。預設是 dump.rdb。

  dir:  RDB、AOF 備份檔案的儲存地址。在伺服器啟動時恢復資料也會在 dir 配置的目錄中讀取對應的備份檔案。預設在執行目錄下。可以通過 "config  get  dir" 獲取 dir 。

APPEND ONLY MODE追加(AOF相關)

  appendonly:  是否啟用AOF。

  appendfilename:  備份檔案的檔名,預設為 appendonly.aof。

  appendfsync:  儲存策略。共有以下三種。

    always:同步持久化,每次寫操作後都會立刻記錄到磁碟,效能較差但是資料完整性最好。

    everysec:非同步操作,每一秒執行一次記錄,可能會有少量資料丟失。

    no:不進行記錄。

  No-appendfsync-on-rewrite:  rewrite 時是否執行儲存策略(進行儲存)。一般使用預設 no 即可,保證資料安全性。

  Auto-aof-rewrite-min-Size:   設定 rewrite 觸發的最小基準值。

  Auto-aof-rewrite-percentage:  設定 rewrite 觸發的超出百分比基準值。

Security(安全許可權相關)

預設情況下,安全許可權是關閉的,在客戶端連線時不需要輸入密碼,執行操作也不需要密碼,但是如果開啟了安全檢測,那麼所有客戶端在執行命令時都需要先執行 "auth 密碼" 來驗證身份。

可以在配置檔案中配置 "requirepass  密碼" 來配置密碼,也可以在命令列執行 "config  set  requirepass  密碼" 來配置,檢視密碼可以使用 "config  get  requirepass"。如果想要關閉可以直接在命令列執行 "config  set  requirepass "" " 。

limit

  maxclients:  最大連線的客戶端數,預設無限制,下同。

  maxmemory:  redis 伺服器佔用的最大記憶體

  maxmemory-policy:  redis 資料儲存策略。類似與執行緒池的拒絕策略,就是當儲存新資料時記憶體空間不足執行的操作。策略主要有以下六種。

    1)volatile-lru:使用 LRU 演算法移除 key,只對設定了過期時間的鍵

    2)allkeys-lru:使用 LRU 演算法移除 key。

    3)volatile-random:在過期集合中移除隨機的 key,只對設定了過期時間的鍵

    4)allkeys-random:移除隨機的 key。

    5))volatile-ttl:移除那些 TTL 最小的 key,即那些最先要過期的 key

    6)noeviction:不進行移除。針對寫操作,只是返回錯誤資訊。

    LRU 演算法就是被使用的資料會被移到頭部,未使用的就會慢慢向尾部靠近,在移除時從尾部移除。

  maxmemory-samples:  設定樣本數。在清除時,因為LRU演算法和最小TTL演算法都並非是精確的演算法,而是估算值,所以我們可以設定一個具體的大小,redis會抽出這個數量的資料並根據演算法進行清除。

 

RDB

預設的持久化方式。其本質就是儲存當前時刻的資料快照預設生成檔名是 dump.rdb。

預設會在一段時間內自動儲存資料,規則就是上面配置檔案 RDB 部分 save 的配置。需要注意的是,RDB 的持久化方式分為 save 與 bgsave。

save 是中斷當前程式,然後進行持久化操作,等到持久化完成後再繼續執行其他操作;

bgsave 是 fork 一個子程式,fork 出來的子程式會擁有當前程式所有的記憶體資料,然後子程式單獨進行持久化操作,不會阻塞當前程式執行。

RDB 持久化觸發時機

1、來自配置檔案中配置的自動備份,也就是上面說得 save。其實現方式是 bgsave。

2、執行命令 save 或 bgsave。執行 save 就是中斷狀態來實現的;而 bgsave 則是 fork 子程式來實現,不會中斷當前程式執行。

3、執行flushdb、flushall、shutdown 命令後在命令生效前也會先備份一次。其實現方式是 save。

RDB 檔案恢復

預設情況下只需要將備份檔案放在啟動目錄下然後在啟動目錄下啟動伺服器即可。

啟動目錄指的是啟動 redis-server 命令的目錄,在備份時會自動備份到該目錄下,比如在 /temp/ 啟動,那麼預設會讀取該目錄下的 dump.rdb 檔案,備份也會在該目錄,如果下次啟動在 /myredis/ 下,那麼也會讀取 /myredis/下的 dump.rdb 檔案,備份資料也是會在該目錄下備份。這個目錄也可以自定義,配置引數是 redis.conf 中 dir 引數。

如何關閉 RDB 的自動備份

可以在配置檔案中將 save 改成 save "",也可以直接執行 " redis-cli config set save ""  "

優勢

1、執行效率高,適用於大規模資料的備份恢復。自動備份不會影響主執行緒工作。

2、備份的檔案佔用空間小。其備份的是資料快照,相對於 AOF 來說檔案大小要小一些。

劣勢

1、可能會造成部分資料丟失。因為是自動備份,所以如果修改的資料量不足以觸發自動備份,同時發生斷電等異常導致 redis 不能正常關閉,所以也沒有觸發關閉的備份,那麼在上一次備份到異常當機過程中發生的寫操作就會丟失。

2、自動備份通過 fork 程式來執行備份操作,而 fork 程式會將當前程式的記憶體資料完整的複製一份,所以這個過程佔用的空間是原來的 2 倍,可能會導致記憶體不足。

 

AOF

AOF 是在 RDB 的補充備份方式,其本質是儲存執行的每一條寫操作(包括flushdb、flushall),所以其產生的備份檔案是可以直接閱讀的。預設備份檔名是 appendonly.aof,儲存位置和 RDB 備份檔案一樣。因為其儲存的是每一條寫操作,所以會比較佔用 CPU,同時生成的備份檔案也比較佔空間,所以預設是關閉的。使用時需要在配置檔案中將其開啟。

AOF 持久化規則

AOF 備份也是採用自動備份,但是備份的頻率會比 RDB 要高,其備份方式分為三種:

1、always:同步持久化,每次寫操作後都會立刻記錄到磁碟,效能較差但是資料完整性最好。

2、everysec:非同步操作,每一秒執行一次記錄,可能會有少量資料丟失,但是效能更好。

3、no:不進行記錄。

 

除此之外,redis 為了防止隨著寫操作越來越多,AOF 的備份檔案越來越大,設定了 rewrite 機制。

Rewrite 機制類似於 RDB 的 bgsave,同樣在後臺開啟一個子程式,其記憶體資料與當前程式的資料一致,然後將這些資料生成對應的寫操作,然後將這些寫操作依次一個臨時檔案,等到全部寫入完畢,再將這個臨時檔案覆蓋掉預設備份檔案 appendonly.aof,在覆蓋過程中 AOF 自動備份會被阻塞。因為 Rewrite 需要消耗額外的 CPU,同時在寫入原檔案時還會造成阻塞,所以應該避免執行 Rewrite。

觸發機制:

1、通過配置檔案中配置的規則預設觸發。

  1)Auto-aof-rewrite-min-Size:觸發重寫最小的基準值。預設是 64M。

  2)Auto-aof-rewrite-percentage:觸發重寫的超出百分比。預設是 100%。

  如果配置按照上面預設配置,那麼觸發 AOF 自動配置需要當前 AOF 檔案超過 64M,同時檔案大小達到了上一次 Rewrite 後檔案大小的兩倍。如果沒有 Rewrite 過那麼會在達到 64M 後觸發第一次。

2、手動通過 " bgrewriteaof " 來觸發重寫。 

AOF 檔案恢復

和 RDB 備份檔案恢復一樣,在預設情況下將備份檔案放在啟動目錄,然後啟動伺服器即可。

檔案修復:因為 AOF 檔案是可修改的,如果內部有一些異常操作,那麼在下次啟動時就會報錯,此時可以通過 redis 提供的修復工具來修復備份檔案。執行命令 " redis-check-aof  --fix  檔名" 來修復。

優勢

總體上來說,要比 RDB 備份方式資料完整性要更好,在資料完整性要求高的場景下可以使用 AOF。

而因為 AOF 有兩種不同的備份規則,所以在資料完整性最優先、效能可以不考慮的場景可以使用 always 方式;在資料完整性要求比較高,但是也允許少量的資料丟失,但是要求效能也不會差,那麼可以選擇 everysec。

劣勢

1、因為儲存的是每一步操作,所以執行效率低。

2、雖然引入 rewrite 來避免備份檔案過大,但是 rewrite 造成的 CPU 資源消耗加上原本備份的 CPU 資源消耗會比只使用 RDB 要多得多,所以如果不是對資料完整性有特別高的要求建議只使用 RDB。

兩種持久化總結

1、預設情況下,redis 只使用 RDB 持久化。因為 AOF 會消耗過多的 CPU,同時執行效率低。

2、如果開啟了 AOF 持久化,那麼在恢復資料時優先使用 AOF 配置檔案來恢復,因為 AOF 儲存的資料更完整。

3、如果 redis 只用於做快取,那麼可以直接禁用 RDB 和 AOF 的自動持久化。

4、RDB 持久化一般用作資料的定期備份,如果對資料完整性要求沒有那麼高,那麼可以只使用 RDB,同時在配置檔案中只儲存 "save  900  1" 這條規則,以此來減少不必要的 CPU 消耗。如果需要使用 AOF ,應該調大 Auto-aof-rewrite-min-Size 來避免頻繁的 Rewrite。

 

Redis 事務

mysql 中的事務擁有 ACID 特性,即原子性、一致性、可見性、永續性。那麼 Redis 的事務呢? Redis 的事務擁有隔離性,但是不包證原子性。並且其沒有隔離級別的概念,也就是說它不像 mysql 中執行了操作,但是因為隔離級別的影響而導致 " 操作未執行 " 的假象。

基本操作

開啟事務:multi;

提交事務:exec;

放棄事務:discard;

事務執行的流程是 " 開啟事務--->操作入隊---->提交事務執行所有操作",下面的截圖就是典型的事務執行過程

如果在提交之前想中斷此次事務,可以通過 "discard" 來取消當前事務。 

 

特點

1、隔離性:事務的執行不會被其他客戶端的操作打斷。

2、不保證原子性:如果事務中的某一條操作執行失敗,那麼其不會影響該事務中的其他操作。

3、在事務提交時,如果某個操作有異常(操作本身的格式有問題,在入隊時就報錯,也就是編譯異常),那麼這個事務在提交後不會生效,內部的所有操作都不會生效。如下圖。

 

4、在事務提交時,如果某個操作在入隊時沒有異常,在提交時發生異常,那麼這個操作不會影響其他操作的執行。

 

除此之外,Redis 還可以通過 "watch  key" 來對指定的資料設定樂觀鎖,此後如果其他會話對該資料操作後,當前會話執行的事務就會被中斷。

 

Redis 的釋出訂閱

雖然這模組功能一般是由訊息佇列來實現,但是如果是簡單的 "釋出-訂閱" 操作如果 redis 也是可以實現的。

相關操作

1、訂閱一個或多個:SUBSCRIBE  訂閱名1  訂閱名2 ...

2、訊息釋出: PUBLISH  訂閱名   訊息內容

  實現如下:

 

 

3、訂閱萬用字元: PUBLISH  萬用字元*

  實現如下:

 

SpringBoot 中的使用

在 springboot2.0 之前,底層預設使用的是 jedis,而 2.0 以後變成了 lettuce,這是因為 jedis 採用的是直連,當多個執行緒操作時,是不安全的。此時可以通過 jedis 的連線池來避免執行緒不安全,但是在執行時還是會比較慢。而 lettuce 底層使用的是 netty,例項可以在多個執行緒中共享,不會發生執行緒不安全的情況。

亂碼問題

在使用 redisTemplate 將資料存入 redis 後往往會發現在 redis 客戶端中讀取會亂碼,這是為什麼?

redis 內部維護的 redisTemplate 底層使用的是 JDK 序列化器,在 redis 中以二進位制形式儲存,所以我們在客戶端直接讀取的是二進位制資料,相關原始碼可以看下面程式碼

// RedisAutoConfiguration.class
    
    @Bean
    @ConditionalOnMissingBean(name = "redisTemplate")
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }   


// RedisTemplate.class
public void afterPropertiesSet() { super.afterPropertiesSet(); boolean defaultUsed = false; if (this.defaultSerializer == null) { this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader()); } if (this.enableDefaultSerializer) { if (this.keySerializer == null) { this.keySerializer = this.defaultSerializer; defaultUsed = true; } if (this.valueSerializer == null) { this.valueSerializer = this.defaultSerializer; defaultUsed = true; } if (this.hashKeySerializer == null) { this.hashKeySerializer = this.defaultSerializer; defaultUsed = true; } if (this.hashValueSerializer == null) { this.hashValueSerializer = this.defaultSerializer; defaultUsed = true; } } ... }

關於 redis 的序列化器有以下幾種:

我們著重看一下常用的幾種:

1、JdkSerializationRedisSerializer。RedisTemplate預設的序列化器,儲存的物件必須實現Serializable介面,不需要指定物件型別資訊,在redis中以二進位制格式來儲存,不可讀,且轉化後的二進位制資料往往比json資料要大。

2、StringRedisSerializer。已String型別進行儲存,不需要指定,不需要實現Serializable介面

3、Jackson2JsonRedisSerializer。需要指定序列化物件的型別,不需要實現Serializable介面

4、GenericJackson2JsonRedisSerializer。不需要指定序列化物件型別。不需要實現Serializable介面,與 Jackson2JsonRedisSerializer 區別是其儲存的物件資料雖然也是 Json 格式的,但是會顯示儲存物件的型別,以及元素物件所在的類路徑。具體可以百度。

redisTemplate 預設 key 與 value 使用的都是 JDK 序列化器,我們自定義一個 redisTemplate 元件來代替預設的,key 可以使用 String 序列化器,value 使用 Jackson2 序列化器。程式碼如下:

@Configuration
public class RedisConfig {

    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(factory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        // key採用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也採用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式採用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式採用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();

        return template;
    }
}

同時如果要儲存的資料就是字串型別的,那麼也可以直接使用 redisTemplate,其 key 與 value 都是使用 String 序列化器。

 

常用方法

redisTemplate.opsForValue();//操作字串
redisTemplate.opsForHash();//操作hash
redisTemplate.opsForList();//操作list
redisTemplate.opsForSet();//操作set
redisTemplate.opsForZSet();//操作有序set
 
redistempalate.boundValueOps;
redistempalate.boundSetOps;
redistempalate.boundListOps;
redistempalate.boundHashOps;
redistempalate.boundZSetOps;
//兩者區別:ops就相當於建立一個operator,前者是通過一個operator來執行各個資料型別的操作,後者是選中資料型別再為這個型別來建立一個operator,
//也就是前者是一個operator執行多種資料,後者是一個operator操作一種資料



// 通過 connection 物件來執行資料庫相關的操作
RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
connection.flushDb();  
connection.flushAll();

 

相關文章