- Redis 是完全開源免費的,遵守BSD協定,是一個高性能的key-value資料庫。
- Redis 與其他 key - value 緩存産品有以下三個特點:
- Redis支援資料的持久化,可以将記憶體中的資料儲存在磁盤中,重新開機的時候可以再次加載進行使用。
- Redis不僅僅支援簡單的key-value類型的資料,同時還提供list,set,zset,hash等資料結構的存儲。
- Redis支援資料的備份,即master-slave模式的資料備份。
- redis優勢
- 性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
- 豐富的資料類型 – Redis支援二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 資料類型操作。
- 原子 – Redis的所有操作都是原子性的,意思就是要麼成功執行要麼失敗完全不執行。單個操作是原子性的。多個操作也支援事務,即原子性,通過MULTI和EXEC指令包起來。
- 豐富的特性 – Redis還支援 publish/subscribe, 通知, key 過期等等特性。
- Redis支援五種資料類型:string(字元串),hash(哈希),list(清單),set(集合)及zset(sorted set:有序集合)。
- string 是 redis 最基本的類型,你可以了解成與 Memcached 一模一樣的類型,一個 key 對應一個 value。string 類型是二進制安全的。意思是 redis 的 string 可以包含任何資料。比如jpg圖檔或者序列化的對象。string 類型是 Redis 最基本的資料類型,string 類型的值最大能存儲 512MB。
- select 0~15 指定資料庫
- redis keys指令:
- DEL key – 當key存在是删除key
- EXISTS key – 檢查給定key是否存在
- EXPIRE key seconds – 為給定key設定過期時間,以秒記
- PERSIST key – 移除key的過期時間,key将持久儲存
- TTL key – 以秒為機關,傳回給定 key 的剩餘生存時間(TTL, time to live)。
- RENAME key newkey – 修改key的名稱
- keys na* --模糊查詢key值
- redis字元串指令:
- SET key value – 設定指定 key 的值。
- GET key – 擷取指定 key 的值。
- GETRANGE key start end – 傳回 key 中字元串值的子字元。
- GETSET key value – 将給定 key 的值設為 value ,并傳回 key 的舊值(old value)。
- MGET key1 [key2…] – 擷取所有(一個或多個)給定 key 的值。
- SETNX key value – 隻有在 key 不存在時設定 key 的值。
- SETRANGE key offset value – 用 value 參數覆寫給定 key 所儲存的字元串值,從偏移量 offset 開始。
- MSET key value [key value …] – 同時設定一個或多個 key-value 對。
- MSETNX key value [key value …] – 同時設定一個或多個 key-value 對,當且僅當所有給定 key 都不存在。
- INCR key – 将 key 中儲存的數字值增一。
- INCRBY key increment – 将 key 所儲存的值加上給定的增量值(increment)。
- DECR key – 将 key 中儲存的數字值減一。
- INCRBYFLOAT key increment – 将 key 所儲存的值加上給定的浮點增量值(increment)。
- APPEND key value – 如果 key 已經存在并且是一個字元串, APPEND 指令将指定的 value 追加到該 key 原來值(value)的末尾。
- Redis hash : Redis hash 是一個string類型的field和value的映射表,hash特别适合用于存儲對象。Redis 中每個 hash 可以存儲 232 - 1 鍵值對(40多億)。
- Redis hash 指令:
- HSET key field value – 将哈希表 key 中的字段 field 的值設為 value 。
- HSETNX key field value – 隻有在字段 field 不存在時,設定哈希表字段的值。
- HMSET key field1 value1 [field2 value2 ] – 同時将多個 field-value (域-值)對設定到哈希表 key 中。
- HDEL key field1 [field2] – 删除一個或多個哈希表字段。
- HEXISTS key field – 檢視哈希表 key 中,指定的字段是否存在。
- HGET key field – 擷取存儲在哈希表中指定字段的值。
- HGETALL key – 擷取在哈希表中指定 key 的所有字段和值。
- HKEYS key – 擷取所有哈希表中的字段。
- HMGET key field1 [field2] – 擷取所有給定字段的值。
- HLEN key – 擷取哈希表中字段的數量。
- Redis 清單(List): Redis清單是簡單的字元串清單,按照插入順序排序。你可以添加一個元素到清單的頭部(左邊)或者尾部(右邊)。一個清單最多可以包含 232 - 1 個元素 (4294967295, 每個清單超過40億個元素)。
- Redis 清單指令
- LPUSH key value1 [value2] – 将一個或多個值插入到清單頭部
- RPUSH key value1 [value2] – 在清單中添加一個或多個值
- LPUSHX key value – 将一個值插入到已存在的清單頭部
- RPUSHX key value – 為已存在的清單添加值
- LINSERT key BEFORE|AFTER pivot value – 在清單的元素前或者後插入元素
- LINDEX key index – 通過索引擷取清單中的元素
- LLEN key – 擷取清單長度
- LRANGE key start stop – 擷取清單指定範圍内的元素
- LREM key count value – 移除清單元素
- RPOP key – 移除清單的最後一個元素,傳回值為移除的元素
- LPOP key – 移出并擷取清單的第一個元素
- RPOPLPUSH source destination – 移除清單的最後一個元素,并将該元素添加到另一個清單并傳回
- LSET key index value – 通過索引設定清單元素的值
- LTRIM key start stop – 對一個清單進行修剪(trim),就是說,讓清單隻保留指定區間内的元素,不在指定區間之内的元素都将被删除。
- Redis 集合(Set):Redis 的 Set 是 String 類型的無序集合。集合成員是唯一的,這就意味着集合中不能出現重複的資料。Redis 中集合是通過哈希表實作的,是以添加,删除,查找的複雜度都是 O(1)。集合中最大的成員數為 232 - 1 (4294967295, 每個集合可存儲40多億個成員)。
- redis集合指令
- SADD key member1 [member2] – 向集合添加一個或多個成員
- SCARD key – 擷取集合的成員數
- SDIFF key1 [key2] – 傳回給定所有集合的差集
- SDIFFSTORE destination key1 [key2] – 傳回給定所有集合的差集并存儲在 destination 中
- SINTER key1 [key2] – 傳回給定所有集合的交集
- SINTERSTORE destination key1 [key2] – 傳回給定所有集合的交集并存儲在 destination 中
- SISMEMBER key member – 判斷 member 元素是否是集合 key 的成員
- SMEMBERS key – 傳回集合中的所有成員
- SMOVE source destination member – 将 member 元素從 source 集合移動到 destination 集合
- SPOP key – 移除并傳回集合中的一個随機元素
- SRANDMEMBER key [count] – 傳回集合中一個或多個随機數
- SREM key member1 [member2] – 移除集合中一個或多個成員
- SUNION key1 [key2] – 傳回所有給定集合的并集
- SUNIONSTORE destination key1 [key2] – 所有給定集合的并集存儲在 destination 集合中
- SSCAN key cursor [MATCH pattern]-[ COUNT coun] – 疊代集合中的元素
- Redis 有序集合(sorted set):Redis 有序集合和集合一樣也是string類型元素的集合,且不允許重複的成員。不同的是每個元素都會關聯一個double類型的分數。redis正是通過分數來為集合中的成員進行從小到大的排序。有序集合的成員是唯一的,但分數(score)卻可以重複。集合是通過哈希表實作的,是以添加,删除,查找的複雜度都是O(1)。 集合中最大的成員數為 232 - 1 (4294967295, 每個集合可存儲40多億個成員)。
- Redis 有序集合指令:
- ZADD key score1 member1 [score2 member2] – 向有序集合添加一個或多個成員,或者更新已存在成員的分數
- ZCARD key – 擷取有序集合的成員數
- ZCOUNT key min max – 計算在有序集合中指定區間分數的成員數
- ZINCRBY key increment member – 有序集合中對指定成員的分數加上增量 increment
- ZINTERSTORE destination numkeys key [key …] – 計算給定的一個或多個有序集的交集并将結果集存儲在新的有序集合 key 中
- ZLEXCOUNT key min max – 在有序集合中計算指定字典區間内成員數量
- ZRANGE key start stop [WITHSCORES] – 通過索引區間傳回有序集合成指定區間内的成員
- ZRANGEBYLEX key min max [LIMIT offset count] – 通過字典區間傳回有序集合的成員
- ZRANK key member – 傳回有序集合中指定成員的索引
- ZREM key member [member …] – 移除有序集合中的一個或多個成員
- ZREMRANGEBYLEX key min max – 移除有序集合中給定的字典區間的所有成員
- ZREMRANGEBYRANK key start stop – 移除有序集合中給定的排名區間的所有成員
- ZREMRANGEBYSCORE key min max – 移除有序集合中給定的分數區間的所有成員
- ZSCORE key member – 傳回有序集中,成員的分數值
- ZUNIONSTORE destination numkeys key [key …] – 計算給定的一個或多個有序集的并集,并存儲在新的 key 中
- ZSCAN key cursor [MATCH pattern]-[ COUNT coun] – 疊代有序集合中的元素(包括元素成員和元素分值)
- flushdb 删除目前選擇的資料庫中所有的key
- flushall 删除所有資料庫中的所有key
- Redis HyperLogLog: Redis HyperLogLog 是用來做基數統計的算法,HyperLogLog 的優點是,在輸入元素的數量或者體積非常非常大時,計算基數所需的空間總是固定 的、并且是很小的。在 Redis 裡面,每個 HyperLogLog 鍵隻需要花費 12 KB 記憶體,就可以計算接近 2^64 個不同元素的基 數。這和計算基數時,元素越多耗費記憶體就越多的集合形成鮮明對比。但是,因為 HyperLogLog 隻會根據輸入元素來計算基數,而不會儲存輸入元素本身,是以 HyperLogLog 不能像集合那樣,傳回輸入的各個元素。
- 什麼是基數:比如資料集 {1, 3, 5, 7, 5, 7, 8}, 那麼這個資料集的基數集為 {1, 3, 5 ,7, 8}, 基數(不重複元素)為5。 基數估計就是在誤差可接受的範圍内,快速計算基數。
- Redis HyperLogLog 指令:
- PFADD key element [element …] – 添加指定元素到 HyperLogLog 中
- PFCOUNT key [key …] – 傳回給定 HyperLogLog 的基數估算值
- PFMERGE destkey sourcekey [sourcekey …] – 将多個 HyperLogLog 合并為一個 HyperLogLog
- Redis 釋出訂閱:Redis 釋出訂閱(pub/sub)是一種消息通信模式:發送者(pub)發送消息,訂閱者(sub)接收消息。Redis 用戶端可以訂閱任意數量的頻道。
- Redis 釋出訂閱指令:
- PSUBSCRIBE pattern [pattern …] – 訂閱一個或多個符合給定模式的頻道
- PUBSUB subcommand [argument [argument …]] – 檢視訂閱與釋出系統狀态
- PUBLISH channel message – 将資訊發送到指定的頻道
- PUNSUBSCRIBE [pattern [pattern …]] – 退訂所有給定模式的頻道。
- SUBSCRIBE channel [channel …] – 訂閱給定的一個或多個頻道的資訊。
- UNSUBSCRIBE [channel [channel …]] – 指退訂給定的頻道。
- Redis 事務: MULTI 開始一個事務, 然後将多個指令入隊到事務中, 最後由 EXEC 指令觸發事務, 一并執行事務中的所有指令。将多個指令請求打包,然後一次性、按順序去執行,在事物執行期間伺服器不會終端事物而改去執行其他用戶端請求指令,要等事物中的所有指令執行完畢,才去執行其他用戶端的請求指令。
-
在開啟事物之前先鎖定值,當值發生變化的時候,後續的事物将會送出失敗
watch ticket
MULTI
decrby ticket 1
…
EXEC
- Redis 事務可以一次執行多個指令, 并且帶有以下兩個重要的保證:
- 批量操作在發送 EXEC 指令前被放入隊列緩存
- 收到 EXEC 指令後進入事務執行,事務中任意指令執行失敗,其餘的指令依然被執行。
- 在事務執行過程,其他用戶端送出的指令請求不會插入到事務執行指令序列中。
- 一個事務從開始到執行會經曆以下三個階段:
- 開始事務
- 指令入隊
- 執行事務
- 單個 Redis 指令的執行是原子性的,但 Redis 沒有在事務上增加任何維持原子性的機制,是以 Redis 事務的執行并不是原子性的。事務可以了解為一個打包的批量執行腳本,但批量指令并非原子化的操作,中間某條指令的失敗不會導緻前面已做指令的復原,也不會造成後續的指令不做。
- Redis 事務指令
- DISCARD – 取消事務,放棄執行事務塊内的所有指令。
- EXEC – 執行所有事務塊内的指令
- MULTI – 标記一個事務塊的開始。
- UNWATCH – 取消 WATCH 指令對所有 key 的監視
- Redis 連接配接:Redis 連接配接指令主要是用于連接配接 redis 服務
- Redis 連接配接指令
- AUTH password – 驗證密碼是否正确
- ECHO message – 列印字元串
- PING – 檢視服務是否運作
- QUIT – 關閉目前連接配接
- SELECT index – 切換到指定的資料庫
- Redis 資料備份: SAVE 指令用于建立目前資料庫的備份,該指令将在 redis 安裝目錄中建立dump.rdb檔案。
-
Redis 資料恢複:如果需要恢複資料,隻需将備份檔案 (dump.rdb) 移動到 redis 安裝目錄并啟動服務即可。擷取 redis 目錄可以使用 CONFIG 指令,如下所示:
CONFIG GET dir
以上指令 CONFIG GET dir 輸出的 redis 安裝目錄為 /usr/local/redis/bin
- 建立 redis 備份檔案也可以使用指令 BGSAVE,該指令在背景執行
- Redis 安全:我們可以通過 redis 的配置檔案設定密碼參數,這樣用戶端連接配接到 redis 服務就需要密碼驗證,這樣可以讓你的 redis 服務更安全。
- CONFIG get requirepass – 檢視是否設定了密碼驗證
- CONFIG set requirepass “runoob” – 設定密碼
- Redis 管道技術: Redis是一種基于用戶端-服務端模型以及請求/響應協定的TCP服務。這意味着通常情況下一個請求會遵循以下步驟:
- 用戶端向服務端發送一個查詢請求,并監聽Socket傳回,通常是以阻塞模式,等待服務端響應。
- 服務端處理指令,并将結果傳回給用戶端。
- Redis 管道技術可以在服務端未響應時,用戶端可以繼續向服務端發送請求,并最終一次性讀取所有服務端的響應。
- 持久化: RDB和AOF
- RDB(快照): 相當于定期給記憶體中的資料拍一張照片,儲存到硬碟中。
- RDB檔案的建立,可通過save或者bgsave
- 當save指令執行時,Redis伺服器會被阻塞,此時用戶端發送的所有請求都會被拒絕,需等待save指令執行完畢,才能接收用戶端請求。
- bgsave是由子程序執行,是以Redis服務是非阻塞的,可以接收用戶端的請求,但是在bgsave指令執行期間,當再執行save、bgsave或bgrewriteaof三個指令時會有所不同,如執行save或bgsave直接拒絕,如執行bgrewriteaof會延時在bgsave完畢之後才執行。
-
自動間隔性儲存,可通過以下配置完成:
在滿足以下3個條件時,bgsave指令就會被執行,生成dump.rdb檔案:
- save 900 #900秒内,如果有一個key的value發生變化,則執行RDB
- save 300 #300秒内,如果有10個key的value發生變化,則執行RDB
-
save 60 #60秒内,如果有10000個key的value發生變化,則執行RDB
缺點:在兩次RDB之間,資料肯定會丢失。
-
RDB預設開啟,可以在redis.conf配置檔案中修改上述政策
save 900 1
save 300 10
save 60 10000
-
AOF(日志),預設關閉需修改配置檔案redis.conf開啟,對伺服器壓力比較大:
appendonly yes 開啟AOF
appendfilename “appendonly.aof” AOF産生的日志檔案
-
AOF産生的政策
appendfsync always 每個操作
appendfsync everysec 每秒
appendfsync no
- AOF日志的重寫,當AOF超過64M時,發生重寫。
- Redis讀寫分離,在Redis中可以通過slaveof指令或設定conf配置檔案中的slaveof選項,實作主從複制,讀寫分離。
- 體系結構和原理
-
星型結構
優點:效率高
缺點:HA實作麻煩
1)選舉其中的一個從節點為Master
2) 其他從節點需要重新連接配接到新的Master
-
線型結構
優點:HA實作簡單
1)把緊鄰的Slave變為Master
缺點:
效率低:
-
- 星型結構的實作方式
- 在主節點的配置檔案上面關閉RDB和AOF
bind 0.0.0.0 # save 900 1 # save 300 10 # save 60 10000 appendonly no
- 修改從節點1的配置檔案
bind 0.0.0.0 port 6380 replicaof 192.168.18.177 6379 dbfilename dump_6380.rdb appendfilename "appendonly_6380.aof"
- 修改從節點2的配置檔案
bind 0.0.0.0 port 6381 replicaof 192.168.18.177 6379 dbfilename dump_6381.rdb appendfilename "appendonly_6381.aof"
- 在主節點的配置檔案上面關閉RDB和AOF
- 連接配接指定端口号的redis: redis-cli -p 6379
- 隻能在主節點上面寫入資料,不能再從節點上面寫入資料,報錯資訊為
(error) READONLY You can't write against a read only replica.
-
哨兵機制
Sentinel: (哨崗、哨兵)是Redis高可用解決方案,由一個或多個Sentinel組成,在redis中要實作哨兵機制,redis必須在2.4+版本。
Sentinel哨兵 —> 主伺服器下線 ----> 故障遷移(重新選取主伺服器) ----> 原主伺服器啟動後将降級為從伺服器
哨兵機制會監視redis叢集中的所有節點,當檢測到主伺服器下線時,哨兵會在所有的從節點中重新選取一個主節點,原主伺服器恢複後,将降級為從伺服器,并從新的主節點上面複制資料。
- 哨兵配置,修改sentinel.conf
sentinel monitor mymaster 192.168.18.177 6379 1 #主節點ip 主節點端口号 哨兵個數 sentinel auth-pass <master-name> <password> # 設定哨兵連接配接主節點時的使用者名和密碼 sentinel down-after-milliseconds mymaster 30000 #多少秒内沒有收到主節點的心跳,哨兵就認為主節點挂了 sentinel parallel-syncs mymaster 1 #選舉新的主節點後,可以同時連接配接其他從節點個數,不能太大 sentinel failover-timeout mymaster 180000 #失敗切換時,允許的最大時間
- 啟動哨兵
啟動後日志為redis-sentinel sentinel.conf
1538:X 15 May 2019 15:45:17.882 # +monitor master mymaster 192.168.18.177 6379 quorum 1 1538:X 15 May 2019 15:45:17.883 * +slave slave 192.168.18.177:6380 192.168.18.177 6380 @ mymaster 192.168.18.177 6379 1538:X 15 May 2019 15:45:17.884 * +slave slave 192.168.18.177:6381 192.168.18.177 6381 @ mymaster 192.168.18.177 6379
-
檢視節點資訊: info replication
主節點:
從節點:# Replication role:master connected_slaves:2 slave0:ip=192.168.18.177,port=6380,state=online,offset=57336,lag=1 slave1:ip=192.168.18.177,port=6381,state=online,offset=57336,lag=1 master_replid:a317eba3b8ffa1ada4d8ae59e7291a00c945d1b9 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:57336 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:57336
# Replication role:slave master_host:192.168.18.177 master_port:6379 master_link_status:up master_last_io_seconds_ago:1 master_sync_in_progress:0 slave_repl_offset:48002 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:a317eba3b8ffa1ada4d8ae59e7291a00c945d1b9 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:48002 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:48002
- Spring Boot連接配接哨兵的配置檔案
spring: redis: # host: 192.168.18.177 #連接配接單節點redis # password: jfpt_common # port: 6381 database: 0 #資料庫0 timeout: 5000 sentinel: #Redis哨兵(HA) master: mymaster nodes: 192.168.18.177:26379 jedis: pool: max-idle: 100 min-idle: 1 max-active: 1000 max-wait: -1
- Spring Boot使用redis叢集的代碼
@Autowired private StringRedisTemplate stringRedisTemplate; @RequestMapping("set") public String setValue(String key, String value){ stringRedisTemplate.opsForValue().set(key, value); String newValue = stringRedisTemplate.opsForValue().get(key); return newValue; }
- Redis叢集:Redis叢集是Redis3.0版本開始提供的分布式資料庫方案,通過分片(sharding)進行資料共享,并提供複制和故障遷移的功能,叢集中可以有多個master。
- 槽指派:Redis叢集通過分片的方式來儲存資料庫中的鍵值,叢集中的整個redis資料庫别分為16384個槽(slot),資料庫中的每個鍵都資料16384個槽中的其中一個,叢集中的每個節點可處理為16384個槽。将Key值進行CRC16計算,得到的數值對16384取模
- Redis叢集的配置
- 複制一個全新的redis.conf配置檔案
- 建立cluster 檔案夾: mkdir cluster
- 在cluster下建立檔案夾: mkdir -p 7001 7002 7003 7004 7005 7006
- 修改配置檔案
port 7001 # 節點端口号 daemonize yes # bind 0.0.0.0 #綁定機器IP dir /usr/redis/cluster/7001/ #資料檔案存放位置 pidfile /var/run/redis_7001.pid #7001要和port對應 cluster-enabled yes #啟動叢集模式 cluster-config-file nodes-7001.conf #7001要和port對應 cluster-node-timeout 10000 #攔截逾時等待時間 appendonly yes appendfilename "appendonly_7001.aof"
- 将上面的檔案分别複制到 cluster/7001 到 cluster/7006,并将使用對應的檔案夾的數字替換配置檔案中的内容:
:%s /7001/7002
- 分别啟動六個redis服務
redis-server ./cluster/7001/redis.conf
- 此時往redis中寫入資料時會報如下的錯誤,原因是沒有安裝ruby
(error) CLUSTERDOWN Hash slot not served
- 安裝ruby
yum install ruby yum install rubygems gem install redis
- 執行上面第三步時會報如下的錯誤
ERROR: Error installing redis: redis requires Ruby version >= 2.2.2.
- 繼續執行下面的指令
連結為:http://www.cnblogs.com/Patrickliu/p/8454579.htmlgpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB curl -sSL https://get.rvm.io | bash -s stable find / -name rvm -print source /usr/local/rvm/scripts/rvm rvm list known rvm install 2.4.1 rvm use 2.4.1 rvm use 2.4.1 --default rvm remove 2.3.4 ruby --version gem install redis
- 建立叢集
–cluster-replicas 1 表示主從複制比例為1:1,即一個主節點對應一個從節點,在redis叢集中預設有16383個solt,預設平均配置設定./redis-cli --cluster create --cluster-replicas 1 192.168.18.177:7001 192.168.18.177:7002 192.168.18.177:7003 192.168.18.177:7004 192.168.18.177:7005 192.168.18.177:7006
- 輸出的内容為:
M: cbe246e4cb7d2be813e8d75b72ee18f95ce6b1b9 192.168.18.177:7001 slots:[0-5460] (5461 slots) master 1 additional replica(s) S: 3e88c6431b67db01a3f37cb73668edd36003b4cf 192.168.18.177:7006 slots: (0 slots) slave replicates 5515163a16503a5892e0d0fc14a5b292d76216c0 S: 4603f8973e3f641ae839872a5b3e963e19a7de07 192.168.18.177:7005 slots: (0 slots) slave replicates cbe246e4cb7d2be813e8d75b72ee18f95ce6b1b9 M: 5f45ddefab50f1d57f54ef53d736f1096256449f 192.168.18.177:7003 slots:[10923-16383] (5461 slots) master 1 additional replica(s) M: 5515163a16503a5892e0d0fc14a5b292d76216c0 192.168.18.177:7002 slots:[5461-10922] (5462 slots) master 1 additional replica(s) S: 57ef0adbb38bb8caf9616873834dc60d8b2a1d74 192.168.18.177:7004 slots: (0 slots) slave replicates 5f45ddefab50f1d57f54ef53d736f1096256449f
- Can I set the above configuration? (type ‘yes’ to accept): yes
- 連接配接驗證
- redis-cli -c -p 7001
- 檢視叢集資訊: cluster nodes
57ef0adbb38bb8caf9616873834dc60d8b2a1d74 192.168.18.177:[email protected] slave 5f45ddefab50f1d57f54ef53d736f1096256449f 0 1558167694000 4 connected 3e88c6431b67db01a3f37cb73668edd36003b4cf 192.168.18.177:[email protected] slave 5515163a16503a5892e0d0fc14a5b292d76216c0 0 1558167695000 6 connected 4603f8973e3f641ae839872a5b3e963e19a7de07 192.168.18.177:[email protected] slave cbe246e4cb7d2be813e8d75b72ee18f95ce6b1b9 0 1558167695963 5 connected cbe246e4cb7d2be813e8d75b72ee18f95ce6b1b9 192.168.18.177:[email protected] master - 0 1558167694000 1 connected 0-5460 5f45ddefab50f1d57f54ef53d736f1096256449f 192.168.18.177:[email protected] master - 0 1558167693000 3 connected 10923-16383 5515163a16503a5892e0d0fc14a5b292d76216c0 192.168.18.177:70[email protected] myself,master - 0 1558167692000 2 connected 5461-10922
- SpringBoot連接配接redis叢集
spring: redis: cluster: nodes: - 192.168.18.177:7001 - 192.168.18.177:7002 - 192.168.18.177:7003 - 192.168.18.177:7004 - 192.168.18.177:7005 - 192.168.18.177:7006 jedis: pool: max-idle: 100 min-idle: 1 max-active: 1000 max-wait: -1
- 分布式鎖的實作方式
- 資料庫的樂觀鎖
- 基于Redis的分布式鎖
- 基于zookeeper的分布式鎖
- 為了確定分布式鎖的可用,至少要確定鎖的實作同時滿足以下4個條件
- 互斥性:在任意時刻,隻有一個用戶端能持有鎖
- 不會發生死鎖: 即使有一個用戶端在持有鎖期間發生崩潰而沒有主動解鎖,也能保證後續其他用戶端能加鎖。
- 具有容錯性: 隻要大部分節點的Redis正常運作,用戶端就可以加鎖和解鎖。
- 加鎖和解鎖必須是同一個用戶端,用戶端自己不能把别人加的鎖給結了。
- 分布式鎖的簡單實作
package com.swkang.springboot.springbootredissentinel.utils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import java.util.UUID; import java.util.concurrent.TimeUnit; @Service public class RedisUtil { @Autowired private StringRedisTemplate redisTemplate; private String key = "lock_key"; /** * 基于Redis實作分布式加鎖 * @param waitTime 加鎖等待時間 * @param timeOut 鎖的儲存時間 * @return 傳回非空字元串,加鎖成功 */ public String lock(int waitTime, int timeOut){ try { String uuid = UUID.randomUUID().toString(); Long endTime = System.currentTimeMillis() + waitTime; while(System.currentTimeMillis() < endTime){ if(redisTemplate.opsForValue().setIfAbsent(key, uuid, timeOut, TimeUnit.SECONDS)){ return uuid; } } }catch (Exception e){ e.printStackTrace();; } return null; } /** * 釋放鎖 * @param uuid */ public void unlock(String uuid){ try { if(redisTemplate.opsForValue().get(key).equals(uuid)){ redisTemplate.delete(key); } } catch (Exception e){ e.printStackTrace(); } } }