Redis:八、主從複製和虛擬內存

redis主從複製配置和使用都非常簡單。通過主從複製可以允許多個slave server擁有和master server相同的數據庫副本。下面是關於redis主從複製的一些特點
1.master可以有多個slave
2.除了多個slave連到相同的master外,slave也可以連接其他slave形成圖狀結構
3.主從複製不會阻塞master。也就是說當一個或多個slave與master進行初次同步數據時,master可以繼續處理client發來的請求。相反slave在初次同步數據時則會阻塞不能處理client的請求。
4.主從複製可以用來提高系統的可伸縮性,我們可以用多個slave 專門用於client的讀請求,比如sort操作可以使用slave來處理。也可以用來做簡單的數據冗餘
5.可以在master禁用數據持久化,只需要註釋掉master 配置文件中的所有save配置,然後只在slave上配置數據持久化。
下面介紹下主從複製的過程
       當設置好slave服務器後,slave會建立和master的連接,然後發送sync命令。無論是第一次同步建立的連接還是連接斷開後的重新連 接,master都會啓動一個後臺進程,將數據庫快照保存到文件中,同時master主進程會開始收集新的寫命令並緩存起來。後臺進程完成寫文件 後,master就發送文件給slave,slave將文件保存到磁盤上,然後加載到內存恢復數據庫快照到slave上。接着master就會把緩存的命 令轉發給slave。而且後續master收到的寫命令都會通過開始建立的連接發送給slave。從master到slave的同步數據的命令和從 client發送的命令使用相同的協議格式。當master和slave的連接斷開時slave可以自動重新建立連接。如果master同時收到多個 slave發來的同步連接命令,只會使用啓動一個進程來寫數據庫鏡像,然後發送給所有slave。
配置slave服務器很簡單,只需要在配置文件中加入如下配置

slaveof 192.168.1.1 6379  #指定master的ip和端口


虛擬內存:

首先說明下redis的虛擬內存與os的虛擬內存不是一碼事,但是思路和目的都是相同的。就是暫時把不經常訪問的數據從內存交換到磁盤中,從而騰出寶貴的 內存空間用於其他需要訪問的數據。尤其是對於redis這樣的內存數據庫,內存總是不夠用的。除了可以將數據分割到多個redis server外。另外的能夠提高數據庫容量的辦法就是使用vm把那些不經常訪問的數據交換的磁盤上。如果我們的存儲的數據總是有少部分數據被經常訪問,大 部分數據很少被訪問,對於網站來說確實總是隻有少量用戶經常活躍。當少量數據被經常訪問時,使用vm不但能提高單臺redis server數據庫的容量,而且也不會對性能造成太多影響。
        redis沒有使用os提供的虛擬內存機制而是自己在用戶態實現了自己的虛擬內存機制,作者在自己的blog專門解釋了其中原因。http://antirez.com/post/redis-virtual-memory-story.html
主要的理由有兩點
1.os 的虛擬內存是已4k頁面爲最小單位進行交換的。而redis的大多數對象都遠小於4k,所以一個os頁面上可能有多個redis對象。另外redis的集 合對象類型如list,set可能存在與多個os頁面上。最終可能造成只有10%key被經常訪問,但是所有os頁面都會被os認爲是活躍的,這樣只有內 存真正耗盡時os纔會交換頁面。
2.相比於os的交換方式。redis可以將被交換到磁盤的對象進行壓縮,保存到磁盤的對象可以去除指針和對象元數據信息。一般壓縮後的對象會比內存中的對象小10倍。這樣redis的vm會比os vm能少做很多io操作。
下面是vm相關配置
vm-enabled yes                          #開啓vm功能
vm-swap-file /tmp/redis.swap                 #交換出來的value保存的文件路徑/tmp/redis.swap
vm-max-memory 1000000                    #redis使用的最大內存上限,超過上限後redis開始交換value到磁盤文件中。
vm-page-size 32                    #每個頁面的大小32個字節
vm-pages 134217728                 #最多使用在文件中使用多少頁面,交換文件的大小 = vm-page-size * vm-pages
vm-max-threads 4                    #用於執行value對象換入換出的工作線程數量。0表示不使用工作線程(後面介紹)
       redis的vm在設計上爲了保證key的查找速度,只會將value交換到swap文件中。所以如果是內存問題是由於太多value很小的key造成 的,那麼vm並不能解決。和os一樣redis也是按頁面來交換對象的。redis規定同一個頁面只能保存一個對象。但是一個對象可以保存在多個頁面中。 在redis使用的內存沒超過vm-max-memory之前是不會交換任何value的。當超過最大內存限制後,redis會選擇較老的對象。如果兩個 對象一樣老會優先交換比較大的對象,精確的公式swappability = age*log(size_in_memory)。 對於vm-page-size的設置應該根據自己的應用將頁面的大小設置爲可以容納大多數對象的大小。太大了會浪費磁盤空間,太小了會造成交換文件出現碎 片。對於交換文件中的每個頁面,redis會在內存中對應一個1bit值來記錄頁面的空閒狀態。所以像上面配置中頁面數量(vm-pages 134217728 )會佔用16M內存用來記錄頁面空閒狀態。vm-max-threads表示用做交換任務的線程數量。如果大於0推薦設爲服務器的cpu core的數量。如果是0則交換過程在主線程進行。
參數配置討論完後,在來簡單介紹下vm是如何工作的,
當vm-max-threads設爲0時(Blocking VM)
換出
主線程定期檢查發現內存超出最大上限後,會直接已阻塞的方式,將選中的對象保存到swap文件中,並釋放對象佔用的內存,此過程會一直重複直到下面條件滿足
1.內存使用降到最大限制以下
2.swap文件滿了
3.幾乎全部的對象都被交換到磁盤了
換入
當有client請求value被換出的key時。主線程會以阻塞的方式從文件中加載對應的value對象,加載時此時會阻塞所以client。然後處理client的請求
當vm-max-threads大於0(Threaded VM)
換出
當主線程檢測到使用內存超過最大上限,會將選中的要交換的對象信息放到一個隊列中交由工作線程後臺處理,主線程會繼續處理client請求。
換入
如果有client請求的key被換出了,主線程先阻塞發出命令的client,然後將加載對象的信息放到一個隊列中,讓工作線程去加載。加載完畢後工作線程通知主線程。主線程再執行client的命令。這種方式只阻塞請求value被換出key的client
總 的來說blocking vm的方式總的性能會好一些,因爲不需要線程同步,創建線程和恢復被阻塞的client等開銷。但是也相應的犧牲了響應性。threaded vm的方式主線程不會阻塞在磁盤io上,所以響應性更好。如果我們的應用不太經常發生換入換出,而且也不太在意有點延遲的話則推薦使用blocking vm的方式。關於redis vm的更詳細介紹可以參考下面鏈接
http://antirez.com/post/redis-virtual-memory-story.html
http://redis.io/topics/internals-vm

from:http://www.cnblogs.com/xhan/archive/2011/02/07/1949717.html

redcreen

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章