Redis 部署策略

公司線上redis主從環境下的持久化策略調整:
描述:
以前線上項目使用redis,部署了redis主從環境。redis的主從複製功能很是強大,一個master能夠擁有多個slave,而一個slave又能夠擁有多個slave,如此下去,造成了強大的多級服務器集羣架構。因爲主redis採用了AOF和save快照的持久化,長時間下去,aof文件不斷增大,磁盤空間使用率逐漸暴增。
考慮到性能問題,須要對redis持久化作些調整,調整以下:
   1)主庫不開啓AOF持久化,並關閉save快照功能(即註釋默認的三個save設置),只在每晚12點定時手動作一次bgsave快照,並將快照文件轉移到異地。即主庫上不產生appendonly.aof持久化文件,作的快照數據放在.rdb文件裏(如dump.rdb,因爲是壓縮配置(rdbcompression yes表示快照文件要壓縮),因此快照文件要比aof文件小),而後將這個快照文件dump.rdb轉移到其餘的服務器上,防止主服務器宕機形成的損失!
   2)從庫開啓AOF持久化並1秒落地,一樣不作快照save。並在每晚12點作一次bgrewriteaof壓縮appendonly.aof持久化文件,壓縮前先對aof文件進行備份。
--------------------------------------------------------------------------------------------------------------------------------------------
按照這種方法進行redis持久化調整,因爲線上redis的主庫以前採用了AOF和save快照的持久化,以後將這兩種都關閉,從庫採用AOF持久化。出現了下面的現象:
就是主庫關閉AOF和save快照後,主redis上的appendonly.aof持久化文件在一段時間內還在刷,在增大,這是正常的,因爲以前開啓的緣故,刷過一段時間,主redis的appendonly.aof持久化文件就不刷了,只有從redis的appendonly.aof持久化文件在刷了
--------------------------------------------------------------------------------------------------------------------------------------------redis

主從redis部署的主要目的:數據持久化,災難恢復,冗餘。主庫不落地,減小消耗。
1)主庫不作AOF,不作快照,容許從庫訪問便可。
2)從庫開啓AOF,不作save
3)備份策略:
主庫每晚12點整給每一個實例手動作一次bgsave快照,並將快照文件備份到遠程節點上。
從庫每晚12點整對AOF文件打包備份(tar),打包備份後作一次AOF文件壓縮(bgrewriteaof)。天天的數據起始點是前一天晚上rewriteaof後的數據。bash

主庫服務器腳本:
即主庫快照以後,將快照文件轉移到異地即從庫機器192.168.1.121/135上面。服務器

1網絡

2架構

3app

4性能

5學習

6ui

7spa

8

9

[root@192-168-1-132 redis]# cat redis_bgsave.sh

#!/bin/bash

CURHOUR=`date +%Y%m%d_%H`

/usr/local/bin/redis-cli -h 127.0.0.1 -p 6379 bgsave

sleep 10

rsync -av /data/redis/dump.rdb root@192.168.1.121:/data/backup/192.168.1.132-save/$CURHOUR/

rsync -av /data/redis/dump.rdb root@192.168.1.135:/data/backup/192.168.1.132-save/$CURHOUR/

sleep 10

date >> /data/logs/bgsave.log

從庫服務器腳本:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

[root@cdn redis]# cat redis_backup.sh

#!/bin/bash

 

CURDATE=`date +%Y%m%d`

CURHOUR=`date +%Y%m%d_%H`

CURTIME=`date +%Y%m%d_%H%M%S`

LOGFILE=/data/logs/redisbak/redis_allbak_${CURDATE}.log

REDISNAME=appendonly.7000

DDIR=/data/backup/redis/$CURHOUR

mkdir -p ${DDIR}

RDIR=/data/redis

cd ${RDIR}

tar -zcf $DDIR/${REDISNAME}_${CURTIME}.tar.gz appendonly.7000.aof

if [ $? != 0 ]; then

  echo "tar error $REDISNAME.aof" >> $LOGFILE

fi

sleep 5

/usr/local/bin/redis-cli -h 127.0.0.1 -p 6379 bgrewriteaof

sleep 5

 

###  delete old backup data dir  ###

#/bin/rm -rf `date -d -30day + "%Y%m%d"`

find /data/backup/redis/ -mtime +30 | xargs rm -rf

echo "Backup $REDISNAME ok at $CURTIME !" >> $LOGFILE

[root@cdn redis]# crontab -e
59 23 * * * /bin/bash /data/redis/redis_backup.sh >/dev/null 2>&1

[root@cdn redis]# cd /data/backup/redis/20161207_13
[root@cdn 20161207_13]# ls 
appendonly.7000_20161207_133131.tar.gz

-------------再看一例----------------------------------------------------------------------------------------------------------------------
公司線上一個項目數據存儲採用MySQL,共分爲10個庫,分佈在4臺機器上,每一個庫數據量約爲10G,各機器均採用RAID5加速磁盤訪問;
當同時在線人數達高峯期(10w),DB磁盤IO壓力巨大,致使訪問巨慢,,在線人數就很難上不去了。

針對上面描述狀況,使用redis後可有效解決這一瓶頸,由於Redis數據讀寫都是直接操做內。

解決方案:
將部分數據壓縮導入到redis後,總數據量約30G(轉換成redis數據類型數據量),一主一從模型,共兩組。
一臺機器內存32G,開10個實例,共20個實例,多實例方便作持久化。

一樣適用於上面的redis持久化策略調整方案(思路和上面一致)

主從庫配置:
主庫:關閉save開展,aof默認不打開,容許從庫訪問。主庫設置了密碼訪問requirepass My#redis
從庫:需增長配置:開啓AOF持久化,關閉save快照,設置密碼;
從庫10個實例的配置文件分別爲:slave6001.conf ~ slave6010.conf
slave6001.conf配置內容以下(其餘實例拷貝這個,修改端口等其餘信息便可)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

daemonize yes

pidfile /var/run/slave6001.pid

port 6001

timeout 300

loglevel debug

logfile /usr/local/redis/var/debug6001.log

syslog-enabled yes

databases 16

rdbcompression yes

dbfilename slave6001.rdb

dir /data/redis-data/slave6001

slaveof 192.168.0.139 6001

masterauth My#redis

slave-serve-stale-data yes

requirepass My#redis

appendonly yes

appendfilename slave6001.aof

appendfsync everysec

no-appendfsync-on-rewrite no

vm-enabled no

vm-swap-file /tmp/redis.swap

vm-max-memory 0

vm-page-size 32

vm-pages 134217728

vm-max-threads 4

hash-max-zipmap-entries 512

hash-max-zipmap-value 64

list-max-ziplist-entries 512

list-max-ziplist-value 64

set-max-intset-entries 512

activerehashing yes

主庫每晚12點給每一個實例手動作一次bgsave快照。主庫備份腳本(redis_bgsave.sh)

1

2

3

4

5

6

7

8

9

#!/bin/bash

#date=`date +%y%m%d_%H%M%S`

REDISPASSWORD=My#redis

for PORT in `seq 6001 6010`

do

/usr/local/redis/bin/redis-cli -h 127.0.0.1 -p $PORT -a $REDISPASSWORD bgsave

sleep 10

done

date >> /usr/local/redis/var/bgsave.log

從庫每晚12點拷貝每一個實例的AOF到其餘目錄並對其打包,壓縮包要有異地備份,以後再壓縮AOF(bgrewriteaof)。
從庫備份AOF並bgrewriteaof腳本(redis_backup.sh :對單個實例)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

#!/bin/sh

## FD:File Dir

## RD:Runing Dir

## 第一個參數爲redis實例名

if [ $# -ne 1 ]; then

echo 「Usage:$0  redis_name」

exit

fi

CURDATE=`date +%Y%m%d`

CURHOUR=`date +%Y%m%d_%H`

CURTIME=`date +%Y%m%d_%H%M%S`

REDISPASSWORD=My#redis

REDISNAME=$1

PORT=`echo $REDISNAME | cut -c6-9`

LOGFILE=/data/logs/redisbak/redis_allbak_${CURDATE}.log

if "${REDISNAME}" "" ]; then

echo 「redis name Error!」

exit 1

else

if [ ! -d "/data/redis-data/${REDISNAME}" ]; then

echo 「redis name Error!」

exit 1

fi

fi

DDIR=/data/backup/redis/$CURHOUR

mkdir -p ${DDIR}

RDIR=/data/redis-data/$REDISNAME

cd ${RDIR}

tar -zcf $DDIR/${REDISNAME}_${CURTIME}.tar.gz $REDISNAME.aof

if [ $? != 0 ]; then

echo tar error $REDISNAME.aof」 >> $LOGFILE

#exit 1

fi

sleep 5

/usr/local/redis/bin/redis-cli -h 127.0.0.1 -p $PORT -a $REDISPASSWORD bgrewriteaof

sleep 5

###  delete old backup data dir  ###

#/bin/rm -rf `date -d -7day +」%Y%m%d」`

find /data/backup/redis/ -mtime +7 | xargs rm -rf

echo 「Backup $REDISNAME ok at $CURTIME !」 >> $LOGFILE

從庫對全部實例備份(/data/sh/redis_allbak.sh)

1

2

3

4

5

6

7

#!/bin/sh

CURDATE=`date +%Y%m%d`

LOGFILE=/data/logs/redisbak/redis_allbak_${CURDATE}.log

for PORT in `seq 6001 6010`

do

/data/sh/redis_backup.sh slave${PORT} && echo 「slave${PORT} ok `date +%Y%m%d_%H%M%S`」 >> $LOGFILE 2>&1 || echo 「slave${PORT} backup error」 >> $LOGFILE 2>&1

done

操做注意事項
1)若主庫掛了,不能直接開啓主庫程序。若直接開啓主庫程序將會沖掉從庫的AOF文件,這樣將致使只能恢復到前一天晚上12的備份。
2)程序在跑時,不能重啓網絡(程序是經過網絡接口的端口進行讀寫的)。網絡中斷將致使中斷期間數據丟失。
3)肯定配置文件所有正確才啓動(尤爲不能有數據文件名相同),不然會沖掉原來的文件,可能形成沒法恢復的損失。

災難恢復
1)主庫故障,快速恢復到最近狀態描述:主庫掛了(redis程序掛了/機器宕機了),從庫正常,恢復到主庫掛掉的時間點:去從庫手動作一次快照,拷貝快照到主庫相應目錄,啓動,OK。
在從庫作一次快照,轉移快照文件到其餘目錄,將快照文件目錄拷貝到主庫相應目錄,啓動主庫,OK!
( /data/sh/redis_bgsave_cp.sh )

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

#!/bin/bash

REDISPASSWORD=My#redis

for PORT in `seq 6001 6010`

do

/usr/local/redis/bin/redis-cli -h 127.0.0.1 -p $PORT -a $REDISPASSWORD bgsave

sleep 5

done

sleep 15

for PORT in `seq 6001 6010`

do

SDIR=/data/redis-data/slave${PORT}/

DDIR=/data/redis_recovery/redis-data/

mkdir -p $DDIR/redis${PORT}/

cd $SDIR

cp -rf slave${PORT}.rdb $DDIR/redis${PORT}/redis${PORT}.rdb

#sleep 1

done

在主庫將原來數據目錄重命名。
從從庫拷貝快照文件到主庫。
啓動主庫。

2)恢復到當天12點狀態注意備份數據(當前狀態AOF+正常退出快照)!
中止redis。
解壓AOF(/data/sh/redis_untar.sh)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

#!/bin/bash

DAY=20111102

SDIR=/data/backup/redis/20161102_00/

cd $SDIR

for PORT in `seq 6001 6010`

do

tar -zxf slave${PORT}_$DAY_*.tar.gz

sleep 2

done

切割AOF(/data/sh/redis_sed.sh)

#!/bin/bash

DDIR=/data/redis_recovery/

TAG=」TAG111101_1200″

for PORT in `seq 6001 6010`

do

SDIR=/data/backup/redis/20161102_00/

SAOF=${SDIR}/slave${PORT}.aof

line=`sed -n 「/$TAG/=」 $SAOF`

num=$[$line + 3]

mkdir -p ${DDIR}/slave${PORT}/

sed 「${num},\$d」 $SAOF > ${DDIR}/slave${PORT}/slave${PORT}.aof

done

將原來數據目錄重命名。
將切割出來的AOF目錄重命名爲配置文件的數據目錄。(註釋主從同步配置項)。
啓動從庫。
作快照,拷貝到主庫,啓動主庫(同上面第1)步)。

3)恢復到兩天或幾天前12點狀態從庫每晚備份要備份AOF未bgrewriteaof以前的數據,可根據當天晚上12點備份,沒有bfrewriteaof以前的AOF文件來進行恢復,方法同上面的第2)步。

***************當你發現本身的才華撐不起野心時,就請安靜下來學習吧***************

相關文章
相關標籤/搜索