1. 程式人生 > >生產環境redis搭建

生產環境redis搭建

1、安裝單機版redis2、redis的生產環境啟動方案3、redis cli的使用------------------------------------------------------------------------1、安裝單機版redis大家可以自己去官網下載tar -xzvf tcl8.6.1-src.tar.gzcd  /usr/local/tcl8.6.1/unix/./configure  make && make install使用redis-3.2.8.tar.gztar -zxvf redis-3.2.8.tar.gzcd redis-3.2.8make && make test && make install------------------------------------------------------------------------2、redis的生產環境啟動方案如果一般的學習課程,你就隨便用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中的部分配置為生產環境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 databasechkconfig redis_6379 on------------------------------------------------------------------------3、redis cli的使用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 v1GET k1redis持久化的意義,在於資料備份、故障恢復持久化主要是做災難恢復,資料恢復,也可以歸類到高可用的一個環節裡面去比如你redis整個掛了,然後redis就不可用了,你要做的事情是讓redis變得可用,儘快變得可用重啟redis,儘快讓它對外提供服務,但是就像上一講說,如果你沒做資料備份,這個時候redis啟動了,也不可用啊,資料都沒了很可能說,大量的請求過來,快取全部無法命中,在redis里根本找不到資料,這個時候就死定了,快取雪崩問題,所有請求,沒有在redis命中,就會去mysql資料庫這種資料來源頭中去找,一下子mysql承接高併發,然後就掛了mysql掛掉,你都沒法去找資料恢復到redis裡面去,redis的資料從哪兒來?從mysql來。。。如果你把redis的持久化做好,備份和恢復方案做到企業級的程度,那麼即使你的redis故障了,也可以通過備份資料,快速恢復,一旦恢復立即對外提供服務RDB持久化機制,對redis中的資料執行週期性的持久化 ->就是每隔幾分鐘或者幾小時生成一次redis記憶體中所有資料的快照
AOF機制對每條寫入命令作為日誌,以append-only的模式寫入一個日誌檔案中,在redis重啟的時候,可以通過回放AOF日誌中的寫入指令來重新構建整個資料集
1、RDB和AOF兩種持久化機制的介紹RDB持久化機制,對redis中的資料執行週期性的持久化AOF機制對每條寫入命令作為日誌,以append-only的模式寫入一個日誌檔案中,在redis重啟的時候,可以通過回放AOF日誌中的寫入指令來重新構建整個資料集如果我們想要redis僅僅作為純記憶體的快取來用,那麼可以禁止RDB和AOF所有的持久化機制通過RDB或AOF,都可以將redis記憶體中的資料給持久化到磁碟上面來,然後可以將這些資料備份到別的地方去,比如說阿里雲,雲服務如果redis掛了,伺服器上的記憶體和磁碟上的資料都丟了,可以從雲服務上拷貝回來之前的資料,放到指定的目錄中,然後重新啟動redis,redis就會自動根據持久化資料檔案中的資料,去恢復記憶體中的資料,繼續對外提供服務如果同時使用RDB和AOF兩種持久化機制,那麼在redis重啟的時候,會使用AOF來重新構建資料,因為AOF中的資料更加完整-------------------------------------------------------------------------------------2、RDB持久化機制的優點
(1)RDB會生成多個數據檔案,每個資料檔案都代表了某一個時刻中redis的資料,這種多個數據檔案的方式,非常適合做冷備,可以將這種完整的資料檔案傳送到一些遠端的安全儲存上去,比如說Amazon的S3雲服務上去,在國內可以是阿里雲的ODPS分散式儲存上,以預定好的備份策略來定期備份redis中的資料(2)RDB對redis對外提供的讀寫服務,影響非常小,可以讓redis保持高效能,因為redis主程序只需要fork一個子程序,讓子程序執行磁碟IO操作來進行RDB持久化即可(3)相對於AOF持久化機制來說,直接基於RDB資料檔案來重啟和恢復redis程序,更加快速-------------------------------------------------------------------------------------3、RDB持久化機制的缺點
(1)如果想要在redis故障時,儘可能少的丟失資料,那麼RDB沒有AOF好。一般來說,RDB資料快照檔案,都是每隔5分鐘,或者更長時間生成一次,這個時候就得接受一旦redis程序宕機,那麼會丟失最近5分鐘的資料(2)RDB每次在fork子程序來執行RDB快照資料檔案生成的時候,如果資料檔案特別大,可能會導致對客戶端提供的服務暫停數毫秒,或者甚至數秒-------------------------------------------------------------------------------------4、AOF持久化機制的優點(1)AOF可以更好的保護資料不丟失,一般AOF會每隔1秒,通過一個後臺執行緒執行一次fsync操作,最多丟失1秒鐘的資料(2)AOF日誌檔案以append-only模式寫入,所以沒有任何磁碟定址的開銷,寫入效能非常高,而且檔案不容易破損,即使檔案尾部破損,也很容易修復(3)AOF日誌檔案即使過大的時候,出現後臺重寫操作,也不會影響客戶端的讀寫。因為在rewrite log的時候,會對其中的指導進行壓縮,創建出一份需要恢復資料的最小日誌出來。再建立新日誌檔案的時候,老的日誌檔案還是照常寫入。當新的merge後的日誌檔案ready的時候,再交換新老日誌檔案即可。(4)AOF日誌檔案的命令通過非常可讀的方式進行記錄,這個特性非常適合做災難性的誤刪除的緊急恢復。比如某人不小心用flushall命令清空了所有資料,只要這個時候後臺rewrite還沒有發生,那麼就可以立即拷貝AOF檔案,將最後一條flushall命令給刪了,然後再將該AOF檔案放回去,就可以通過恢復機制,自動恢復所有資料-------------------------------------------------------------------------------------5、AOF持久化機制的缺點(1)對於同一份資料來說,AOF日誌檔案通常比RDB資料快照檔案更大(2)AOF開啟後,支援的寫QPS會比RDB支援的寫QPS低,因為AOF一般會配置成每秒fsync一次日誌檔案,當然,每秒一次fsync,效能也還是很高的(3)以前AOF發生過bug,就是通過AOF記錄的日誌,進行資料恢復的時候,沒有恢復一模一樣的資料出來。所以說,類似AOF這種較為複雜的基於命令日誌/merge/回放的方式,比基於RDB每次持久化一份完整的資料快照檔案的方式,更加脆弱一些,容易有bug。不過AOF就是為了避免rewrite過程導致的bug,因此每次rewrite並不是基於舊的指令日誌進行merge的,而是基於當時記憶體中的資料進行指令的重新構建,這樣健壯性會好很多。-------------------------------------------------------------------------------------6、RDB和AOF到底該如何選擇(1)不要僅僅使用RDB,因為那樣會導致你丟失很多資料(2)也不要僅僅使用AOF,因為那樣有兩個問題,第一,你通過AOF做冷備,沒有RDB做冷備,來的恢復速度更快; 第二,RDB每次簡單粗暴生成資料快照,更加健壯,可以避免AOF這種複雜的備份和恢復機制的bug(3)綜合使用AOF和RDB兩種持久化機制,用AOF來保證資料不丟失,作為資料恢復的第一選擇; 用RDB來做不同程度的冷備,在AOF檔案都丟失或損壞不可用的時候,還可以使用RDB來進行快速的資料恢復1、如何配置RDB持久化機制redis.conf檔案,也就是/etc/redis/6379.conf,去配置持久化save 60 1000每隔60s,如果有超過1000個key發生了變更,那麼就生成一個新的dump.rdb檔案,就是當前redis記憶體中完整的資料快照,這個操作也被稱之為snapshotting,快照也可以手動呼叫save或者bgsave命令,同步或非同步執行rdb快照生成save可以設定多個,就是多個snapshotting檢查點,每到一個檢查點,就會去check一下,是否有指定的key數量發生了變更,如果有,就生成一個新的dump.rdb檔案------------------------------------------------------------------------2、RDB持久化機制的工作流程(1)redis根據配置自己嘗試去生成rdb快照檔案(2)fork一個子程序出來(3)子程序嘗試將資料dump到臨時的rdb快照檔案中(4)完成rdb快照檔案的生成之後,就替換之前的舊的快照檔案dump.rdb,每次生成一個新的快照,都會覆蓋之前的老快照------------------------------------------------------------------------3、基於RDB持久化機制的資料恢復實驗(1)在redis中儲存幾條資料,立即停掉redis程序,然後重啟redis,看看剛才插入的資料還在不在資料還在,為什麼?帶出來一個知識點,通過redis-cli SHUTDOWN這種方式去停掉redis,其實是一種安全退出的模式,redis在退出的時候會將記憶體中的資料立即生成一份完整的rdb快照/var/redis/6379/dump.rdb(2)在redis中再儲存幾條新的資料,用kill -9粗暴殺死redis程序,模擬redis故障異常退出,導致記憶體資料丟失的場景這次就發現,redis程序異常被殺掉,資料沒有進dump檔案,幾條最新的資料就丟失了(2)手動設定一個save檢查點,save 5 1(3)寫入幾條資料,等待5秒鐘,會發現自動進行了一次dump rdb快照,在dump.rdb中發現了資料(4)異常停掉redis程序,再重新啟動redis,看剛才插入的資料還在1、AOF持久化的配置AOF持久化,預設是關閉的,預設是開啟RDB持久化appendonly yes,可以開啟AOF持久化機制,在生產環境裡面,一般來說AOF都是要開啟的,除非你說隨便丟個幾分鐘的資料也無所謂開啟AOF持久化機制之後,redis每次接收到一條寫命令,就會寫入日誌檔案中,當然是先寫入os cache的,然後每隔一定時間再fsync一下而且即使AOF和RDB都開啟了,redis重啟的時候,也是優先通過AOF進行資料恢復的,因為aof資料比較完整可以配置AOF的fsync策略,有三種策略可以選擇,一種是每次寫入一條資料就執行一次fsync; 一種是每隔一秒執行一次fsync; 一種是不主動執行fsyncalways: 每次寫入一條資料,立即將這個資料對應的寫日誌fsync到磁碟上去,效能非常非常差,吞吐量很低; 確保說redis裡的資料一條都不丟,那就只能這樣了mysql -> 記憶體策略,大量磁碟,QPS到多少,一兩k。QPS,每秒鐘的請求數量redis -> 記憶體,磁碟持久化,QPS到多少,單機,一般來說,上萬QPS沒問題everysec: 每秒將os cache中的資料fsync到磁碟,這個最常用的,生產環境一般都這麼配置,效能很高,QPS還是可以上萬的no: 僅僅redis負責將資料寫入os cache就撒手不管了,然後後面os自己會時不時有自己的策略將資料刷入磁碟,不可控了------------------------------------------------------------------------------2、AOF持久化的資料恢復實驗(1)先僅僅開啟RDB,寫入一些資料,然後kill -9殺掉redis程序,接著重啟redis,發現數據沒了,因為RDB快照還沒生成(2)開啟AOF的開關,啟用AOF持久化(3)寫入一些資料,觀察AOF檔案中的日誌內容其實你在appendonly.aof檔案中,可以看到剛寫的日誌,它們其實就是先寫入os cache的,然後1秒後才fsync到磁碟中,只有fsync到磁碟中了,才是安全的,要不然光是在os cache中,機器只要重啟,就什麼都沒了(4)kill -9殺掉redis程序,重新啟動redis程序,發現數據被恢復回來了,就是從AOF檔案中恢復回來的redis程序啟動的時候,直接就會從appendonly.aof中載入所有的日誌,把記憶體中的資料恢復回來------------------------------------------------------------------------------3、AOF rewriteredis中的資料其實有限的,很多資料可能會自動過期,可能會被使用者刪除,可能會被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 100auto-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)用新的日誌檔案替換掉舊的日誌檔案------------------------------------------------------------------------------4、AOF破損檔案的修復如果redis在append資料到AOF檔案時,機器宕機了,可能會導致AOF檔案破損用redis-check-aof --fix命令來修復破損的AOF檔案------------------------------------------------------------------------------5、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進行資料恢復,因為其中的日誌更完整------------------------------------------------------------------------------6、最後一個小實驗,讓對redis的資料恢復有更加深刻的體會(1)在有rdb的dump和aof的appendonly的同時,rdb裡也有部分資料,aof裡也有部分資料,這個時候其實會發現,rdb的資料不會恢復到記憶體中(2)我們模擬讓aof破損,然後fix,有一條資料會被fix刪除(3)再次用fix得aof檔案去重啟redis,發現數據只剩下一條了資料恢復完全是依賴於底層的磁碟的持久化的,主要rdb和aof上都沒有資料,那就沒了1、企業級的持久化的配置策略在企業中,RDB的生成策略,用預設的也差不多save 60 10000:如果你希望儘可能確保說,RDB最多丟1分鐘的資料,那麼儘量就是每隔1分鐘都生成一個快照,低峰期,資料量很少,也沒必要10000->生成RDB,1000->RDB,這個根據你自己的應用和業務的資料量,你自己去決定AOF一定要開啟,fsync,everysecauto-aof-rewrite-percentage 100: 就是當前AOF大小膨脹到超過上次100%,上次的兩倍auto-aof-rewrite-min-size 64mb: 根據你的資料量來定,16mb,32mb2、企業級的資料備份方案RDB非常適合做冷備,每次生成之後,就不會再有修改了資料備份方案(1)寫crontab定時排程指令碼去做資料備份(2)每小時都copy一份rdb的備份,到一個目錄中去,僅僅保留最近48小時的備份(3)每天都保留一份當日的rdb的備份,到一個目錄中去,僅僅保留最近1個月的備份(4)每次copy備份的時候,都把太舊的備份給刪了(5)每天晚上將當前伺服器上所有的資料備份,傳送一份到遠端的雲服務上去/usr/local/redis每小時copy一次備份,刪除48小時前的資料crontab -e0 * * * * sh /usr/local/redis/copy/redis_rdb_copy_hourly.shredis_rdb_copy_hourly.sh#!/bin/shcur_date=`date +%Y%m%d%k`rm -rf /usr/local/redis/snapshotting/$cur_datemkdir /usr/local/redis/snapshotting/$cur_datecp /var/redis/6379/dump.rdb /usr/local/redis/snapshotting/$cur_datedel_date=`date -d -48hour +%Y%m%d%k`rm -rf /usr/local/redis/snapshotting/$del_date每天copy一次備份crontab -e0 0 * * * sh /usr/local/redis/copy/redis_rdb_copy_daily.shredis_rdb_copy_daily.sh#!/bin/shcur_date=`date +%Y%m%d`rm -rf /usr/local/redis/snapshotting/$cur_datemkdir /usr/local/redis/snapshotting/$cur_datecp /var/redis/6379/dump.rdb /usr/local/redis/snapshotting/$cur_datedel_date=`date -d -1month +%Y%m%d`rm -rf /usr/local/redis/snapshotting/$del_date每天一次將所有資料上傳一次到遠端的雲伺服器上去3、資料恢復方案(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檔案都出現了丟失/損壞到無法恢復,一般不是機器的故障,人為大資料系統,hadoop,有人不小心就把hadoop中儲存的大量的資料檔案對應的目錄,rm -rf一下,我朋友的一個小公司,運維不太靠譜,許可權也弄的不太好/var/redis/6379下的檔案給刪除了找到RDB最新的一份備份,小時級的備份可以了,小時級的肯定是最新的,copy到redis裡面去,就可以恢復到某一個小時的資料容災演練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 config set熱修改配置引數,可能配置檔案中的實際的引數沒有被持久化的修改,再次停止redis,手動修改配置檔案,開啟aof的命令,再次重啟redis(4)如果當前機器上的所有RDB檔案全部損壞,那麼從遠端的雲服務上拉取最新的RDB快照回來恢復資料(5)如果是發現有重大的資料錯誤,比如某個小時上線的程式一下子將資料全部汙染了,資料全錯了,那麼可以選擇某個更早的時間點,對資料進行恢復舉個例子,12點上線了程式碼,發現程式碼有bug,導致程式碼生成的所有的快取資料,寫入redis,全部錯了找到一份11點的rdb的冷備,然後按照上面的步驟,去恢復到11點的資料,不就可以了嗎