前面的文章已經介紹了redis做爲緩存數據庫的說明,本文主要說下redis主從複製及集羣管理配置的操做記錄:php
Redis主從複製(目前redis僅支持主從複製模式,能夠支持在線備份、讀寫分離等功能。)node
1)Redis的複製功能是支持多個數據庫之間的數據同步。一類是主數據庫(master),一類是從數據庫(slave),主數據庫能夠進行讀寫操做,當發生寫操做的時候自動 將數據同步到從數據庫,而從數據庫通常是隻讀的,並接收主數據庫同步過來的數據,一個主數據庫能夠有多個從數據庫,而一個從數據庫只能有一個主數據庫。 2)經過redis的複製功能能夠很好的實現數據庫的讀寫分離,提升服務器的負載能力。主數據庫主要進行寫操做,而從數據庫負責讀操做。
Redis主從複製流程圖linux
複製過程:git
1)當一個從數據庫啓動時,會向主數據庫發送sync命令, 2)主數據庫接收到sync命令後會開始在後臺保存快照(執行rdb操做),並將保存期間接收到的命令緩存起來 3)當快照完成後,redis會將快照文件和全部緩存的命令發送給從數據庫。 4)從數據庫收到後,會載入快照文件並執行收到的緩存的命令。
下面簡單記錄下Redis主從複製的操做記錄:github
1)機器信息 Redis主從結構支持一主多從,這裏我使用一主兩從(一主一從也行,配置同樣) 主節點 182.48.115.236 master-node 從節點 182.48.115.237 slave-node1 從節點 182.48.115.238 slave-node2 關閉三個節點機的iptables防火牆和selinux 2)安裝redis 三臺節點機的安裝步驟同樣 [root@master-node ~]# wget http://download.redis.io/redis-stable.tar.gz [root@master-node ~]# tar -zvxf redis-stable.tar.gz [root@master-node ~]# cd redis-stable [root@master-node redis-stable]# make [root@master-node redis-stable]# cd src/ [root@master-node src]# cp redis-server redis-cli redis-check-aof redis-check-rdb redis-sentinel redis-trib.rb /usr/local/bin/ 而後新建目錄,存放配置文件 [root@master-node src]# mkdir /etc/redis [root@master-node src]# mkdir /var/redis [root@master-node src]# mkdir /var/redis/log [root@master-node src]# mkdir /var/redis/run [root@master-node src]# mkdir /var/redis/redis 在redis解壓根目錄中找到配置文件模板 [root@master-node src]# cd ../ [root@master-node redis-stable]# cp redis.conf /etc/redis/redis.conf 設置啓動腳本 [root@master-node redis-stable]# cp utils/redis_init_script /etc/init.d/redis [root@master-node redis-stable]# chmod 755 /etc/init.d/redis 修改腳本pid及conf路徑爲實際路徑 [root@master-node redis-stable]# vim /etc/init.d/redis ...... REDISPORT=6379 EXEC=/usr/local/bin/redis-server CLIEXEC=/usr/local/bin/redis-cli PIDFILE=/var/redis/run/redis_6379.pid CONF="/etc/redis/redis.conf" ....... 3)主從複製配置 master-node [root@master-node ~]# vim /etc/redis/redis.conf ....... port 6379 ....... daemonize yes //這個修改成yes ....... bind 0.0.0.0 //綁定的主機地址。說明只能經過這個ip地址鏈接本機的redis。最好綁定0.0.0.0;注意這個不能配置成127.0.0.1,不然複製會失敗!用0.0.0.0或者本機ip地址均可以 ....... pidfile /var/redis/run/redis_6379.pid ....... logfile /var/redis/log/redis_6379.log ....... dir /var/redis/redis #redis數據目錄 ....... appendonly yes #啓用AOF持久化方式 appendfilename "appendonly.aof" #AOF文件的名稱,默認爲appendonly.aof appendfsync everysec #每秒鐘強制寫入磁盤一次,在性能和持久化方面作了很好的折中,是受推薦的方式。 ..... save 900 1 #啓用RDB快照功能,默認就是啓用的 save 300 10 save 60 10000 #即在多少秒的時間內,有多少key被改變的數據添加到.rdb文件裏 ....... dbfilename dump.rdb #快照文件名稱 ...... slave-node1和slave-node2兩個從節點相比於master-node主節點的redis.conf配置,只是多了下面一行配置,其它都同樣: slaveof 182.48.115.236 6379 啓動三個節點的redis(啓動命令同樣) [root@master-node ~]# /etc/init.d/redis start Starting Redis server... [root@master-node ~]# lsof -i:6379 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME redis-ser 10475 root 4u IPv4 88640 0t0 TCP localhost:6379 (LISTEN) 登錄主節點master-node的redis,查看狀態 [root@master-node ~]# redis-cli -h 127.0.0.1 -p 6379 //使用182.48.115.236也能夠登陸,或者直接使用redis-cli也能夠登陸 127.0.0.1:6379> info ...... ...... # Replication role:master //節點在集羣中的狀態 connected_slaves:2 //slave節點的個數 slave0:ip=182.48.115.238,port=6379,state=online,offset=1,lag=1 slave1:ip=182.48.115.237,port=6379,state=online,offset=1,lag=1 ........ 登陸從節點slave-node1的redis,查看狀態 [root@slave-node1 ~]# redis-cli -h 127.0.0.1 -p 6379 127.0.0.1:6379> info ....... ....... # Replication role:slave master_host:182.48.115.236 master_port:6379 master_link_status:up ...... 登陸從節點slave-node2的redis,查看狀態 [root@slave-node2 ~]# redis-cli -h 127.0.0.1 -p 6379 127.0.0.1:6379> info ...... # Replication role:slave master_host:182.48.115.236 master_port:6379 master_link_status:up ...... 4)測試數據同步 主節點master-node上寫入新數據 [root@master-node ~]# redis-cli -h 127.0.0.1 -p 6379 127.0.0.1:6379> set name wangshibo OK 127.0.0.1:6379> get name "wangshibo" 而後到兩臺從節點上查看是否同步了上面寫入的數據 [root@slave-node1 ~]# redis-cli -h 127.0.0.1 -p 6379 127.0.0.1:6379> get name "wangshibo" [root@slave-node2 ~]# redis-cli -h 127.0.0.1 -p 6379 127.0.0.1:6379> get name "wangshibo" redis主從複製默認是讀寫分離的,即: 主節點上能夠讀寫操做;從節點上只能進行讀操做,不能寫數據 [root@slave-node1 ~]# redis-cli -h 127.0.0.1 -p 6379 127.0.0.1:6379> set name huanqiu (error) READONLY You can't write against a read only slave. [root@slave-node2 ~]# redis-cli -h 127.0.0.1 -p 6379 127.0.0.1:6379> set name huanqiu (error) READONLY You can't write against a read only slave. 5)主從切換 5.1)中止主節點master-node的redis [root@master-node ~]# redis-cli -h 127.0.0.1 -p 6379 shutdown [root@master-node ~]# redis-cli -h 127.0.0.1 -p 6379 Could not connect to Redis at 127.0.0.1:6379: Connection refused Could not connect to Redis at 127.0.0.1:6379: Connection refused 將從節點slave-node1的redis設成主redis [root@slave-node1 ~]# redis-cli -h 127.0.0.1 -p 6379 slaveof NO ONE //這條命了只是臨時將該節點設置爲主節點;當redis重啓後,就會失效;能夠登陸redis,經過info信息查看! OK [root@slave-node1 ~]# redis-cli -h 127.0.0.1 -p 6379 //變爲主redis後,slave-node1就能夠進行寫入操做了 127.0.0.1:6379> set name huanqiu OK 127.0.0.1:6379> info ...... # Replication role:master //可知已經變成master主節點了 connected_slaves:0 master_repl_offset:0 這時候master-node節點已經故障了,而另外一個從節點slave-node2還跟它有主從關係。此時slave-node1已經變成主redis了,因此能夠將slave-node2的主從關係中的主節點 配置修改成slave-node1(即182.48.115.237) 5.2)原來的主redis恢復正常了,要從新切換回去 好比原來的主redis節點master-node如今恢復了 [root@master-node ~]# /etc/init.d/redis start Starting Redis server... [root@master-node ~]# redis-cli -h 127.0.0.1 -p 6379 127.0.0.1:6379> info ...... # Replication role:master //原來的主節點恢復了,發現只有一個從節點save-node2。另外一個從節點slave-node1在master-node故障期間臨時變爲主節點 connected_slaves:1 slave0:ip=182.48.115.238,port=6379,state=online,offset=1,lag=0 ...... 那麼如今要從新將主節點切換回去。步驟以下: a)登陸臨時切換的主節點slave-node1 [root@slave-node1 ~]# redis-cli -h 127.0.0.1 -p 6379 127.0.0.1:6379> set name hahahha OK 127.0.0.1:6379> get name "hahahha" 127.0.0.1:6379> save //將數據保存 OK b)將如今的主redis(即slave-node1節點,臨時設置的主節點)根目錄下app文件和dump.rdb文件拷貝覆蓋到原來主redis的根目錄(覆蓋前將原來主redis下的持久化文件備份下) [root@slave-node1 ~]# rsync -e "ssh -p22" -avpgolr /var/redis/redis/dump.rdb 182.48.115.236:/var/redis/redis/ [root@slave-node1 ~]# rsync -e "ssh -p22" -avpgolr /var/redis/redis/appendonly.aof 182.48.115.236:/var/redis/redis/ c)重啓原來的主redis(即master-node節點) [root@master-node ~]# /etc/init.d/redis stop [root@master-node ~]# /etc/init.d/redis start d)在如今的主redis(即slave-node1)中切換(或者直接重啓該節點的redis,由於redis.conf文件中已經配置了;若是不想重啓redis,就使用下面的命令) [root@slave-node1 ~]# redis-cli -h 127.0.0.1 -p 6379 slaveof 182.48.115.236 6379 OK e)登陸原來的主redis(也就是master-node)查看 [root@master-node ~]# redis-cli -h 127.0.0.1 -p 6379 127.0.0.1:6379> info ....... # Replication role:master connected_slaves:2 slave0:ip=182.48.115.237,port=6379,state=online,offset=1,lag=0 slave1:ip=182.48.115.238,port=6379,state=online,offset=1,lag=0 master_repl_offset:1 ...... ------------------------------------------------------------------------------------------------------------------ 注意事項 若是使用主從複製,那麼要確保你的master激活了持久化,或者確保它不會在當掉後自動重啓,緣由: a)slave是master的完整備份,所以若是master經過一個空數據集重啓,slave也會被清掉。 b)在配置redis複製功能的時候,若是主數據庫設置了密碼,須要在從數據的配置文件中經過masterauth參數設置主數據庫的密碼,這樣從數據庫在鏈接 主數據庫時就會自動使用auth命令認證了。至關於作了一個免密碼登陸。(我上面的例子中沒有設置密碼)
Redis的主從自動切換(failover)能夠經過Redis自帶的Sentinel工具來實現(具體操做這裏就先不介紹了)。redis的sentinel系統用於管理多個redis服務器,
該系統主要執行三個任務:監控、提醒、自動故障轉移。
1)監控(Monitoring): Redis Sentinel實時監控主服務器和從服務器運行狀態,而且實現自動切換。
2)提醒(Notification):當被監控的某個 Redis 服務器出現問題時, Redis Sentinel 能夠向系統管理員發送通知, 也能夠經過 API 向其餘程序發送通知。
3)自動故障轉移(Automatic failover): 當一個主服務器不能正常工做時,Redis Sentinel 能夠將一個從服務器升級爲主服務器, 並對其餘從服務器進行配置,
讓它們使用新的主服務器。當應用程序鏈接Redis 服務器時, Redis Sentinel會告之新的主服務器地址和端口。
注意:
在使用sentinel監控主從節點的時候,從節點須要是使用動態方式配置的,若是直接修改配置文件,後期sentinel實現故障轉移的時候會出問題。redis
------------------------------------------------------------------------------------------------------------------------------------------------ 數據庫
Redis默認只支持主從模式,不支持主主模式,可使用SSDB主主模式代替Redis實現主主同步環境。SSDB是一個快速的用來存儲十億級別列表數據的開源 NoSQL 數據庫。支持Key-value, Keyhashmap, Key-zset(sorted set) 等數據結構,十分適合存儲數億條級別的列表, 排序表等集合數據, 是Redis的替代和加強方案。
SSDB特性:vim
1)替代 Redis 數據庫, Redis 的100倍容量 2)LevelDB 網絡支持, 使用C/C++ 開發 3)Redis API 兼容, 支持 Redis 客戶端 4)適合存儲集合數據, 如 list, hash, zset... 5)客戶端 API 支持的語言包括: C++, PHP, Python,Cpy,Java,Nodejs,Ruby, Go等 6)持久化的隊列服務 7)主從複製,支持雙主(雙master)和多主架構, 負載均衡 8)圖形化管理工具(phpssdbadmin)
SSDB的主從同步策略很是簡單, 就是把主(Master)上的全部寫操做(Binlogs), 在從(Slave)上再執行一遍. MySQL 的主從同步也是同樣. 而多主能夠理解爲互爲主從.緩存
SSDB的雙主和多主配置
SSDB 數據庫是支持雙主(雙 Master)和多主架構的. 並且, 咱們的應用也是部署雙主架構, 但看成單主來用. 也就是說, 平時只往其中一個寫, 當出現故障時, 總體切換到另外一個主上面. 若是應用層已經解決了數據拆分, 也即不會兩個節點同時操做一個 key, 那麼就能夠放心使用雙主同時寫入.安全
SSDB 雙主的配置很是簡單:
server1服務器
replication: slaveof: id: svc_2 # sync|mirror, default is sync type: mirror ip: 192.168.1.10 port: 8888
server2服務器
replication: slaveof: id: svc_1 # sync|mirror, default is sync type: mirror ip: 192.168.1.11 port: 8888
只須要將type設置爲mirror, 而後每一個節點各指向對方便可。若是是多主, 則每一個節點要指向其它 n-1 個節點。
SSDB 主主同步模式部署記錄
SSDB主主模式的部署記錄: 182.48.115.236 master-node1 182.48.115.237 master-node2 1)安裝SSDB(在兩個節點機上安裝步驟同樣,以下) [root@master-node1 ~]# mkdir -p /home/slim/ssdb [root@master-node1 ~]# wget https://github.com/ideawu/ssdb/archive/master.zip [root@master-node1 ~]# unzip master.zip [root@master-node1 ~]# cd ssdb-master/ [root@master-node1 ssdb-master]# make PREFIX=/home/slim/ssdb [root@master-node1 ssdb-master]# make PREFIX=/home/slim/ssdb install 2)主主模式配置 master-node1節點上的配置 [root@master-node1 ~]# cd /home/slim/ssdb/ [root@master-node1 ssdb]# cp ssdb.conf ssdb.conf.bak [root@master-node1 ssdb]# vim ssdb.conf # ssdb-server config # MUST indent by TAB! # relative to path of this file, directory must exists work_dir = ./var pidfile = ./var/ssdb.pid server: ip: 182.48.115.236 port: 8888 # bind to public ip #ip: 0.0.0.0 # format: allow|deny: all|ip_prefix # multiple allows or denys is supported #deny: all #allow: 127.0.0.1 #allow: 192.168 # auth password must be at least 32 characters #auth: very-strong-password #readonly: yes replication: binlog: yes # Limit sync speed to *MB/s, -1: no limit sync_speed: -1 slaveof: # to identify a master even if it moved(ip, port changed) # if set to empty or not defined, ip:port will be used. id: svc_1 # sync|mirror, default is sync type: mirror host: 182.48.115.237 port: 8888 logger: level: debug output: log.txt rotate: size: 1000000000 leveldb: # in MB cache_size: 500 # in MB write_buffer_size: 64 # in MB/s compaction_speed: 1000 # yes|no compression: yes master-node2節點上的配置 [root@master-node2 ~]# cd /home/slim/ssdb/ [root@master-node2 ssdb]# cp ssdb.conf ssdb.conf.bak [root@master-node2 ssdb]# vim ssdb.conf # ssdb-server config # MUST indent by TAB! # relative to path of this file, directory must exists work_dir = ./var pidfile = ./var/ssdb.pid server: ip: 182.48.115.237 port: 8888 # bind to public ip #ip: 0.0.0.0 # format: allow|deny: all|ip_prefix # multiple allows or denys is supported #deny: all #allow: 127.0.0.1 #allow: 192.168 # auth password must be at least 32 characters #auth: very-strong-password #readonly: yes replication: binlog: yes # Limit sync speed to *MB/s, -1: no limit sync_speed: -1 slaveof: # to identify a master even if it moved(ip, port changed) # if set to empty or not defined, ip:port will be used. id: svc_2 # sync|mirror, default is sync type: mirror host: 182.48.115.236 port: 8888 logger: level: debug output: log.txt rotate: size: 1000000000 leveldb: # in MB cache_size: 500 # in MB write_buffer_size: 64 # in MB/s compaction_speed: 1000 # yes|no compression: yes 3)啓動服務(兩節點啓動命令同樣) [root@master-node1 ~]# /home/slim/ssdb/ssdb-server -d /home/slim/ssdb/ssdb.conf ssdb-server 1.9.4 Copyright (c) 2012-2015 ssdb.io [root@master-node1 ~]# ps -ef|grep ssdb root 23803 1 0 21:05 ? 00:00:00 /home/slim/ssdb/ssdb-server -d /home/slim/ssdb/ssdb.conf root 23819 23719 0 21:05 pts/0 00:00:00 grep ssdb ......................................................................................................... 關閉命令: /home/slim/ssdb/ssdb-server /home/slim/ssdb/ssdb.conf -s stop 幫忙命令 /home/slim/ssdb/ssdb-server -h ......................................................................................................... 4)數據同步測試 在master-node1節點上寫入數據 [root@master-node1 ~]# /home/slim/ssdb/ssdb-cli -h 182.48.115.236 -p 8888 ssdb (cli) - ssdb command line tool. Copyright (c) 2012-2016 ssdb.io 'h' or 'help' for help, 'q' to quit. ssdb-server 1.9.4 ssdb 182.48.115.236:8888> set name wangshibo ok (0.001 sec) ssdb 182.48.115.236:8888> get name wangshibo (0.001 sec) ssdb 182.48.115.236:8888> 在master-node2節點上查看: [root@master-node2 ~]# /home/slim/ssdb/ssdb-cli -h 182.48.115.237 -p 8888 ssdb (cli) - ssdb command line tool. Copyright (c) 2012-2016 ssdb.io 'h' or 'help' for help, 'q' to quit. ssdb-server 1.9.4 ssdb 182.48.115.237:8888> get name wangshibo (0.001 sec) 同理,在master-node2節點上寫入數據 [root@master-node2 ~]# /home/slim/ssdb/ssdb-cli -h 182.48.115.237 -p 8888 ssdb (cli) - ssdb command line tool. Copyright (c) 2012-2016 ssdb.io 'h' or 'help' for help, 'q' to quit. ssdb-server 1.9.4 ssdb 182.48.115.237:8888> set huanqiutest hahahah ok (0.001 sec) ssdb 182.48.115.237:8888> 而後在另外一臺master-node1節點上查看 [root@master-node1 ~]# /home/slim/ssdb/ssdb-cli -h 182.48.115.236 -p 8888 ssdb (cli) - ssdb command line tool. Copyright (c) 2012-2016 ssdb.io 'h' or 'help' for help, 'q' to quit. ssdb-server 1.9.4 ssdb 182.48.115.236:8888> get huanqiutest hahahah (0.001 sec) 以上說明ssdb主主同步環境已經實現! .............................................................................. ssdb服務監控 info 命令返回的信息 [root@master-node1 ~]# /home/slim/ssdb/ssdb-cli -h 182.48.115.236 -p 8888 ........ ssdb 182.48.115.236:8888> info ........ replication client 182.48.115.237:56014 type : mirror status : SYNC last_seq : 3 replication slaveof 182.48.115.237:8888 id : svc_1 type : mirror status : SYNC last_seq : 2 copy_count : 1 sync_count : 1 [root@master-node2 ~]# /home/slim/ssdb/ssdb-cli -h 182.48.115.237 -p 8888 ......... ssdb 182.48.115.237:8888> info ......... replication client 182.48.115.236:50210 type : mirror status : SYNC last_seq : 2 replication slaveof 182.48.115.236:8888 id : svc_2 type : mirror status : SYNC last_seq : 3 copy_count : 1 sync_count : 0 ............................................................................ info命令後的消息參數解釋: 1)binlogs 當前實例的寫操做狀態. capacity: binlog 隊列的最大長度 min_seq: 當前隊列中的最小 binlog 序號 max_seq: 當前隊列中的最大 binlog 序號 2)replication 能夠有多條 replication 記錄. 每一條表示一個鏈接進來的 slave(client), 或者一個當前服務器所鏈接的 master(slaveof). slaveof|client ip:port, 遠端 master/slave 的 ip:port。 type: 類型, sync|mirror. status: 當前同步狀態, DISCONNECTED|INIT|OUT_OF_SYNC|COPY|SYNC。 last_seq: 上一條發送或者收到的 binlog 的序號。 slaveof.id: master 的 id(這是從 slave's 角度來看的, 你永遠不須要在 master 上配置它本身的 id)。 slaveof.copy_count: 在全量同步時, 已經複製的 key 的數量。 slaveof.sync_count: 發送或者收到的 binlog 的數量。 3)關於 status: DISCONNECTED: 與 master 斷開了鏈接, 通常是網絡中斷。 INIT: 初始化狀態。 OUT_OF_SYNC: 因爲短期內在 master 有大量寫操做, 致使 binlog 隊列淘汰, slave 丟失同步點, 只好從新複製所有的數據。 COPY: 正在複製基準數據的過程當中, 新的寫操做可能沒法及時地同步。 SYNC: 同步狀態是健康的. 4)判斷同步狀態 binlogs.max_seq 是指當前實例上的最新一次的寫(寫/更新/刪除)操做的序號, replication.client.last_seq 是指已發送給 slave 的最新一條 binlog 的序號。因此, 若是你想判斷主從同步是否已經同步到位(實時更新), 那麼就判斷 binlogs.max_seq 和 replication.client.last_seq 是否相等。 ---------------------SSDB備份與恢復---------------------- 1)備份 支持了在線備份功能, 能夠在不中止服務的狀況下備份服務器數據,這個功能讓 SSDB 更加成爲一個真正生產環境的存儲服務器。 [root@master-node1 ~]# /home/slim/ssdb/ssdb-dump 182.48.115.237 8888 ./backup_dir 這條命令從監聽在182.48.115.237:8888 的SSDB服務器上備份全量的數據, 保存到本地新建立的目錄 backup_dir, 這個目錄實際上是一個 LevelDB 的數據庫(db)。 2)恢復 將 backup_dir 傳輸到服務器, 修改新ssdb服務器的配置文件, 將 SSDB 使用的數據庫名改成 backup_dir, 而後重啓 SSDB 便可。 3)使用主從(Master-Slave)架構實時備份 注意: a)通常, 建議你將 logger.level 設置爲 debug 級別。詳情參考:日誌解讀 b)利用配置文件的 deny, allow 指令限制可信的來源 IP 訪問,提升服務的安全。 c)SSDB 的配置文件使用一個 TAB 來表示一級縮進, 不要使用空格來縮進, 不管你用2個, 3個, 4個, 或者無數個空格都不行! d)必定要記得修改你的 Linux 內核參數, 關於 max open files(最大文件描述符數)的內容,詳情參考:構建C1000K的服務器