Redis叢集+tomcat7叢集實現session共享
就在昨天,一個線上的產品突然不能訪問了,經過一系列的排查問題,最終發現原來是redis死掉了,因為做的用redis管理session,redis又是單臺伺服器,當redis宕機後,網站就訪問不上了。為了避免以後redis宕機導致網站上不去,同時也為了網站的穩健性,我決定把redis做成叢集的方式,其中一個redis宕機,也不影響網站的正常使用。
本文軟體架構:redis3.2.10,tomcat7,jdk7,centos7.2,一般叢集都是採用奇數群,so redis3個 tomcat3個,
目錄
準備工作
-
下載tomcat7:wget http://mirrors.shu.edu.cn/apache/tomcat/tomcat-7/v7.0.91/bin/apache-tomcat-7.0.91.tar.gz
安裝redis
在編譯之前,請檢查有沒有安裝gcc,g++,
yum -y install gcc yum -y install gcc-c++
編譯:進入redis目錄,執行make (這一步時間可能有點長)
copy redis.conf 和src下的 redis-server redis-cli 到 /usr/local/server/redis1下,copy三次,注意資料夾名字不要重複
修改redis1中的redis.conf
把當前的redis選中為master節點,要修改的配置檔案如下:
註釋掉bind 127.0.0.1,允許外部連線
protected-mode yes 改為 protected-mode no 禁用保護模式
(上面這兩部重要,為了後面連線 這個坑我又踩了一遍,)
修改埠號:port 6301
修改為後臺執行:daemonize yes
修改日誌檔案位置:logfile "/tmp/logs/redis1.log"
修改 pidfile /var/run/redis_6301.pid
最後根據實際情況修改:maxclients maxmemory
(主節點修改完畢)
修改redis2(從節點) 的redis.conf
註釋掉bind 127.0.0.1,允許外部連線
protected-mode yes 改為 protected-mode no 禁用保護模式
修改埠號:port 6302
修改為後臺執行:daemonize yes
修改日誌檔案位置:logfile "/tmp/logs/redis2.log"
修改pidfile /var/run/redis_6302.pid
做主從複製:找到 slaveof <masterip> <masterport>:slave 主節點ip 埠
註釋掉save 900 1 save 300 10 save 60 10000,從節點只做讀取的操作,so把它註釋掉
最後根據實際情況修改:maxclients maxmemory
修改redis3(從節點)的redis.conf
這個根據reids2的conf配置檔案修改 埠為6303 日誌檔案 和pid 剩下的基本一樣
三個redis配置完了,這只是做了redis的主從複製,但是需要一個監控redis的狀態資訊,redis提供了一個sentinel哨兵機制
搭建sentinel
sentinel也需奇數群 本文設定3個
copy redis安裝目錄中的 sentinel.conf 和 src下的 redis-sentinel 到/usr/local/server/redis/sentinel1中(其餘的如此複製)
修改sentinel.conf配置檔案:
port 26380 sentinel埠號
daemonize yes 在後臺執行
protected-mode no 允許遠端連線(這個巨坑)
dir /tmp
sentinel monitor mymaster 主節點ip 6301 2 監控主節點,後面2表示 如果2個sentinel認為主節點宕機 就是真的宕機
sentinel down-after-milliseconds mymaster 1000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
剩下的兩個根據上面配置 只需要修改埠號就可以、
下面依次啟動三個redis 和三個sentinel
tomcat配置
在tomcat的conf下context.xml中新增:
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" /> <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager" sentinelMaster="mymaster" 主節點的名稱 sentinels="主機ip:26379,主機ip:26380,主機ip:26381" 三個sentinel幾點的ip和埠 database="0" 連線的redis資料庫 maxInactiveInterval="60" /> session失效時間 單位為分鐘
修改webapp下ROOT中index.jsp
刪掉<%@ page session="false" %>
在body下新增<div>當前sessionId是<%= session.getId()%></div>
最後啟動三個redis和三個sentinel 瀏覽器訪問三個tomcat 就能看見sessionId是一樣。
redis-sentinel總結:
- sentinel的作用,他用來監控reids主節點的狀態,每次做心跳檢測會向redis主節點發送一次info如果沒有得到資訊,就有一個故障資訊,剩下的sentinel會再一次傳送一次info 如果配置的是兩個sentinel發現reids主節點死掉, 就會做一個主從切換(slave of主節點),會從剩下的reids中重新選舉一個從節點作為主節點。(sentinel仲裁會)
- 上面說到reids主節點宕機,如果sentinel也發生宕機,這就是sentinel也需要叢集化的原因。如果sentinel的“老大”也老生宕機這個時候sentinel叢集會重新選舉一個“老大”(sentinel選舉)
redis主從複製總結:
-
一主兩從 兩個從節點只能讀不能寫;當從節點和主機點斷開連線後需要重新slave of主節點,才能建立連線;master掛掉後,master關係依然存在,master重啟即可恢復。
-
上一個slave可以是下一個slave的master,slave同樣可以接收其他slaves的連線和同步請求,那麼該slave作為了 鏈條中下一個slave的Master,如此可以有效減輕Master的寫壓力。如果slave中途變更轉向,會清除之前的資料,重新建立最新的。