天天看點

CentOS Redis高可用ClusterRedis高可用Cluster

Redis高可用Cluster

什麼是Redis Cluster

1)Redis叢集是一個可以在多個Redis主從複制節點之間進行資料共享的設施(installation)

2)Redis叢集不支援那些需要同時處理多個鍵的Redis指令,因為執行這些指令需要在多個Redis節點之間移動資料,并且在高負載的情況下,這些指令将降低Redis叢集的性能,并導緻不可預測的行為。

3)Redis叢集通過分區(partition)來提供一定程度的可用性(availability):即使叢集中有一部分節點失效或者無法進行通訊,叢集也可以繼續處理指令請求。

4)Redis叢集有将資料自動切分(split)到多個節點的能力。

redis Cluster特性

高性能

1.在多酚片節點中,将16384個槽位,均勻分布到多個分片節點中

2.存資料時,将key做crc16(key),然後和16384進行取模,得出槽位值(0-16384之間)

3.根據計算得出的槽位值,找到相對應的分片節點的主節點,存儲到相應槽位上

4.如果用戶端當時連接配接的節點不是将來要存儲的分片節點,分片叢集會将用戶端連接配接切換至真正存儲節點進行資料存儲

高可用

在搭建叢集時,會為每一個分片的主節點,對應一個從節點,實作slaveof功能,同時當主節點down,實作類似于sentinel的自動failover的功能。

CentOS Redis高可用ClusterRedis高可用Cluster

redis cluster可以連接配接任意節點提供服務

CentOS Redis高可用ClusterRedis高可用Cluster

如圖所示,當我們用用戶端連接配接A分片時,如果按照資料的取模,我們想要通路的資料,不在A分片中,那麼叢集會自動将請求進行轉發。

redis cluster共享資料

Redis 叢集使用資料分片(sharding)而非一緻性哈希(consistency hashing)來實作: 一個 Redis 叢集包含 16384 個哈希槽(hash slot), 資料庫中的每個鍵都屬于這 16384 個哈希槽的其中一個, 叢集使用公式 CRC16(key) % 16384 來計算鍵 key 屬于哪個槽, 其中 CRC16(key) 語句用于計算鍵 key 的 CRC16 校驗和 。

1.節點 A 負責處理 0 号至 5500 号哈希槽。

2.節點 B 負責處理 5501 号至 11000 号哈希槽。

3.節點 C 負責處理 11001 号至 16384 号哈希槽。

CentOS Redis高可用ClusterRedis高可用Cluster

所有的redis節點彼此互聯(PING-PONG機制),内部使用二進制協定優化傳輸速度和帶寬.

節點的fail是通過叢集中超過半數的master節點檢測失效時才生效.

用戶端與redis節點直連,不需要中間proxy層.用戶端不需要連接配接叢集所有節點,連接配接叢集中任何一個可用節點即可

把所有的實體節點映射到[0-16383]slot上,cluster 負責維護node<->slot<->key

叢集如何做複制

為了使得叢集在一部分節點下線或者無法與叢集的大多數(majority)節點進行通訊的情況下, 仍然可以正常運作, Redis 叢集對節點使用了主從複制功能: 叢集中的每個節點都有 1 個至 N 個複制品(replica), 其中一個複制品為主節點(master), 而其餘的 N-1 個複制品為從節點(slave)。

在之前列舉的節點 A 、B 、C 的例子中, 如果節點 B 下線了, 那麼叢集将無法正常運作, 因為叢集找不到節點來處理 5501 号至 11000 号的哈希槽。

假如在建立叢集的時候(或者至少在節點 B 下線之前), 我們為主節點 B 添加了從節點 B1 , 那麼當主節點 B 下線的時候, 叢集就會将 B1 設定為新的主節點, 并讓它代替下線的主節點 B , 繼續處理 5501 号至 11000 号的哈希槽, 這樣叢集就不會因為主節點 B 的下線而無法正常運作了。

不過如果節點 B 和 B1 都下線的話, Redis 叢集還是會停止運作。

叢集的複制特性重用了 SLAVEOF 指令的代碼,是以叢集節點的複制行為和 SLAVEOF 指令的複制行為完全相同。

Rdis Cluster故障轉移

1)在叢集裡面,節點會對其他節點進行下線檢測。

2)當一個主節點下線時,叢集裡面的其他主節點負責對下線主節點進行故障移。

3)換句話說,叢集的節點內建了下線檢測和故障轉移等類似 Sentinel 的功能。

4)因為 Sentinel 是一個獨立運作的監控程式,而叢集的下線檢測和故障轉移等功能是內建在節點裡面的,它們的運作模式非常地不同,是以盡管這兩者的功能很相似,但叢集的實作沒有重用 Sentinel 的代碼。

redis cluster執行指令的兩種情況

1)指令發送到了正确的節點:指令要處理的鍵所在的槽正好是由接收指令的節點負責,那麼該節點執行指令,就像單機 Redis 伺服器一樣。

Redis Cluster部署(隻有redis5.0版本以上才可以實作)

環境準備

外網IP 内網IP 端口 安裝包
10.0.0.52 172.16.1.52 7000,7001 redis-3.2.12.tar.gz
10.0.0.53 172.16.1.53 7002,7003 redis-3.2.12.tar.gz
10.0.0.54 172.16.1.54 7004,7005 redis-3.2.12.tar.gz
## 安裝redis
[root@db02 ~]# wget wget https://download.redis.io/redis-stable.tar.gz
[root@db02 ~]# tar xf redis-stable.tar.gz
[root@db02 ~]# cd redis-stable/
[root@db02 redis-stable]# make
[root@db02 redis-stable]# make install

[root@db04 ~]# wget wget https://download.redis.io/redis-stable.tar.gz
[root@db04 ~]# tar xf redis-stable.tar.gz
[root@db04 ~]# cd redis-stable/
[root@db04 redis-stable]# make
[root@db04 redis-stable]# make install

## 建立redis多執行個體目錄
[root@db02 ~]# mkdir -p /data/{7000..7001}
[root@db03 ~]# mkdir -p /data/{7002..7003}
[root@db04 ~]# mkdir -p /data/{7004..7005}

## 編輯多執行個體配置檔案
[root@db02 ~]# vim /data/7000/redis.conf 
port 7000	# 端口
bind 127.0.0.1 10.0.0.52 172.16.1.52	# 本地ip
daemonize yes	# 放入背景
pidfile /data/7000/redis.pid	# pid檔案路徑
loglevel notice	# log的級别(notice)
logfile "/data/7000/redis.log"	# 日志檔案
dbfilename dump.rdb	# 備份的檔案名
dir /data/7000	# 存放備份檔案的目錄
protected-mode no	# 關閉安全模式
cluster-enabled yes	# 是否是叢集
cluster-config-file nodes.conf	# 叢集配置檔案
cluster-node-timeout 5000	# 叢集連接配接逾時時間
appendonly yes	# 資料持久化類型

[root@db02 ~]# vim /data/7001/redis.conf 
port 7001
bind 127.0.0.1 10.0.0.52 172.16.1.52
daemonize yes
pidfile /data/7001/redis.pid
loglevel notice
logfile "/data/7001/redis.log"
dbfilename dump.rdb
dir /data/7001
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

[root@db03 ~]# vim /data/7002/redis.conf 
port 7002
bind 127.0.0.1 10.0.0.53 172.16.1.53
daemonize yes
pidfile /data/7002/redis.pid
loglevel notice
logfile "/data/7002/redis.log"
dbfilename dump.rdb
dir /data/7002
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

[root@db03 ~]# vim /data/7003/redis.conf 
port 7003
bind 127.0.0.1 10.0.0.53 172.16.1.53
daemonize yes
pidfile /data/7003/redis.pid
loglevel notice
logfile "/data/7003/redis.log"
dbfilename dump.rdb
dir /data/7003
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

[root@db04 ~]# vim /data/7004/redis.conf 
port 7004
bind 127.0.0.1 10.0.0.54 172.16.1.54
daemonize yes
pidfile /data/7004/redis.pid
loglevel notice
logfile "/data/7004/redis.log"
dbfilename dump.rdb
dir /data/7004
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

[root@db04 ~]# vim /data/7005/redis.conf 
port 7005
bind 127.0.0.1 10.0.0.54 172.16.1.54
daemonize yes
pidfile /data/7005/redis.pid
loglevel notice
logfile "/data/7005/redis.log"
dbfilename dump.rdb
dir /data/7005
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

## 啟動redis
[root@db02 ~]# redis-server /data/7000/redis.conf 
[root@db02 ~]# redis-server /data/7001/redis.conf

[root@db03 ~]# redis-server /data/7002/redis.conf 
[root@db03 ~]# redis-server /data/7003/redis.conf

[root@db04 ~]# redis-server /data/7004/redis.conf 
[root@db04 ~]# redis-server /data/7005/redis.conf

## 安裝redis-cluster插件
# 1.安裝ruby環境
[root@db02 ~]# yum install ruby rubygems -y

# 2.更換gem源
[root@db02 ~]# gem source list
[root@db02 ~]# gem sources --remove https://rubygems.org/
https://rubygems.org/ removed from sources
[root@db02 ~]# gem sources -a http://mirrors.aliyun.com/rubygems/
source http://mirrors.aliyun.com/rubygems/ added to sources

[root@db03 ~]# gem source list
[root@db03 ~]# gem sources --remove https://rubygems.org/
https://rubygems.org/ removed from sources
[root@db03 ~]# gem sources -a http://mirrors.aliyun.com/rubygems/
source http://mirrors.aliyun.com/rubygems/ added to sources

[root@db04 ~]# gem source list
[root@db04 ~]# gem sources --remove https://rubygems.org/
https://rubygems.org/ removed from sources
[root@db04 ~]# gem sources -a http://mirrors.aliyun.com/rubygems/
source http://mirrors.aliyun.com/rubygems/ added to sources

# 3.安裝redis cluster插件
[root@db02 ~]# gem install redis -v 3.3.3
[root@db03 ~]# gem install redis -v 3.3.3
[root@db04 ~]# gem install redis -v 3.3.3

# 4.将節點加入叢集
[root@db02 ~]# redis-cli --cluster create 172.16.1.52:7000 172.16.1.52:7001 172.16.1.53:7002 172.16.1.53:7003 172.16.1.54:7004 172.16.1.54:7005 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.16.1.53:7003 to 172.16.1.52:7000
Adding replica 172.16.1.54:7005 to 172.16.1.53:7002
Adding replica 172.16.1.52:7001 to 172.16.1.54:7004
M: 5064156c03853f2281976fa2a70ebc28229eaf00 172.16.1.52:7000
   slots:[0-5460] (5461 slots) master
S: c2af01070a1ee3c64ba0a4ce5b5b40255d219aee 172.16.1.52:7001
   replicates 41a2c56c3a05e455806bcbf6f1355bbb386e8106
M: dad534b8587511a86dc166c2a2668c7880a1e678 172.16.1.53:7002
   slots:[5461-10922] (5462 slots) master
S: 594c72e3da1c272db32004a71c7c1a4728b38d18 172.16.1.53:7003
   replicates 5064156c03853f2281976fa2a70ebc28229eaf00
M: 41a2c56c3a05e455806bcbf6f1355bbb386e8106 172.16.1.54:7004
   slots:[10923-16383] (5461 slots) master
S: 08ead59decf461e44e5d29b87a8f1ae41c42aedd 172.16.1.54:7005
   replicates dad534b8587511a86dc166c2a2668c7880a1e678
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.
>>> Performing Cluster Check (using node 172.16.1.52:7000)
M: 5064156c03853f2281976fa2a70ebc28229eaf00 172.16.1.52:7000
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: dad534b8587511a86dc166c2a2668c7880a1e678 172.16.1.53:7002
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: c2af01070a1ee3c64ba0a4ce5b5b40255d219aee 172.16.1.52:7001
   slots: (0 slots) slave
   replicates 41a2c56c3a05e455806bcbf6f1355bbb386e8106
S: 594c72e3da1c272db32004a71c7c1a4728b38d18 172.16.1.53:7003
   slots: (0 slots) slave
   replicates 5064156c03853f2281976fa2a70ebc28229eaf00
M: 41a2c56c3a05e455806bcbf6f1355bbb386e8106 172.16.1.54:7004
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 08ead59decf461e44e5d29b87a8f1ae41c42aedd 172.16.1.54:7005
   slots: (0 slots) slave
   replicates dad534b8587511a86dc166c2a2668c7880a1e678
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

## 檢視master和slave資訊
[root@db02 ~]# redis-cli -p 7000 cluster nodes
dad534b8587511a86dc166c2a2668c7880a1e678 172.16.1.53:7002@17002 master - 0 1663867162553 3 connected 5461-10922
c2af01070a1ee3c64ba0a4ce5b5b40255d219aee 172.16.1.52:7001@17001 slave 41a2c56c3a05e455806bcbf6f1355bbb386e8106 0 1663867163456 5 connected
594c72e3da1c272db32004a71c7c1a4728b38d18 172.16.1.53:7003@17003 slave 5064156c03853f2281976fa2a70ebc28229eaf00 0 1663867162451 1 connected
41a2c56c3a05e455806bcbf6f1355bbb386e8106 172.16.1.54:7004@17004 master - 0 1663867161000 5 connected 10923-16383
08ead59decf461e44e5d29b87a8f1ae41c42aedd 172.16.1.54:7005@17005 slave dad534b8587511a86dc166c2a2668c7880a1e678 0 1663867163000 3 connected
5064156c03853f2281976fa2a70ebc28229eaf00 172.16.1.52:7000@17000 myself,master - 0 1663867162000 1 connected 0-5460

## 連接配接叢集并set key
[root@db02 ~]# redis-cli -c -p 7000
127.0.0.1:7000> set name 'qqq'
-> Redirected to slot [5798] located at 172.16.1.53:7002
OK

[root@db03 ~]# redis-cli -c -p 7002
127.0.0.1:7002> keys *
1) "name"
127.0.0.1:7002> get name
"qqq"
           

Redis Cluster擴充叢集

## 準備兩台新節點
[root@db01 ~]# mkdir -p /data/{7006..7007}

[root@db01 ~]# vim /data/7006/redis.conf
port 7006
bind 10.0.0.51 172.16.1.51 127.0.0.1
daemonize yes
pidfile /data/7006/redis.pid
loglevel notice
logfile "/data/7006/redis.log"
dbfilename dump.rdb
dir /data/7006
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

[root@db01 ~]# vim /data/7007/redis.conf
port 7007
bind 10.0.0.51 172.16.1.51 127.0.0.1
daemonize yes
pidfile /data/7007/redis.pid
loglevel notice
logfile "/data/7007/redis.log"
dbfilename dump.rdb
dir /data/7007
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

# 安裝redis
[root@db01 ~]# wget wget https://download.redis.io/redis-stable.tar.gz
[root@db01 ~]# tar xf redis-stable.tar.gz
[root@db01 ~]# cd redis-stable/
[root@db01 redis-stable]# make
[root@db01 redis-stable]# make install

## 安裝redis-cluster插件
# 1.安裝ruby環境
[root@db01 ~]# yum install ruby rubygems -y

# 2.更換gem源
[root@db01 ~]# gem source list
*** CURRENT SOURCES ***
https://rubygems.org/
[root@db01 ~]# gem sources --remove https://rubygems.org/
https://rubygems.org/ removed from sources
[root@db01 ~]# gem sources -a http://mirrors.aliyun.com/rubygems/

# 3.安裝redis cluster插件
[root@db01 ~]# gem install redis -v 3.3.3

## 啟動redis
[root@db01 ~]# redis-server /data/7006/redis.conf
[root@db01 ~]# redis-server /data/7007/redis.conf

## 将新節點的7006端口加入叢集
[root@db01 ~]# redis-cli --cluster add-node 172.16.1.51:7006 172.16.1.52:7000
>>> Adding node 172.16.1.51:7006 to cluster 172.16.1.52:7000
>>> Performing Cluster Check (using node 172.16.1.52:7000)
M: 5064156c03853f2281976fa2a70ebc28229eaf00 172.16.1.52:7000
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: c2af01070a1ee3c64ba0a4ce5b5b40255d219aee 172.16.1.52:7001
   slots: (0 slots) slave
   replicates 41a2c56c3a05e455806bcbf6f1355bbb386e8106
S: dad534b8587511a86dc166c2a2668c7880a1e678 172.16.1.53:7002
   slots: (0 slots) slave
   replicates 08ead59decf461e44e5d29b87a8f1ae41c42aedd
M: 41a2c56c3a05e455806bcbf6f1355bbb386e8106 172.16.1.54:7004
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 594c72e3da1c272db32004a71c7c1a4728b38d18 172.16.1.53:7003
   slots: (0 slots) slave
   replicates 5064156c03853f2281976fa2a70ebc28229eaf00
M: 08ead59decf461e44e5d29b87a8f1ae41c42aedd 172.16.1.54:7005
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Getting functions from cluster
>>> Send FUNCTION LIST to 172.16.1.51:7006 to verify there is no functions in it
>>> Send FUNCTION RESTORE to 172.16.1.51:7006
>>> Send CLUSTER MEET to node 172.16.1.51:7006 to make it join the cluster.
[OK] New node added correctly.

## 檢視master和slave資訊
[root@db01 ~]# redis-cli -p 7006 cluster nodes
2572f478f7b82f9729302bf729502e390f73fb0f 172.16.1.51:7006@17006 myself,master - 0 1663873710000 0 connected
c2af01070a1ee3c64ba0a4ce5b5b40255d219aee 172.16.1.52:7001@17001 slave 41a2c56c3a05e455806bcbf6f1355bbb386e8106 0 1663873712000 5 connected
594c72e3da1c272db32004a71c7c1a4728b38d18 172.16.1.53:7003@17003 slave 5064156c03853f2281976fa2a70ebc28229eaf00 0 1663873712495 1 connected
41a2c56c3a05e455806bcbf6f1355bbb386e8106 172.16.1.54:7004@17004 master - 0 1663873712000 5 connected 10923-16383
5064156c03853f2281976fa2a70ebc28229eaf00 172.16.1.52:7000@17000 master - 0 1663873712000 1 connected 0-5460
dad534b8587511a86dc166c2a2668c7880a1e678 172.16.1.53:7002@17002 slave 08ead59decf461e44e5d29b87a8f1ae41c42aedd 0 1663873713000 7 connected
08ead59decf461e44e5d29b87a8f1ae41c42aedd 172.16.1.54:7005@17005 master - 0 1663873713506 7 connected 5461-10922

## 重新分片(重新規劃槽位)
[root@db01 ~]# redis-cli --cluster reshard 172.16.1.52:7000
# 你要分出多少個槽位
How many slots do you want to move (from 1 to 16384)? 2000
# 接收4096槽位的ID是什麼?
What is the receiving node ID? 2572f478f7b82f9729302bf729502e390f73fb0f
# 是不是全部接收
Please enter all the source node IDs.
  Type 'all' to use all the nodes as source nodes for the hash slots.
  Type 'done' once you entered all the source nodes IDs.
Source node #1: all
# 是按照上面的計劃執行
Do you want to proceed with the proposed reshard plan (yes/no)? yes

## 檢視master資訊
[root@db01 ~]# redis-cli -p 7006 cluster nodes| grep master
2572f478f7b82f9729302bf729502e390f73fb0f 172.16.1.51:7006@17006 myself,master - 0 1663874052000 8 connected 0-1364 5461-6826 10923-12287
41a2c56c3a05e455806bcbf6f1355bbb386e8106 172.16.1.54:7004@17004 master - 0 1663874052553 5 connected 12288-16383
5064156c03853f2281976fa2a70ebc28229eaf00 172.16.1.52:7000@17000 master - 0 1663874052858 1 connected 1365-5460
08ead59decf461e44e5d29b87a8f1ae41c42aedd 172.16.1.54:7005@17005 master - 0 1663874051339 7 connected 6827-10922

## 将7007從節點加入7006的主節點
[root@db01 ~]# redis-cli --cluster add-node --cluster-slave --cluster-master-id 2572f478f7b82f9729302bf729502e390f73fb0f 172.16.1.51:7007 172.16.1.51:7006

## 檢視slave資訊
[root@db01 ~]# redis-cli -p 7006 cluster nodes| grep slave
a5793ea280714f84f249ae703ee9b4b4ea887c8f 172.16.1.51:7007@17007 slave 2572f478f7b82f9729302bf729502e390f73fb0f 0 1663874419519 8 connected
c2af01070a1ee3c64ba0a4ce5b5b40255d219aee 172.16.1.52:7001@17001 slave 41a2c56c3a05e455806bcbf6f1355bbb386e8106 0 1663874420000 5 connected
594c72e3da1c272db32004a71c7c1a4728b38d18 172.16.1.53:7003@17003 slave 5064156c03853f2281976fa2a70ebc28229eaf00 0 1663874420717 1 connected
dad534b8587511a86dc166c2a2668c7880a1e678 172.16.1.53:7002@17002 slave 08ead59decf461e44e5d29b87a8f1ae41c42aedd 0 1663874418555 7 connected
           

Redis Cluster删除節點

## 重新分片
[root@db02 ~]# redis-cli --cluster reshard 127.0.0.1:7000

# 需要重新分片多少個slot
How many slots do you want to move (from 1 to 16384)? 200
# 誰來接收這些槽位7000
What is the receiving node ID? 5064156c03853f2281976fa2a70ebc28229eaf0
Please enter all the source node IDs.
  Type 'all' to use all the nodes as source nodes for the hash slots.
  Type 'done' once you entered all the source nodes IDs.
# 源節點:誰要給出這些槽位7006
Source node #1: 2572f478f7b82f9729302bf729502e390f73fb0f
# done結束
Source node #2: done

## 删除節點
[root@db02 ~]# redis-cli --cluster del-node 172.16.1.51:7006 2572f478f7b82f9729302bf729502e390f73fb0f

[root@db02 ~]# redis-cli --cluster del-node 172.16.1.51:7007 a5793ea280714f84f249ae703ee9b4b4ea887c8f
           

Redis存在的問題

緩存穿透

概念:
通路一個不存在的key,緩存不起作用,請求會穿透到DB,流量大時DB會挂掉。

解決方案:
采用布隆過濾器,使用一個足夠大的bitmap,用于存儲可能通路的key,不存在的key直接被過濾;
通路key未在DB查詢到值,也将空值寫進緩存,但可以設定較短過期時間。

緩存雪崩

概念:
大量的key設定了相同的過期時間,導緻在緩存在同一時刻全部失效,造成瞬時DB請求量大、壓力驟增,引起雪崩。

解決方案:
可以給緩存設定過期時間時加上一個随機值時間,使得每個key的過期時間分布開來,不會集中在同一時刻失效。

緩存擊穿

概念:
一個存在的key,在緩存過期的一刻,同時有大量的請求,這些請求都會擊穿到DB,造成瞬時DB請求量大、壓力驟增。

解決方案:
在通路key之前,采用SETNX(set if not exists)來設定另一個短期key來鎖住目前key的通路,通路結束再删除該短期key。
           

繼續閱讀