新聞中心
Redis持久化是有兩種方式:RDB和AOF

對(duì)這兩種方式的官方文檔的翻譯請(qǐng)看:
http://latteye.com/2011/11/redis-persistence.html
RDB就是快照存儲(chǔ),比如“每1個(gè)小時(shí)對(duì)redis進(jìn)行快照存儲(chǔ)”。那么,
save這個(gè)參數(shù)就應(yīng)該設(shè)置save 3600 1000 //前一次快照3600秒后,當(dāng)有超過1000個(gè)key被改動(dòng)的時(shí)候就進(jìn)行一次快照更新RDB快照產(chǎn)生dump.rdb文件,當(dāng)每到快照時(shí)間,更新文件。
AOF是存儲(chǔ)所有的寫操作,分兩個(gè)步驟:fsync和rewritefsync是把內(nèi)存中的寫操作寫入aof文件中rewrite是將寫操作合并,比如set aa 1; set aa 2; 兩個(gè)操作應(yīng)該寫成一個(gè)操作set aa 2;
如果數(shù)據(jù)量小的話,啥問題也沒有
現(xiàn)在假設(shè)服務(wù)器是20G內(nèi)存,而且服務(wù)器上僅僅只有跑redis一個(gè)占內(nèi)存的進(jìn)程,就是說redis最多可以跑20G物理內(nèi)存現(xiàn)在壓入13G的redis數(shù)據(jù)(可以使用phpredis循環(huán)壓入,但是要注意設(shè)置php的運(yùn)行內(nèi)存大小,最好使用pipeline的方式,否則php出現(xiàn)內(nèi)存不足的error)
嘗試1,我們只使用RDB的方式當(dāng)進(jìn)行快照的時(shí)候(測(cè)試時(shí)候可以把快照間隔時(shí)間定成30秒或更短)top查看進(jìn)程
26376 test 16 0 13.5g 13g 7488 D 0.0 42.8 6:48.24 redis-server
32459 test 18 0 13.5g 13g 7200 D 1.3 42.8 0:23.22 redis-server
看到有兩個(gè)進(jìn)程,同時(shí)在運(yùn)行,并且占用同樣大小的內(nèi)存數(shù),和起來竟然占用26G之大~!
現(xiàn)在redis服務(wù)端上兩個(gè)進(jìn)程都運(yùn)行,看看客戶端:測(cè)試redis-cli set操作:
redis 10.1.0.108:6379> set test2 22
耗時(shí)(40.47s)近1分鐘
就是說在大數(shù)據(jù)量的時(shí)候,做RDB,redis服務(wù)會(huì)暫停近1分鐘!這個(gè)就是redis持久化的時(shí)候的服務(wù)暫?,F(xiàn)象。
好吧,為了保證數(shù)據(jù)容錯(cuò)性,我們的快照一般是要頻繁快照的,所以暫停一分鐘是不可容忍的。
現(xiàn)在嘗試使用AOF+RDB:
1 將RDB的快照時(shí)間設(shè)置為1天(由于加上了AOF,所以這個(gè)時(shí)間是合理的)。
2 1次性壓入1000w左右的string數(shù)據(jù)到redis中(大概有5G數(shù)據(jù)量)
3 查看性能表現(xiàn):
第一個(gè)步驟fsync:
redis會(huì)從內(nèi)存中逐漸生成appendonly.aof 在這個(gè)過程我試了下set和get操作都是沒有暫?,F(xiàn)象的(很好~?。?/p>
好了,現(xiàn)在appendonly.aof生成了,有5.7個(gè)G
-rw-r--r-- 1 root root 4186238374 Mar 6 15:50 appendonly.aof
第二個(gè)步驟:調(diào)用BGREWRITEAOF重寫aof文件
這個(gè)時(shí)候top查看:
看到也是兩個(gè)redis-server服務(wù)開著。說明rewrite的時(shí)候是fork一個(gè)子進(jìn)程在rewrite的,主進(jìn)程是進(jìn)行著redis服務(wù)的。
這個(gè)時(shí)候redis-cli調(diào)用檢查
get操作:無延時(shí)
set操作:出現(xiàn)了延遲現(xiàn)象 !!
這個(gè)說明AOF在重寫的時(shí)候會(huì)占用服務(wù)器的大量CPU和內(nèi)存資源,導(dǎo)致服務(wù)出現(xiàn)短暫暫?,F(xiàn)象!但是為什么get操作沒有出現(xiàn)延遲現(xiàn)象呢?參考官網(wǎng)文章,看到一個(gè)配置項(xiàng):no-appendfsync-on-rewrite
這個(gè)配置項(xiàng)是設(shè)置在rewrite的時(shí)候是否對(duì)新的寫操作進(jìn)行fsync。no表示進(jìn)行fsync,yes表示不進(jìn)行
默認(rèn)是設(shè)置為no
現(xiàn)在將這個(gè)配置項(xiàng)設(shè)置為yes(我們對(duì)于rewrite的aof文件硬盤大小沒有很大要求)
重新進(jìn)行測(cè)試:
對(duì)同樣的5.7G的AOF操作進(jìn)行一次BGREWRITEAOF。
get操作:無延遲
set操作:無延遲
很好!說明在rewrite的時(shí)候如果不進(jìn)行fsync操作,主進(jìn)程和子進(jìn)程是互不干擾的。
那么如果rewrite的時(shí)候?qū)π碌膶懖僮鞑贿M(jìn)行fsync,那么新的aof文件里面是否會(huì)丟失這個(gè)寫操作呢?
答案是不會(huì)的,redis會(huì)將新的寫操作放在內(nèi)存中,等待rewrite操作完成的時(shí)候,將新操作直接掛在aof中。
好了,至此,這個(gè)問題應(yīng)該已經(jīng)可以過去了。
推薦幾個(gè)文章:
對(duì)數(shù)據(jù)持久化的一些想法:http://www.yiihsia.com/2011/04/%E5%AF%B9redis%E6%95%B0%E6%8D%AE%E6%8C%81%E4%B9%85%E5%8C%96%E7%9A%84%E4%B8%80%E4%BA%9B%E6%83%B3%E6%B3%95/
(這個(gè)文章提供了一個(gè)非常好的方法,當(dāng)數(shù)據(jù)量大,內(nèi)存足夠的情況,一臺(tái)機(jī)子上盡量多開幾個(gè)redis,甚至可以考慮有幾個(gè)cpu就開幾個(gè)redis,這樣,每個(gè)redis的內(nèi)存量不會(huì)太大,就不會(huì)有大數(shù)據(jù)量服務(wù)暫停問題,這個(gè)也是考慮到了redis是單線程的,能盡量利用CPU)
redis的內(nèi)存陷阱:http://www.iteye.com/topic/808293
?。ㄟ@個(gè)文章很好解釋了問什么大數(shù)據(jù)量的時(shí)候會(huì)出現(xiàn)服務(wù)暫停)
Copy on write does not seem to work.: http://code.google.com/p/redis/issues/detail?id=150
出處:http://www.cnblogs.com/yjf512/
本文版權(quán)歸yjf512和cnBlog共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明
文章名稱:解決Redis持久化之大數(shù)據(jù)服務(wù)暫停問題
鏈接分享:http://m.5511xx.com/article/cdjpjpi.html


咨詢
建站咨詢
