redis詳解

openkk 12年前發布 | 66K 次閱讀 Redis NoSQL數據庫

什么是redis?

redis 是一個基于內存的高性能key-value數據庫。 (有空再補充,有理解錯誤或不足歡迎指正)

 

Reids的特點

Redis本質上是一個Key-Value類型的內存數據庫,很像memcached,整個數據庫統統加載在內存當中進行操作,定期通過異步操作把數據庫 數據flush到硬盤上進行保存。因為是純內存操作,Redis的性能非常出色,每秒可以處理超過 10萬次讀寫操作,是已知性能最快的Key-Value DB。
Redis的出色之處不僅僅是性能,Redis最大的魅力是支持保存多種數據結構,此外單個value的最大限制是1GB,不像 memcached只能保存1MB的數據,因此Redis可以用來實現很多有用的功能,比方說用他的List來做FIFO雙向鏈表,實現一個輕量級的高性 能消息隊列服務,用他的Set可以做高性能的tag系統等等。另外Redis也可以對存入的Key-Value設置expire時間,因此也可以被當作一 個功能加強版的memcached來用。
Redis的主要缺點是數據庫容量受到物理內存的限制,不能用作海量數據的高性能讀寫,因此Redis適合的場景主要局限在較小數據量的高性能操作和運算上。

 

Redis支持的數據類型

Redis通過Key-Value的單值不同類型來區分, 以下是支持的類型:
Strings
Lists
Sets 求交集、并集
Sorted Set 
hashes
具體的指令說明:http://code.google.com/p/redis/wiki/CommandReference


為什么redis需要把所有數據放到內存中?

Redis為了達到最快的讀寫速度將數據都讀到內存中,并通過異步的方式將數據寫入磁盤。所以redis具有快速和數據持久化的特征。如果不將數據放在內存中,磁盤I/O速度為嚴重影響redis的性能。在內存越來越便宜的今天,redis將會越來越受歡迎。
如果設置了最大使用的內存,則數據已有記錄數達到內存限值后不能繼續插入新值。

另外講講內存中的數據如何同步到磁盤

redis在dump數據的時候,是fork子進程。redis的默認配置中,每60秒如果紀錄更改數達到1萬條就需要dump到硬盤中去,但實際上由于 超過了這個數,我們的redis幾乎不停地在dump數據到硬盤上;dump數據到硬盤時,我估計為了達到一個原子的效應,避免數據丟失,redis是先 把數據dump到一個臨時文件,然后重命名為你在配置文件設定的數據文件名.而前面說到,加載數據要1到2分鐘,dump數據應該也在1分鐘左右 吧;dump出來的文件差不多1到2個G;這樣,服務器幾乎一直保持著每分鐘寫一個2G的文件的這種IO的負載,磁盤基本不閑著;

 

Redis是單進程單線程的

redis利用隊列技術將并發訪問變為串行訪問,消除了傳統數據庫串行控制的開銷

 

虛擬內存

當你的key很小而value很大時,使用VM的效果會比較好.因為這樣節約的內存比較大.
當你的key不小時,可以考慮使用一些非常方法將很大的key變成很大的value,比如你可以考慮將key,value組合成一個新的value.
vm-max-threads這個參數,可以設置訪問swap文件的線程數,設置最好不要超過機器的核數,如果設置為0,那么所有對swap文件的操作都是串行的.可能會造成比較長時間的延遲,但是對數據完整性有很好的保證.

自己測試的時候發現用虛擬內存性能也不錯。如果數據量很大,可以考慮分布式或者其他數據庫

 

分布式

redis支持主從的模式。原則:Master會將數據同步到slave,而slave不會將數據同步到master。Slave啟動時會連接master來同步數據。

這是一個典型的分布式讀寫分離模型。我們可以利用master來插入數據,slave提供檢索服務。這樣可以有效減少單個機器的并發訪問數量

讀寫分離模型

通過增加Slave DB的數量,讀的性能可以線性增長。為了避免Master DB的單點故障,集群一般都會采用兩臺Master DB做雙機熱備,所以整個集群的讀和寫的可用性都非常高。
讀寫分離架構的缺陷在于,不管是Master還是Slave,每個節點都必須保存完整的數據,如果在數據量很大的情況下,集群的擴展能力還是受限于單個節點的存儲能力,而且對于Write-intensive類型的應用,讀寫分離架構并不適合。

                                                                 讀寫分離模型

數據分片模型

為了解決讀寫分離模型的缺陷,可以將數據分片模型應用進來。

可以將每個節點看成都是獨立的master,然后通過業務實現數據分片。

結合上面兩種模型,可以將每個master設計成由一個master和多個slave組成的模型。

 

redis的性能

這是官方給出的數據:SET操作每秒鐘 110000 次,GET操作每秒鐘 81000 次。

實驗中模擬了20個客戶端對redis進行寫操作。當數據庫中的數據達到G數據級時,寫速度會有明顯的下降。

可能的原因: 1、redis需要將數據同步到磁盤,占用了大量的CPU和內存; 2、key數量增大,需要重新布局; 3、消息隊列中還存在大量請求,致使請求阻塞。

 

 

redis應用

這里給出一個小例子,是一個基于redis的消息隊列。

python源碼:

    r = redis.Redis()  
    class Queue(object):  
        """An abstract FIFO queue"""  
        def __init__(self):  
           local_id = r.incr("queue_space")  
           id_name = "queue:%s" %(local_id)  
           self.id_name = id_name  
       def push(self, element):  
       """Push an element to the tail of the queue"""   
           id_name = self.id_name  
           push_element = redis.lpush(id_name, element)  
       def pop(self):  
       """Pop an element from the head of the queue"""  
          id_name = self.id_name  
          popped_element = redis.rpop(id_name)  
          return popped_element  

 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!