OS | soft version |
CentOS 7.5 | redis-4.0.12(目前是4.x最新) |
[root@localhost ~]# wget http://download.redis.io/releases/redis-4.0.12.tar.gz [root@localhost ~]# tar xf redis-4.0.12.tar.gz -C /usr/local/ [root@localhost ~]# cd /usr/local/ [root@localhost local]# ln -sv redis-4.0.12/ redis [root@localhost local]# cd redis [root@localhost redis]#less README.md [root@localhost redis]#yum install tcl -y #安裝依賴,須要8.5及以上版本,若是yum沒有能夠到官網去下載源碼編譯安裝 官方地址:https://sourceforge.net/projects/tcl/files/Tcl/ [root@localhost redis]#make [root@localhost redis]#make test [root@localhost redis]#make install
若是通常的學習,那就隨便用redis-server啓動一下redis,作一些實驗,這樣的話,沒什麼意義 要把redis做爲一個系統的daemon進程去運行的,每次系統啓動,redis進程一塊兒啓動 (1)redis utils目錄下,有個redis_init_script腳本 (2)將redis_init_script腳本拷貝到linux的/etc/init.d目錄中,將redis_init_script重命名爲redis_6379,6379是咱們但願這個redis實例監聽的端口號 (3)修改redis_6379腳本的第6行的REDISPORT,設置爲相同的端口號(默認就是6379) (4)建立兩個目錄:/etc/redis(存放redis的配置文件),/var/redis/6379(存放redis的持久化文件) (5)修改redis配置文件(默認在根目錄下,redis.conf),拷貝到/etc/redis目錄中,修更名稱爲6379.conf (6)修改redis.conf中的部分配置爲生產環境
bind 0.0.0.0 綁定的端口 daemonize yes 讓redis以daemon進程運行 pidfile /var/run/redis_6379.pid 設置redis的pid文件位置 port 6379 設置redis的監聽端口號 dir /var/redis/6379 設置持久化文件的存儲位置,須要手動建立 (7)啓動redis,執行cd /etc/init.d, chmod 777 redis_6379,./redis_6379 start (8)確認redis進程是否啓動,ps -ef | grep redis (9)讓redis跟隨系統啓動自動啓動 在redis_6379腳本中,最上面,加入兩行註釋 # chkconfig: 2345 90 10 # description: Redis is a persistent key-value database chkconfig redis_6379 on
[root@localhost ~]# mkdir /etc/redis/ #存放配置文件(redis.service配置文件指定)
[root@localhost ~]# mkdir /var/redis #存放持久存儲日誌目錄(dir 指令)
[root@localhost system]# cd /usr/lib/systemd/system [root@localhost system]# cat redis.service [Unit] Description=Redis persistent key-value database After=network.target After=network-online.target Wants=network-online.target [Service] Type=forking ExecStart=/usr/local/bin/redis-server /etc/redis/redis_6379.conf ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s QUIT $MAINPID PIDFile=/var/run/redis_6379.pid PrivateTmp=true [Install] WantedBy=multi-user.target [root@localhost system]# systemctl enable redis [root@localhost system]# systemctl start redis
redis-cli SHUTDOWN,鏈接本機的6379端口中止redis進程 redis-cli -h 127.0.0.1 -p 6379 SHUTDOWN,制定要鏈接的ip和端口號 redis-cli PING,ping redis的端口,看是否正常 redis-cli,進入交互式命令行 SET k1 v1 GET k1
1.配置linux
RDB默認配置,具體含義看英文註解。若是知足配置中的需求,那麼就生成一個新的dump.rdb文件,就是當前redis內存中完整的數據快照,這個操做也被稱之爲snapshotting,快照也能夠手動調用save或者bgsave命令,同步或異步執行rdb快照生成 save能夠設置多個,就是多個snapshotting檢查點,每到一個檢查點,就會去check一下,是否有指定的key數量發生了變動,若是有,就生成一個新的dump.rdb文件
二、RDB持久化機制的工做流程redis
(1)redis根據配置本身嘗試去生成rdb快照文件 (2)fork一個子進程出來 (3)子進程嘗試將數據dump到臨時的rdb快照文件中 (4)完成rdb快照文件的生成以後,就替換以前的舊的快照文件 dump.rdb,每次生成一個新的快照,都會覆蓋以前的老快照
三、基於RDB持久化機制的數據恢復實驗算法
(1)在redis中保存幾條數據,當即停掉redis進程,而後重啓redis,看看剛纔插入的數據還在不在vim
[root@localhost ~]# redis-cli 127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> set k2 v2 OK 127.0.0.1:6379> set k3 v3 OK 127.0.0.1:6379> exit [root@localhost ~]# redis-cli SHUTDOWN [root@localhost ~]# redis-cli 127.0.0.1:6379> get k1 "v1" 127.0.0.1:6379> get k2 "v2"
#能夠看到重啓後數據還在,這是由於經過redis-cli SHUTDOWN這種方式去停掉redis,實際上是一種安全退出的模式,redis在退出的時候會將內存中的數據當即生成一份完整的rdb快照
(2)在redis中再保存幾條新的數據,用kill -9粗暴殺死redis進程,模擬redis故障異常退出,致使內存數據丟失的場景centos
[root@localhost ~]# redis-cli SHUTDOWN [root@localhost ~]# systemctl start redis [root@localhost ~]# [root@localhost ~]# [root@localhost ~]# redis-cli 127.0.0.1:6379> set k4 v4 OK 127.0.0.1:6379> set k5 v5 OK 127.0.0.1:6379> exit [root@localhost ~]# kill -9 `ps aux|grep redis|grep -v grep|awk '{print $2}'` [root@localhost ~]# ps aux|grep redis root 12732 0.0 0.0 112664 972 pts/0 S+ 22:30 0:00 grep --color=auto redis [root@localhost ~]# systemctl start redis [root@localhost ~]# ps aux|grep redis root 12740 0.1 0.4 145260 7564 ? Ssl 22:30 0:00 /usr/local/bin/redis-server 0.0.0.0:6379 root 12745 0.0 0.0 112664 972 pts/0 S+ 22:30 0:00 grep --color=auto redis [root@localhost ~]# redis-cli 127.0.0.1:6379> get k4 (nil) 127.0.0.1:6379> get k5 (nil)
# 最後結果是redis進程異常被殺掉,幾條最新的數據就丟失了
1.AOF持久化配置緩存
AOF持久化,默認是關閉的,默認是打開RDB持久化 appendonly yes,能夠打開AOF持久化機制,在生產環境裏面,通常來講AOF都是要打開的,除非你說隨便丟個幾分鐘的數據也無所謂 打開AOF持久化機制以後,redis每次接收到一條寫命令,就會寫入日誌文件中,固然是先寫入os cache的,而後每隔必定時間再fsync一下 並且即便AOF和RDB都開啓了,redis重啓的時候,也是優先經過AOF進行數據恢復的,由於aof數據比較完整 能夠配置AOF的fsync策略,有三種策略能夠選擇: 一種是每次寫入一條數據就執行一次fsync; always: 每次寫入一條數據,當即將這個數據對應的寫日誌fsync到磁盤上去,性能很是很是差,吞吐量很低; 確保說redis裏的數據一條都不丟,那就只能這樣了
一種是每隔一秒執行一次fsync; everysec: 每秒將os cache中的數據fsync到磁盤,這個最經常使用的,生產環境通常都這麼配置,性能很高,QPS仍是能夠上萬的
一種是不主動執行fsync
no: 僅僅redis負責將數據寫入os cache就撒手無論了,而後後面os本身會時不時有本身的策略將數據刷入磁盤,不可控了
二、AOF持久化的數據恢復實驗安全
[root@localhost ~]# vim /etc/redis/redis_6379.conf appendonly yes appendfilename "appendonly.aof" appendfsync everysec [root@localhost ~]# systemctl stop redis [root@localhost ~]# systemctl start redis [root@localhost ~]# redis-cli 127.0.0.1:6379> get k1 #爲何如今k1的值沒有了? (nil) 127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> set k2 v2 OK 127.0.0.1:6379> exit [root@localhost ~]# kill -9 `ps aux|grep redis|grep -v grep|awk '{print $2}'` [root@localhost ~]# systemctl start redis [root@localhost ~]# redis-cli 127.0.0.1:6379> get k1 "v1" 127.0.0.1:6379> get k2 "v2" #kill -9殺掉redis進程,從新啓動redis進程,發現數據被恢復回來了,就是從AOF文件中恢復回來的 #redis進程啓動的時候,直接就會從appendonly.aof中加載全部的日誌,把內存中的數據恢復回來
#在有rdb的dump和aof的appendonly的同時,rdb裏也有部分數據,aof裏也有部分數據,這個時候其實會發現,rdb的數據不會恢復到內存中
三、AOF rewrite服務器
redis中的數據其實有限的,不少數據可能會自動過時,可能會被用戶刪除,可能會被redis用緩存清除的算法清理掉 redis中的數據會不斷淘汰掉舊的,就一部分經常使用的數據會被自動保留在redis內存中 因此可能不少以前的已經被清理掉的數據,對應的寫日誌還停留在AOF中,AOF日誌文件就一個,會不斷的膨脹,到很大很大 因此AOF會自動在後臺每隔必定時間作rewrite操做,好比日誌裏已經存放了針對100w數據的寫日誌了; redis內存只剩下10萬; 基於內存中當前的10萬數據構建一套最新的日誌,到AOF中; 覆蓋以前的老日誌; 確保AOF日誌文件不會過大,保持跟redis內存數據量一致 redis 2.4以前,還須要手動,開發一些腳本,crontab,經過BGREWRITEAOF命令去執行AOF rewrite,可是redis 2.4以後,會自動進行rewrite操做 在redis.conf中,能夠配置rewrite策略 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb 好比說上一次AOF rewrite以後,是128mb 而後就會接着128mb繼續寫AOF的日誌,若是發現增加的比例,超過了以前的100%,256mb,就可能會去觸發一次rewrite 可是此時還要去跟min-size,64mb去比較,256mb > 64mb,纔會去觸發rewrite (1)redis fork一個子進程 (2)子進程基於當前內存中的數據,構建日誌,開始往一個新的臨時的AOF文件中寫入日誌 (3)redis主進程,接收到client新的寫操做以後,在內存中寫入日誌,同時新的日誌也繼續寫入舊的AOF文件 (4)子進程寫完新的日誌文件以後,redis主進程將內存中的新日誌再次追加到新的AOF文件中 (5)用新的日誌文件替換掉舊的日誌文件
四、AOF破損文件的修復app
若是redis在append數據到AOF文件時,機器宕機了,可能會致使AOF文件破損 用redis-check-aof --fix命令來修復破損的AOF文件
[root@localhost ~]# redis-check-aof --fix /var/redis/appendonly.aof
AOF analyzed: size=81, ok_up_to=81, diff=0
AOF is validless
五、AOF和RDB同時工做
(1)若是RDB在執行snapshotting操做,那麼redis不會執行AOF rewrite; 若是redis再執行AOF rewrite,那麼就不會執行RDB snapshotting (2)若是RDB在執行snapshotting,此時用戶執行BGREWRITEAOF命令,那麼等RDB快照生成以後,纔會去執行AOF rewrite (3)同時有RDB snapshot文件和AOF日誌文件,那麼redis重啓的時候,會優先使用AOF進行數據恢復,由於其中的日誌更完整
1.備份方案
RDB很是適合作冷備,每次生成以後,就不會再有修改了 數據備份方案 (1)寫crontab定時調度腳本去作數據備份 (2)每小時都copy一份rdb的備份,到一個目錄中去,僅僅保留最近48小時的備份 (3)天天都保留一份當日的rdb的備份,到一個目錄中去,僅僅保留最近1個月的備份 (4)每次copy備份的時候,都把太舊的備份給刪了 (5)天天晚上將當前服務器上全部的數據備份,發送一份到遠程的雲服務上去
2.數據恢復方案
(1)若是是redis進程掛掉,那麼重啓redis進程便可,直接基於AOF日誌文件恢復數據,不演示了,在AOF數據恢復那一塊,演示了,fsync everysec,最多就丟一秒的數 (2)若是是redis進程所在機器掛掉,那麼重啓機器後,嘗試重啓redis進程,嘗試直接基於AOF日誌文件進行數據恢復,AOF沒有破損,也是能夠直接基於AOF恢復的,AOF append-only,順序寫入,若是AOF文件破損,那麼用redis-check-aof fix (3)若是redis當前最新的AOF和RDB文件出現了丟失/損壞,那麼能夠嘗試基於該機器上當前的某個最新的RDB數據副本進行數據恢復,當前最新的AOF和RDB文件都出現了丟失/損壞到沒法恢復,找到RDB最新的一份備份,小時級的備份能夠了,小時級的確定是最新的,copy到redis裏面去,就能夠恢復到某一個小時的數據
3.數據恢復的坑
appendonly.aof + dump.rdb,優先用appendonly.aof去恢復數據,可是咱們發現redis自動生成的appendonly.aof是沒有數據的 而後咱們本身的dump.rdb是有數據的,可是明顯沒用咱們的數據 redis啓動的時候,自動從新基於內存的數據,生成了一份最新的rdb快照,直接用空的數據,覆蓋掉了咱們有數據的,拷貝過去的那份dump.rdb 你中止redis以後,其實應該先刪除appendonly.aof,而後將咱們的dump.rdb拷貝過去,而後再重啓redis 很簡單,就是雖然你刪除了appendonly.aof,可是由於打開了aof持久化,redis就必定會優先基於aof去恢復,即便文件不在,那就建立一個新的空的aof文件 中止redis,暫時在配置中關閉aof,而後拷貝一份rdb過來,再重啓redis,數據能不能恢復過來,能夠恢復過來 腦子一熱,再關掉redis,手動修改配置文件,打開aof,再重啓redis,數據又沒了,空的aof文件,全部數據又沒了 在數據安全丟失的狀況下,基於rdb冷備,如何完美的恢復數據,同時還保持aof和rdb的雙開 中止redis,關閉aof,拷貝rdb備份,重啓redis,確認數據恢復,直接在命令行熱修改redis配置,打開aof,這個redis就會將內存中的數據對應的日誌,寫入aof文件中 此時aof和rdb兩份數據文件的數據就同步了,同步後關閉Redis,修改配置文件開啓aof,再啓動Redis就OK了
熱修改命令
[root@localhost ~]# redis-cli 127.0.0.1:6379> CONFIG GET appendonly 1) "appendonly" 2) "no" 127.0.0.1:6379> CONFIG SET appendonly yes