1. 程式人生 > 其它 >redis(keys命令,持久化,叢集,ssm框架整合jedis)

redis(keys命令,持久化,叢集,ssm框架整合jedis)

1.設定key的生存週期

  • Redis在實際使用過程中更多的用作快取,然而快取的資料一般都是需要設定生存時間的,即:到期後資料銷燬
expire key seconds    設定key的生存時間(單位:秒),key在多少秒後會自動刪除
ttl key 檢視key的生存時間
persist key 消除生存時間
pexpire key milliseconds  生存時間設定單位為:毫秒

2.其他命令

keys 返回滿足給定pattern的所有key    keys mylist*  返回所有前置名稱為mylist的key
exists key  確認一個key是否存在
del key 刪除一個key
rename key newname 重名名key
type key 返回值的型別

3.伺服器命令

ping 測試連線是否存活
echo 在命令列列印一些內容
select number 切換資料庫(redis預設有16個數據庫)
quit 退出連線
dbsize 返回當前資料庫中的key數目
info 獲取伺服器的資訊和統計
flushdb 刪除當前選擇資料庫是所有key
flushall 刪除所有資料庫中的key

4.持久化(RDB快照)(AOF)

  • Redis的高效能是由於其將所有資料都儲存在了記憶體中,為了使Redis在重啟之後仍能保證資料不丟失,需要將資料從記憶體中同步到硬碟中,這一過程就是持久化。

  • Redis支援兩種方式的持久化,一種是RDB方式,一種是AOF方式。可以單獨使用其中一種或將二者結合使用。

1.RDB持久化

  • RDB方式的持久化是通過快照(snapshotting)完成的,當符合一定條件時Redis會自動將記憶體中的資料進行快照並持久化到硬碟。

  • RDB是Redis預設採用的持久化方式,在redis.conf配置檔案中預設有此下配置:

    save 900 1

    save 300 10

    save 60 10000

  • 在redis.conf中:

    ​ 配置dir指定rdb快照檔案的位置

    ​ 配置dbfilename指定rdb快照檔案的名稱

  • Redis啟動後會讀取RDB快照檔案,將資料從硬碟載入到記憶體。根據資料量大小與結構和伺服器效能不同,這個時間也不同。通常將記錄一千萬個字串型別鍵大小為1GB的

    快照檔案載入到記憶體中需要花費20~30秒鐘。

問題總結:

​ 通過RDB方式實現持久化,一旦Redis異常退出,就會丟失最後一次快照以後更改的所有資料。這就需要開發者根據具體的應用場合,通過組合設定自動快照條件的方式來將可能發生的資料損失控制在能夠接受的範圍。如果資料很重要以至於無法承受任何損失,則可以考慮使用AOF方式進行持久化。

2.AOF持久化

  • 預設情況下Redis沒有開啟AOF(append only file)方式的持久化,可以通過appendonly引數開啟:

    appendonly yes

  • 開啟AOF持久化後每執行一條會更改Redis中的資料的命令,Redis就會將該命令寫入硬

    盤中的AOF檔案。AOF檔案的儲存位置和RDB檔案的位置相同,都是通過dir引數設定的,預設的檔名是appendonly.aof,可以通過appendfilename引數修改:appendfilename appendonly.aof.

  • 專案當中必須使用rdb,手動開啟aof,來保證資料的完整性

    當採用rdb+aof持久化機制的時候,redis伺服器在啟動之後,會先載入rdb檔案,再載入aof檔案,所以才保證了資料的完整性

5.redis主從複製

主:主伺服器 從:從伺服器

主節點主要負責資料寫入,從節點負責資料讀的請求。主和從之間通過網路連線進行資料的傳輸

全量複製:第一次同步會進行全量複製,傳送rgb檔案進行復制

增量複製:之後的每次同步都會根據偏移量,和主機的id值,來進行增量複製

主機掛掉後:從機會根據投票選舉演算法(paxos:分別選舉演算法),選出一個新的主節點。

  • 持久化保證了即使redis服務重啟也不會丟失資料,因為redis服務重啟後會將硬碟上持久化的資料恢復到記憶體中,當redis伺服器的硬碟損壞了可能會導致資料丟失,通過redis的主從複製機制就可以避免這種單點故障
  • 主redis中的資料有兩個副本(replication)即從redis1和從redis2,即使一臺redis伺服器宕機其它兩臺redis服務也可以繼續提供服務

  • 主redis中的資料和從redis上的資料保持實時同步,當主redis寫入資料時通過主從複製機制會複製到兩個從redis服務上

  • 只有一個主redis,可以有多個從redis

  • n 主從複製不會阻塞master,在同步資料時,master 可以繼續處理client (客戶端)請求

  • 一個redis可以即是主又是從

  • 主redis中的資料有兩個副本(replication)即從redis1和從redis2,即使一臺redis伺服器宕機其它兩臺redis服務也可以繼續提供服務

  • 主redis中的資料和從redis上的資料保持實時同步,當主redis寫入資料時通過主從複製機制會複製到兩個從redis服務上

  • 只有一個主redis,可以有多個從redis

  • n 主從複製不會阻塞master,在同步資料時,master 可以繼續處理client (客戶端)請求

  • 一個redis可以即是主又是從

1.主從配置

  • 主機無需配置

  • 從機修改從redis伺服器上的redis.conf檔案,新增slaveof 主redisip 主redis埠

2.主從複製過程

修改從redis伺服器上的redis.conf檔案,新增*slaveof 主redisip 主redis埠*

  • 完整複製

1、 slave 服務啟動,slave 會建立和master 的連線,傳送sync 命令。

2、master啟動一個後臺程序將資料庫快照儲存到RDB檔案中

注意:此時如果生成RDB檔案過程中存在寫資料操作會導致RDB檔案和當前主redis資料不一致,所以此時master 主程序會開始收集寫命令並快取起來。

3、master 就傳送RDB檔案給slave

4、slave 將檔案儲存到磁碟上,然後載入到記憶體恢復

5、master把快取的命令轉發給slave

注意:後續master 收到的寫命令都會通過開始建立的連線傳送給slave。

當master 和slave 的連線斷開時slave 可以自動重新建立連線。如果master 同時收到多個slave 發來的同步連線命令,只會啟動一個程序來寫資料庫映象,然後傳送給所有slave。

  • 部分複製

從機連線主機後,會主動發起 PSYNC 命令,從機會提供 master的runid(機器標識,隨機生成的一個串) 和 offset(資料偏移量,如果offset主從不一致則說明資料不同步),主機驗證 runid 和 offset 是否有效, runid 相當於主機身份驗證碼,用來驗證從機上一次連線的主機,如果runid驗證未通過則,則進行全同步,如果驗證通過則說明曾經同步過,根據offset同步部分資料。

Redis主從結構,資料同步的原理(redis主從複製的原理)

Redis主從伺服器之間,先進行rdb全量複製,再進行增量複製.

缺點:只有一臺主機負責寫入,可以應對查詢的高併發,無法應對寫的高併發,這時候使用cluster叢集

6.redis cluster叢集

叢集是指在多臺機器上安裝同樣的應用,多臺機器共同來完成工作

1.redis cluster叢集工作原理

整個叢集會分配16384個hash槽。

每一個主從都會分配一部分的槽

  • 客戶端進行寫入操作,寫入一個key
  • 客戶端進行讀寫操作的時候,會將key的值crc16演算法,之後再對該值對16384取模 slot=crc16(key值)%16384,計算出該key的solt值
  • 找到對應的一對主從,由這對主從負責對該key的管理(讀,寫)

redis cluster叢集的優點

  • 支援高併發寫
  • 資料存在副本更安全,資料分片(資料分割槽間進行儲存)
  • 提供了哨兵機制(檢測主從之間的連線,一旦發現主節點不可以,會自動切換從節點作為主節點)更安全

2.搭建redis cluster 叢集

  1. 建立6個檔案目錄,用於存放每一個redis例項的配置檔案

    /usr/app/redis-cluster/7001/
    ...
    /usr/app/redis-cluster/7006/

  2. 修改每一份配置檔案

    bind 192.168.192.3 //繫結伺服器IP地址

    port 7001 //繫結埠號,必須修改,以此來區分Redis例項

    daemonize yes //後臺執行

    protected-mode no//關閉保護模式

    databases 1//修改資料庫個數為1

    pidfile /usr/app/redis-cluster/7001/redis-7001.pid //修改pid程序檔名,以埠號命名

    logfile /usr/app/redis-cluster/7001/redis.log //修改日誌檔名稱,以埠號為目錄來區分

    dir /usr/app/redis-cluster/7001/ //修改資料檔案存放地址,以埠號為目錄名來區分(預設當前路徑可以不修改)

    cluster-enabled yes //啟用叢集

    cluster-config-file /usr/app/redis-cluster/7001/nodes-7001.conf //配置每個節點的配置檔案,同樣以埠號為名稱

    cluster-node-timeout 15000 //配置叢集節點的超時時間,可改可不改

    appendonly yes //啟動AOF增量持久化策略

    appendfsync always //發生改變就記錄日誌

  3. 將/usr/app/redis/bin/redis-cli 與 redis-server 放到 /usr/app/redis-cluster 下

  4. 將當前redis程序刪掉

3.環境安裝

redis叢集管理工具redis-trib.rb依賴ruby環境,首先需要安裝ruby環境:

https://jingyan.baidu.com/article/066074d60111e0c3c21cb0ce.html

  • 安裝ruby

    yum -y install ruby ruby-devel rubygems rpm-build //使用yum安裝ruby

    ruby -v 系統自帶的ruby版本為2.0.0

    yum install centos-release-scl-rh 安裝yum源

    yum install rh-ruby24 -y 後面是4是需要安裝的版本號

    scl enable rh-ruby24 bash 設定開機自啟

    ruby -v 檢視ruby版本(2.4.6)

  • 安裝redis外掛

    gem install redis 安裝外掛

    刪除原有的rdb和aof檔案(可以不刪除)
    檢視一下redis程序,保證沒有redis例項在執行
    ps -ef |grep redis

  • 啟動6臺redis例項

    cd /usr/app/redis-cluster 切換到redis-cluster目錄

    ./redis-server ./7001/redis.conf

    ./redis-server ./7002/redis.conf

    ./redis-server ./7003/redis.conf

    ./redis-server ./7004/redis.conf

    ./redis-server ./7005/redis.conf

    ./redis-server ./7006/redis.conf

    ps -ef |grep redis 檢視是否啟動成功

  • 使用指令碼redis-trib.rb(放在redis 原始檔當中),進行叢集

    cd /usr/app/redis-4.0.9/src

    cp redis-trib.rb /usr/app/redis-cluster/

    cd /usr/app/redis-cluster/

    //搭建叢集 replicas 1 代表1臺主機有一臺從機

    ruby redis-trib.rb create --replicas 1 192.168.192.3:7001 192.168.192.3:7002 192.168.192.3:7006 192.168.192.3:7003 192.168.192.3:7004 192.168.192.3:7005

    //連線服務 -c 表示連結的是叢集 -h表示ip -p表示連線的埠號

    ./redis-cli -c -h 192.168.192.3 -p 7005

在建立新的key時候,會先將key進行hash演算法,得到hash值,然後對16384進行取模,獲得需要執行的埠,會進行重定向到指定的埠

cluster info 獲取cluster叢集的資訊(檢視是否出錯)
cluster nodes 獲取節點資訊(主從節點)
//java端連線叢集方式
HashSet<HostAndPort> set = new HashSet();
set.add(new HostAndPort("192.168.192.3",7001));
set.add(new HostAndPort("192.168.192.3",7002));
set.add(new HostAndPort("192.168.192.3",7003));
set.add(new HostAndPort("192.168.192.3",7004));
set.add(new HostAndPort("192.168.192.3",7005));
set.add(new HostAndPort("192.168.192.3",7006));
JedisCluster jedisCluster = new JedisCluster(set);
System.out.println(jedisCluster.get("test"));