天天看點

Redis-初見

目錄

  • 啟動and連接配接
  • JRedis
  • 寶塔
  • Redis.conf
  • RDB
  • AOF(Append Only File)
  • 釋出和訂閱
  • 主從複制
  • 一主二從
  • 複制原理
  • 當機後的手動配置主機
  • 哨兵模式
  • Redis 緩存 穿透 和 雪崩(面試高頻,工作常用)
    • 緩存穿透
    • 緩存雪崩
    • 緩存擊穿(量太大了,緩存過期)

啟動 用的是配置檔案啟動

redis-server .../redis.conf

redis-cli -p 6379

[root@LJT redis]# redis-server redis.conf      [root@LJT redis]# redis-cli -p 6379      127.0.0.1:6379> exit     [root@LJT redis]# pwd     /www/server/redis     用的是寶塔,預設在www使用者下           

關機

SHUTDOWN

<dependency>           <groupId>redis.clients</groupId>           <artifactId>jedis</artifactId>           <version>3.2.0</version>     </dependency>           

我用的aliyun的www 寶塔的 redis 位置

cd /www/server/redis

機關     配置檔案對大小寫不敏感     # 1k => 1000 bytes     # 1kb => 1024 bytes     # 1m => 1000000 bytes     # 1mb => 1024*1024 bytes     # 1g => 1000000000 bytes     # 1gb => 1024*1024*1024 bytes     …………     包含     # include /path/to/local.conf     # include /path/to/other.conf     …………     bind 127.0.0.1		綁定的ip     protected-mode yes		保護模式     port 6379		端口     ################################# GENERAL #####################################     daemonize yes		守護程序方式運作,預設no     pidfile /www/server/redis/redis.pid		如果以背景方式運作,要指定pid     # Specify the server verbosity level.     # This can be one of:     # debug (a lot of information, useful for development/testing)     # verbose (many rarely useful info, but not a mess like the debug level)     # notice (moderately verbose, what you want in production probably)預設,生産環境     # warning (only very important / critical messages are logged)     loglevel notice     logfile "/www/server/redis/redis.log"		位置     # dbid is a number between 0 and 'databases'-1     databases 16		預設16個資料庫     持久化,redis是記憶體資料庫,斷電即失     save 900 1		如果900s内至少有一個key修改,進行持久化操作     save 300 10     save 60 10000     stop-writes-on-bgsave-error yes		持久化出錯,是否繼續工作     rdbcompression yes		是否壓縮 rdb 檔案,要消耗一定的cpu資源     rdbchecksum yes		儲存 rdb 檔案 是否要校驗     dbfilename dump.rdb		rdb 檔案儲存目錄     ################################# REPLICATION #################################     ################################# SECURITY #################################     # requirepass foobared		設定密碼     ################################### CLIENTS ####################################     # maxclients 10000		最大的連接配接數     ############################## MEMORY MANAGEMENT################################     # maxmemory <bytes>		最大的容量     # maxmemory-policy noeviction		記憶體滿了怎麼處理     ############################## APPEND ONLY MODE ###############################     aof的配置     appendonly no		預設不開啟,預設rdb夠用了     appendfilename "appendonly.aof"			持久化的檔案的名字     # appendfsync always		每次都要  sync     appendfsync everysec		每秒執行一次  sync  可能會丢失一秒的資料     # appendfsync no			不執行,作業系統自己同步資料           

Redis DataBase redis 的持久化

Redis-初見

儲存的是dump.rdb

持久化,redis是記憶體資料庫,斷電即失     save 900 1		如果900s内至少有一個key修改,進行持久化操作     save 300 10     save 60 10000     stop-writes-on-bgsave-error yes		持久化出錯,是否繼續工作     rdbcompression yes		是否壓縮 rdb 檔案,要消耗一定的cpu資源     rdbchecksum yes		儲存 rdb 檔案 是否要校驗     dbfilename dump.rdb		rdb 檔案儲存目錄           
  1. save規則滿足了 就自動的執行了
  2. 執行flushall
  3. 退出redis

這個時候是會有 dump.rdb。

怎麼恢複RDB檔案?

隻要放到redis的啟動目錄就可以了,redis會自動檢查。

優點:

  1. 适合大規模的資料恢複
  2. 對資料的完整性要求不高

缺點:

  1. 需要一定的時間間隔
  2. fork的時候會占用一定的記憶體空間

将我們的所有的操作記錄下來。

Redis-初見

以日志的形式來記錄每個寫操作,将Redis執行過的所有指令記錄下來(讀操作不記錄) , 隻許追加檔案但不可以改寫檔案, redis啟動之初會讀取該檔案重新建構資料,換言之, redis重新開機的話就根據日志檔案的内容将寫指令從前到後執行一次以完成資料的恢複。

Aof儲存的是appendonly.aof檔案

############################## APPEND ONLY MODE ###############################     aof的配置     appendonly no		預設不開啟,預設rdb夠用了,這裡改為yes就是開啟了,重新開機redis就生效了     appendfilename "appendonly.aof"			持久化的檔案的名字     # appendfsync always		每次都要  sync     appendfsync everysec		每秒執行一次  sync  可能會丢失一秒的資料     # appendfsync no			不執行,作業系統自己同步資料           

vim 這個 appendonly.aof 檔案,就可以看到自己的所有的操作

以日志級别記錄我們的所有的寫操作。

redis -check-aof

這個是會檢查你的 appendonly.aof 。

redis -check-aof  --fix appendonly.aof           

可以用

ps -ef|grep redis           

看自己的reids是否開啟了。

按照預設的配置,如果aof的檔案大于64m,太大了,redis 會 fork 一個新的程序将我們的檔案進行重寫。

aof 預設的就是檔案的無限追加。

優點

  1. 每一次的修改都同步,檔案的完整性會更好
  2. 每秒同步一個,可能會丢失最後一秒的資料
  3. 從不同步,效率最高

缺點

  1. 相對于資料檔案來說,aof 遠大于 rdb,會很慢,運作效率也更低

擴充:

RDB 持久化可以在指定的時間間隔内生成資料集的時間點快照(point-in-time snapshot)。

AOF 持久化記錄伺服器執行的所有寫操作指令,并在伺服器啟動時,通過重新執行這些指令來還原資料集。

AOF 檔案中的指令全部以 Redis 協定的格式來儲存,新指令會被追加到檔案的末尾。

Redis 還可以在背景對 AOF 檔案進行重寫(rewrite),使得 AOF 檔案的體積不會超出儲存資料集狀态所需的實際大小。

Redis 還可以同時使用 AOF 持久化和 RDB 持久化。

在這種情況下, 當 Redis 重新開機時, 它會優先使用 AOF 檔案來還原資料集, 因為 AOF 檔案儲存的資料集通常比 RDB 檔案所儲存的資料集更完整。你甚至可以關閉持久化功能,讓資料隻在伺服器運作時存在。

通信 隊列 發送者 ======== 訂閱者

redis也是一種消息通信模式

redis可以訂閱任意數量的頻道

Redis-初見

操作例子:

127.0.0.1:6379> SUBSCRIBE zwtjava     Reading messages... (press Ctrl-C to quit)     1) "subscribe"     2) "zwtjava"     3) (integer) 1     1) "message"     2) "zwtjava"     3) "hello zwt"     1) "message"     2) "zwtjava"     3) "hello redis"           
127.0.0.1:6379> PUBLISH zwtjava "hello zwt"     (integer) 1     127.0.0.1:6379> PUBLISH zwtjava "hello redis"     (integer) 1     127.0.0.1:6379>           

Redis-初見

概念

主從複制,是指将一台Redis伺服器的資料,複制到其他的Redis伺服器。

前者稱為主節點(Master/Leader),後者稱為從節點(Slave/Follower), 資料的複制是單向的!隻能由主節點複制到從節點(主節點以寫為主、從節點以讀為主)。

預設情況下,每台Redis伺服器都是主節點,一個主節點可以有0個或者多個從節點,但每個從節點隻能由一個主節點。

作用

  1. 資料備援:主從複制實作了資料的熱備份,是持久化之外的一種資料備援的方式。
  2. 故障恢複:當主節點故障時,從節點可以暫時替代主節點提供服務,是一種服務備援的方式
  3. 負載均衡:在主從複制的基礎上,配合讀寫分離,由主節點進行寫操作,從節點進行讀操作,分擔伺服器的負載;尤其是在多讀少寫的場景下,通過多個從節點分擔負載,提高并發量。
  4. 高可用基石:主從複制還是哨兵和叢集能夠實施的基礎。

為什麼使用叢集?

  1. 單台伺服器難以負載大量的請求
  2. 單台伺服器故障率高,系統崩壞機率大
  3. 單台伺服器記憶體容量有限

檢視目前庫的資訊:

[root@LJT redis]# redis-server redis.conf      [root@LJT redis]# redis-cli -p 6379     127.0.0.1:6379> info replication     # Replication     role:master     connected_slaves:0     master_failover_state:no-failover     master_replid:cf011df27ae3fb7062185a64f1a1b6f660d61b10     master_replid2:0000000000000000000000000000000000000000     master_repl_offset:0     second_repl_offset:-1     repl_backlog_active:0     repl_backlog_size:1048576     repl_backlog_first_byte_offset:0     repl_backlog_histlen:0           

配置僞叢集:

複制配置檔案

[root@LJT redis]# cp redis.conf redis79.conf     [root@LJT redis]# cp redis.conf redis80.conf     [root@LJT redis]# cp redis.conf redis81.conf     [root@LJT redis]# ll     total 436     -rw-rw-r--  1 redis redis 28118 Jun  1 22:03 00-RELEASENOTES     -rw-rw-r--  1 redis redis    51 Jun  1 22:03 BUGS     -rw-rw-r--  1 redis redis  5026 Jun  1 22:03 CONDUCT     -rw-rw-r--  1 redis redis  3384 Jun  1 22:03 CONTRIBUTING     -rw-rw-r--  1 redis redis  1487 Jun  1 22:03 COPYING     drwxrwxr-x  7 redis redis  4096 Jul 12 10:40 deps     -rw-r--r--  1 root  root    104 Jul 21 16:30 dump.rdb     -rw-rw-r--  1 redis redis    11 Jun  1 22:03 INSTALL     -rw-rw-r--  1 redis redis   151 Jun  1 22:03 Makefile     -rw-rw-r--  1 redis redis  6888 Jun  1 22:03 MANIFESTO     -rw-rw-r--  1 redis redis 21567 Jun  1 22:03 README.md     -rw-r--r--  1 root  root  61859 Jul 21 16:32 redis79.conf     -rw-r--r--  1 root  root  61859 Jul 21 16:32 redis80.conf     -rw-r--r--  1 root  root  61859 Jul 21 16:32 redis81.conf     -rw-rw-r--  1 redis redis 61859 Jul 21 10:50 redis.conf     -rw-r--r--  1 redis redis 15057 Jul 21 16:30 redis.log     -rwxrwxr-x  1 redis redis   275 Jun  1 22:03 runtest     -rwxrwxr-x  1 redis redis   279 Jun  1 22:03 runtest-cluster     -rwxrwxr-x  1 redis redis  1046 Jun  1 22:03 runtest-moduleapi     -rwxrwxr-x  1 redis redis   281 Jun  1 22:03 runtest-sentinel     -rw-rw-r--  1 redis redis 13768 Jun  1 22:03 sentinel.conf     drwxrwxr-x  3 redis redis 12288 Jul 12 17:32 src     -rw-r--r--  1 root  root      5 Jul 12 10:42 start.pl     drwxrwxr-x 11 redis redis  4096 Jun  1 22:03 tests     -rw-rw-r--  1 redis redis  3055 Jun  1 22:03 TLS.md     drwxrwxr-x  9 redis redis  4096 Jun  1 22:03 utils     -rw-r--r--  1 root  root      5 Jul 12 10:45 version_check.pl     -rw-r--r--  1 root  root      6 Jul 12 10:42 version.pl     [root@LJT redis]#           

修改對應的配置檔案

-rw-r--r--  1 root  root  61859 Jul 21 16:32 redis80.conf     port 6380     daemonize yes		開啟服務     logfile "/www/server/redis/redis80.log"     dbfilename dump80.rdb     大概就是這樣幾個地方           

連接配接三台主機,都是master,預設都是master,我們一般隻用配置從機就可以。

主(79)從(80,81)

127.0.0.1:6379> info replication     # Replication     role:master     connected_slaves:2     slave0:ip=127.0.0.1,port=6380,state=online,offset=42,lag=1     slave1:ip=127.0.0.1,port=6381,state=online,offset=42,lag=1     master_failover_state:no-failover     master_replid:4c97ee0b19fef1a3f8e4f2f97ec15b20c01d61b1     master_replid2:0000000000000000000000000000000000000000     master_repl_offset:42     second_repl_offset:-1     repl_backlog_active:1     repl_backlog_size:1048576     repl_backlog_first_byte_offset:1     repl_backlog_histlen:42     127.0.0.1:6379>           

SLAVEOF 127.0.0.1 6379

通過這個指令配置主從關系

127.0.0.1:6380> SLAVEOF 127.0.0.1 6379     OK     127.0.0.1:6380> info replication     # Replication     role:slave     master_host:127.0.0.1     master_port:6379     master_link_status:up     master_last_io_seconds_ago:5     master_sync_in_progress:0     slave_repl_offset:0     slave_priority:100     slave_read_only:1     replica_announced:1     connected_slaves:0     master_failover_state:no-failover     master_replid:4c97ee0b19fef1a3f8e4f2f97ec15b20c01d61b1     master_replid2:0000000000000000000000000000000000000000     master_repl_offset:0     second_repl_offset:-1     repl_backlog_active:1     repl_backlog_size:1048576     repl_backlog_first_byte_offset:1     repl_backlog_histlen:0     127.0.0.1:6380>           

這是用的指令實作的,不是永久的,永久的需要再配置檔案裡面實作,

配置中實作這個即可。

# replicaof <masterip> <masterport>     # masterauth <master-password>           

細節了解:

主機可以寫,從機不能寫隻能讀!主機中的所有資訊和資料,都會自動被從機儲存!

127.0.0.1:6379> set k1 v1     OK     127.0.0.1:6379> get k1     "v1"     127.0.0.1:6379>      127.0.0.1:6380> get k1     "v1"     127.0.0.1:6380>     127.0.0.1:6380> set k2 v2     (error) READONLY You can't write against a read only replica.           

測試:主機斷開,從機依舊連接配接,但是沒有寫操作。

​ 主機回來,恢複。

​ 從機斷了,主機的寫操作ok,從機回來,不可以拿到掉線的值。

通過測試管觀察原理:

Slave啟動成功連接配接到master後會發送一個sync指令     Master接到指令,啟動背景的存盤程序,同時收集所有接收到的用于修改資料集指令,在背景程序執行完畢之後, master将傳送整個資料檔案到slave ,并完成一次完全同步。     全量複制:而slave服務在接收到資料庫檔案資料後,将其存盤并加載到記憶體中。     增量複制: Master繼續将新的所有收集到的修改指令依次傳給slave ,完成同步     但是隻要是重新連接配接master , 一次完全同步(全量複制)将被自動執行。           

主節點斷開,info replication

127.0.0.1:6380> SLAVEOF no one      OK     127.0.0.1:6380> info replication     # Replication     role:master     connected_slaves:0     master_failover_state:no-failover     master_replid:7fc61819c4dd84b2476cc55cf827ab854177bdbf     master_replid2:4c97ee0b19fef1a3f8e4f2f97ec15b20c01d61b1     master_repl_offset:3538     second_repl_offset:3539     repl_backlog_active:1     repl_backlog_size:1048576     repl_backlog_first_byte_offset:1     repl_backlog_histlen:3538     127.0.0.1:6380>           

如果這個時候主機ok了,回來了,需要再配置。

自動版的“選老大“。

主從切換技術的方法是:

當主伺服器當機後,需要手動把一台從伺服器切換為主伺服器,這就需要人工幹預,費事費力,還會造成一段時間内服務不可用。

這不是一種推薦的方式,更多時候,我們優先考慮哨兵模式。

Redis從2.8開始正式提供 了Sentinel (哨兵)架構來解決這個問題。

謀朝篡位的自動版,能夠背景監控主機是否故障,如果故障了根據投票數自動将從庫轉換為主庫。

哨兵模式是一種特殊的模式,首先Redis提供了哨兵的指令,哨兵是一個獨立的程序,作為程序,它會獨立運作。

其原理是哨兵通過發送指令,等待Redis伺服器響應,進而監控運作的多個Redis執行個體。

Redis-初見

然而一個哨兵程序對Redis伺服器進行監控,可能會出現問題,為此,我們可以使用多個哨兵進行監控。

各個哨兵之間還會進行監控,這樣就形成了多哨兵模式。

Redis-初見

假設主伺服器當機,哨兵1先檢測到這個結果,系統并不會馬上進行failover過程,僅僅是哨兵1主觀的認為主伺服器不可用,這個現象成為主觀下線。

當後面的哨兵也檢測到主伺服器不可用,并且數量達到一定值時,那麼哨兵之間就會進行一次投票 ,投票的結果由一個哨兵發起,進行failover[故障轉移]操作。

切換成功後,就會通過釋出訂閱模式,讓各個哨兵把自己監控的從伺服器實作切換主機,這個過程稱為客觀下線。

測試:

目前是一主二從。

配置哨兵檔案

sentinel monitor mymaster 127.0.0.1 6379 1           

後面的這個數字1 ,代表主機挂了,slave投票看讓誰接替成為主機,票數最多的就會成為主機!

啟動哨兵

[root@LJT redis]# redis-sentinel sentinel79.conf      20183:X 21 Jul 2021 22:41:55.113 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo     20183:X 21 Jul 2021 22:41:55.113 # Redis version=6.2.4, bits=64, commit=00000000, modified=0, pid=20183, just started     20183:X 21 Jul 2021 22:41:55.113 # Configuration loaded     20183:X 21 Jul 2021 22:41:55.114 * monotonic clock: POSIX clock_gettime                     _._                                                                  _.-``__ ''-._                                                        _.-``    `.  `_.  ''-._           Redis 6.2.4 (00000000/0) 64 bit       .-`` .-```.  ```\/    _.,_ ''-._                                        (    '      ,       .-`  | `,    )     Running in sentinel mode      |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379      |    `-._   `._    /     _.-'    |     PID: 20183       `-._    `-._  `-./  _.-'    _.-'                                         |`-._`-._    `-.__.-'    _.-'_.-'|                                        |    `-._`-._        _.-'_.-'    |           https://redis.io              `-._    `-._`-.__.-'_.-'    _.-'                                         |`-._`-._    `-.__.-'    _.-'_.-'|                                        |    `-._`-._        _.-'_.-'    |                                         `-._    `-._`-.__.-'_.-'    _.-'                                              `-._    `-.__.-'    _.-'                                                      `-._        _.-'                                                              `-.__.-'                                                    20183:X 21 Jul 2021 22:41:55.120 # Sentinel ID is 236bea779a3b0737574dc5022c37d17d825b0ccb     20183:X 21 Jul 2021 22:41:55.120 # +monitor master mymaster 127.0.0.1 6379      quorum 1		#有一票      #它的倆個從節點     20183:X 21 Jul 2021 22:41:55.120 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379     20183:X 21 Jul 2021 22:41:55.125 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379     #關閉主節點後的日志		failover		selected     20183:X 21 Jul 2021 22:42:49.558 # +sdown master mymaster 127.0.0.1 6379     20183:X 21 Jul 2021 22:42:49.558 # +odown master mymaster 127.0.0.1 6379 #quorum 1/1     20183:X 21 Jul 2021 22:42:49.558 # +new-epoch 1     20183:X 21 Jul 2021 22:42:49.558 # +try-failover master mymaster 127.0.0.1 6379     20183:X 21 Jul 2021 22:42:49.565 # +vote-for-leader 236bea779a3b0737574dc5022c37d17d825b0ccb 1     20183:X 21 Jul 2021 22:42:49.565 # +elected-leader master mymaster 127.0.0.1 6379     20183:X 21 Jul 2021 22:42:49.565 # +failover-state-select-slave master mymaster 127.0.0.1 6379     20183:X 21 Jul 2021 22:42:49.637 # +selected-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379     20183:X 21 Jul 2021 22:42:49.637 * +failover-state-send-slaveof-noone slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379     20183:X 21 Jul 2021 22:42:49.720 * +failover-state-wait-promotion slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379     20183:X 21 Jul 2021 22:42:50.053 # +promoted-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379     20183:X 21 Jul 2021 22:42:50.053 # +failover-state-reconf-slaves master mymaster 127.0.0.1 6379     20183:X 21 Jul 2021 22:42:50.113 * +slave-reconf-sent slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379     20183:X 21 Jul 2021 22:42:51.102 * +slave-reconf-inprog slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379     20183:X 21 Jul 2021 22:42:51.102 * +slave-reconf-done slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379     20183:X 21 Jul 2021 22:42:51.157 # +failover-end master mymaster 127.0.0.1 6379     20183:X 21 Jul 2021 22:42:51.157 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6380     20183:X 21 Jul 2021 22:42:51.158 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380     20183:X 21 Jul 2021 22:42:51.158 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380     20183:X 21 Jul 2021 22:43:21.239 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380     #再測試,果然 master 是 6380     127.0.0.1:6380> info replication     # Replication     role:master     connected_slaves:1     slave0:ip=127.0.0.1,port=6381,state=online,offset=9076,lag=0     master_failover_state:no-failover     master_replid:6d563979b4c421fde3bc7a8996b88d2f02f060ee     master_replid2:1645d3e978dea3fea45f2f5219077322693e61a3     master_repl_offset:9076     second_repl_offset:1585     repl_backlog_active:1     repl_backlog_size:1048576     repl_backlog_first_byte_offset:1     repl_backlog_histlen:9076     127.0.0.1:6380>      #6379再次上線     20183:X 21 Jul 2021 22:42:51.157 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6380     20183:X 21 Jul 2021 22:42:51.158 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380     20183:X 21 Jul 2021 22:42:51.158 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380     20183:X 21 Jul 2021 22:43:21.239 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380     20183:X 21 Jul 2021 22:47:03.632 # -sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380     20183:X 21 Jul 2021 22:47:13.578 * +convert-to-slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380     #發現現在沒有用,還是6380統治天下           

**

優點:**

1、哨兵叢集,基于主從複制模式,所有的主從配置優點,它全有

2、主從可以切換,故障可以轉移,系統的可用性就會更好

3、哨兵模式就是主從模式的更新,手動到自動,更加健壯!

缺點:

1、Redis 不好啊線上擴容的,叢集容量- -旦到達上限,線上擴容就十分麻煩!

2、實作哨兵模式的配置其實是很麻煩的,裡面有很多選擇!

Redis緩存的使用,極大的提升了應用程式的性能和效率,特别是資料查詢方面。

但同時,它也帶來了一些問題。

其中,最要害的問題,就是資料的一緻性問題,從嚴格意義上講,這個問題無解。

如果對資料的一緻性要求很高,那麼就不能使用緩存。

另外的一些典型問題就是,緩存穿透、緩存雪崩和緩存擊穿。

Redis-初見

緩存穿透的概念很簡單,使用者想要查詢一個資料發現redis記憶體資料庫沒有,

也就是緩存沒有命中,于是向持久層資料庫查詢。

發現也沒有,于是本次查詢失敗。當使用者很多的時候,緩存都沒有命中,于是都去請求了持久層資料庫。

這會給持久層資料庫造成很大的壓力,這時候就相當于出現了緩存穿透。

解決方案

布隆過濾器

是一種資料結構,對所有可能查詢的參數以hash形式存儲,在控制層先進行校驗,不符合則丢棄,進而避免了對底層存儲系統的查詢壓力。

Redis-初見

緩存空對象

當存儲層不命中後,即使傳回的空對象也将其緩存起來,同時會設定一個過期時間,之後再通路這個資料将會從緩存中擷取,保護後端資料源。

Redis-初見

但是這種方法會存在兩個問題:

1、如果空值能夠被緩存起來,這就意味着緩存需要更多的空間存儲更多的鍵,因為這當中可能會有很多的空值的鍵。

2、即使對空值設定了過期時間,還是會存在緩存層和存儲層的資料會有一段時間視窗的不一緻,這對于需要保持一緻性的業務會有影響。

緩存雪崩,是指在某一一個時間段,緩存集中過期失效。

産生雪崩的原因之一,比如在寫本文的時候,馬上就要到雙十二零點,很快就會迎來-波搶購,這波商品時間比較集中的放入了緩存,假設緩存-個小時。那麼到了淩晨一點鐘的時候 ,這批商品的緩存就都過期了。而對這批商品的通路查詢,都落到了資料庫上,對于資料庫而言,就會産生周期性的壓力波峰。于是所有的請求都會達到存儲層,存儲層的調用量會暴增,造成存儲層也會挂掉的情況。

Redis-初見

redis高可用

這個思想的含義是,既然redis有可能挂掉,那我多增設幾台redis ,這樣一台挂掉之 後其他的還可以繼續工作,其實就是搭建的叢集。(異地多活! )

限流降級

這個解決方案的思想是,在緩存失效後,通過加鎖或者隊列來控制讀資料庫寫緩存的線程數量。比如對某個key隻允許一個線程查詢資料和寫緩存,其他線程等待。

資料預熱

資料加熱的含義就是在正式部署之前,我先把可能的資料先預先通路一遍,這樣部分可能大量通路的資料就會加載到緩存中。

在即将發生大并發通路前手動觸發加載緩存不同的key ,設定不同的過期時間,讓緩存失效的時間點盡量均勻。

例如:微網誌熱搜

設定熱點不過期

加互斥鎖