Redis詳解 Redis的出現 NoSQL資料庫瞭解 在過去幾年中,NoSQL資料庫一度成為高併發、海量數據存儲解決方案的代名詞,與之相應的產品也如同雨後春筍般出現,然而在眾多產品中,能夠脫穎而出的卻 屈指可數,如Redis、MongoDB、BerkeleyDB和CouchDB等。由於每種產品所擁 ...
-
-
Redis的出現
-
NoSQL資料庫瞭解
在過去幾年中,NoSQL資料庫一度成為高併發、海量數據存儲解決方案的代名詞,與之相應的產品也如同雨後春筍般出現,然而在眾多產品中,能夠脫穎而出的卻 屈指可數,如Redis、MongoDB、BerkeleyDB和CouchDB等。由於每種產品所擁有的特性不同,因此它們的應用場景也存在著一定差異。
-
-
BerkeleyDB是一種極為流行的開源嵌入式資料庫,在更多情況下可用於存儲引擎,比如BerlkeyDB再被Oracle收購之前曾作為MySQL的存儲引擎,由此可見,該產品擁有極好的併發伸縮性,支持事物及嵌套事物,海量數據存儲等重要特性,在用於存儲實時數據方面具有極高的可用價值。
-
MongDB定義為Oriented-Document資料庫伺服器,和BerkeleyDB不同的是,該資料庫可以像其他關係型資料庫伺服器那樣獨立的運行並提供相關的數據服務。MongoDB主要適用於論壇或博客等類型的網站,這些網站具有併發訪問量高、多讀少些、數據量大、邏輯關係簡單、以文檔數據作為主要數據源等特點,適合用MongoDB提供數據服務。
-
Memcahced,數據緩存伺服器。在使用方式上,它和Redis最為相似,它們之間最大的區別是,memcached只是提供了數據緩存服務,而沒有提供任何形式的數據持久化功能,而Redis則提供了這樣的功能。一旦Memcached伺服器宕機,之前在記憶體中緩存的數據也將全部消失。再有就是,Redis提供了更為豐富的數據存儲結構
-
Redis,典型的NoSQL資料庫伺服器。與BerkeleyDB相比,它可以作為服務程式獨立運行於自己的伺服器主機。Redis除了Key/Value之外還支持List、Hash、Set和Ordered Set等數據結構,因此它的用途也更廣泛。
-
-
-
Redis是什麼
Redis是由義大利人Salvatore Sanfilippo開發的一款記憶體高速緩存資料庫。Redis本質上是一種鍵值資料庫,但是它在保持鍵值資料庫簡單快捷特點的同時,又吸收了部分關係型數庫的優點。從而使它的位置處於關係資料庫和鍵值資料庫之間。Redis不僅能保存String類型的數據,還能保持lists類型(有序)和Sets類型(無序)的數據,而且還能完成排序(sort)等高級功能,在實現INCR,SETNX等功能的時候,保證了其操作的原子性,除此之外,還支持主從複製功能。
-
-
Redis的特點
-
Redis用c語言編寫,以記憶體作為數據存儲介質,所以讀寫數據的效率極高,以設置和獲取一個256位元組字元串為例,它的讀取速度可高達110000次/s,寫速度高達81000次/s。
-
存儲在Redis中的數據是持久化的,斷電或重啟後,數據也不會丟失。因為Redis的存儲分為記憶體存儲、硬碟存儲和log文件三部分。重啟後,Redis可以從磁碟重新將數據載入到記憶體中,保證數據不會丟失
-
對不同數據類型的操作都是自動的,很安全
-
Redis支持主從模式,可以配置集群,這樣更利於支撐大型的項目
-
-
Redis的優勢
-
豐富的數據類型 。Redis支持二進位案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操作。
-
Redis的所有操作都是原子性的,同時Redis還支持對幾個操作全並後的原子性執行。
-
豐富的特性。 Redis還支持 publish/subscribe, 通知, key 過期等等特性。
-
易用性極高。可以利用Redis快速的搭建平臺
-
Redis在解決了很多通用性問題的同時,也為一些個性化問題提供了相關的解決方案,如索引引擎、統計排名、消息隊列服務等。
-
-
Redis的缺點
資料庫容量受到物理記憶體的限制,不能用作海量數據的高性能讀寫。因此Redis適合的場景主要局限在較小數據量的高性能操作和運算上。
-
Redis的應用場景
-
眾多語言都支持Redis,因為Redis交換數據快,所以在伺服器中常用來存儲一些需要頻繁調取的數據,這樣可以大大節省系統直接讀取磁碟來獲得數據的I/O開銷,更重要的是可以極大提升速度。
-
通常局限點來說,Redis以消息隊列的形式存在,作為內嵌的List存在,滿足實時的高併發需求,而通常在一個電商類型的數據處理過程中,有關商品,熱銷,推薦排序的隊列,通常放在Redis之中,期間也包括Storm對於Redis列表的讀取和更新。對於這種熱點數據完全可以存到Redis(記憶體)中,要用的時候,直接從記憶體取,將會極大的提高了速度和節約了伺服器的開銷。
-
-
Redis的兩種持久化方式及原理
Redis數據可以持久化,而且支持的數據類型很豐富。有字元串,鏈表,集 合和有序集合。支持在伺服器端計算集合的並,交和補集(difference)等,還支持多種排序功能。所以Redis也可以被看成是一個數據結構伺服器。
-
第一種方式 ==> filesnapshotting
預設redis會以快照的形式將數據持久到硬碟(一個二進位文件,dump.rdb,這個文件名字可以指定),在配置文件中的格式是:save N M表示在N秒之內,redis至少發生M次修改則redis抓快照到磁碟。當然我們也可以手動執行save或者bgsave(非同步)做快照。
工作原理:當redis需要做持久化時,redis會fork一個子進程;子進程將數據寫到磁碟上一個臨時RDB文件中;當子進程完成寫臨時文件後,將原來的RDB替換掉
-
第二種方式 ==> Append-only
filesnapshotting方法在redis異常死掉時,最近的數據會丟失(丟失數據的多少視你save策略的配置),所以這是它最大的缺點,當業務量很大時,丟失的數據是很多的。Append-only方法可以做到全部數據不丟失,但redis的性能就要差些。AOF就可以做到全程持久化,只需要在配置文件中開啟(預設是no),appendonly yes開啟AOF之後,redis每執行一個修改數據的命令,都會把它添加到aof文件中,當redis重啟時,將會讀取AOF文件進行“重放”以恢復到redis關閉前的最後時刻。
AOF文件刷新的方式,有三種,參考配置參數appendfsync :appendfsync always每提交一個修改 命令都調用fsync刷新到AOF文件,非常非常慢,但也非常安全;appendfsync everysec每秒鐘都調用fsync刷新到AOF文件,很快,但可能會丟失一秒以內的數據;appendfsync no依靠OS進行刷新,redis不主動刷新AOF,這樣最快,但安全性就差。預設並推薦每秒刷新,這樣在速度和安全上都做到了兼顧。
工作原理:首先redis會fork一個子進程;子進程將最新的AOF寫入一個臨時文件;父進程增量的把記憶體中的最新執行的修改寫入(這時仍寫入舊的AOF,rewrite如果失敗也是安全的);當子進程完成rewrite臨時文件後,父進程會收到一個信號,並把之前記憶體中增量的修改寫入臨時文件末尾;這時redis將舊AOF文件重命名,臨時文件重命名,開始向新的AOF中寫入。
-
-
Redis使用單進程單線程效率也很快的原因
-
Redis採用的是基於記憶體的單進程單線程模型的KV資料庫,由c語言編寫
-
數據結構簡單,對數據操作也很簡單
-
使用多路 I/O復用模型。多路 I/O 復用模型是利用select、poll、epoll可以同時監察多個流的 I/O 事件的能力,在空閑的時候,會把當前線程阻塞掉,當有一個或多個流有I/O事件時,就從阻塞態中喚醒,於是程式就會輪詢一遍所有的流(epoll是只輪詢那些真正發出了事件的流),並且只依次順序的處理就緒的流,這種做法就避免了大量的無用操作。這裡“多路”指的是多個網路連接,“復用”指的是復用同一個線程。採用多路 I/O 復用技術可以讓單個線程高效的處理多個連接請求(儘量減少網路IO的時間消耗),且Redis在記憶體中操作數據的速度非常快(記憶體內的操作不會成為這裡的性能瓶頸),主要以上兩點造就了Redis具有很高的吞吐量。
-
-
Redis集群方案
-
為什麼需要集群
通常,為了提高網站響應速度,總是把熱點數據保存在記憶體中而不是從後端伺服器讀取。但是在大型網站,熱點數據往往數據量巨大,這需要由多台主機協調提供服務,這需要由多台主機協同提供服務,即分散式多個Redis實例協同運行
-
集群方案
-
官方Redis集群方案 Redis Cluster
Redis Cluster可以說是服務端Sharding分片技術的體現,即將鍵值按照一定演算法合理的分配到各個實例分片上,同時各個實例節點協調溝通,共同對外承擔一致服務。Redis Cluster中,Sharding採用slot(槽)的概念,一共分成16384個槽,對於每個進入Redis的鍵值對,根據key進行散列,分配到這16384個slot的某一個中。使用的hash演算法也比較簡單,就是CRC16後16384取模。
Redis集群中的每個node(節點)負責分攤這16384個slot中的一部分,也就是說,每個slot都對應一個node負責處理,當動態添加或者減少node節點時,需要將16384個槽再分配,槽中的鍵值也要遷移。Redis集群,要保證16834個槽對應的node都正常工作,如果某個node發生故障,那它負責的slots也就失效,這個集群將不能工作
為了增加集群的可訪問性,推薦方案是將node配置成主從結構。即一個master主節點,掛n個slave從節點。這時,如果主節點失效,Redis Cluster會根據選舉演算法從slave節點中選擇一個上升為主節點,整個集群繼續對外提供服務。
Redis Cluster的新節點識別能力,故障判斷能力及故障轉移能力是通過集群中的每個node都在和其他nodes進行通信,這別稱為集群匯流排。們使用特殊的埠號,即對外服務埠號加10000。nodes之間的通信採用特殊的二進位協議。
對於客戶端來說,整個cluster被看做一個整體,客戶端可以連接任意一個node進行操作,就像操作單一Redis實例一樣,當客戶端操作的key沒有分配到該node上時,Redis會返迴轉向指令,指向正確的node。
-
Redis Sharding集群
Redis Sharding可以說是Redis Cluster出來之前,業界普遍使用的多Redis實例集群方法。其主要思想是採用哈希演算法將Redis數據的key進行散列,通過hash函數,特定的key會映射到特定的Redis節點上,這樣,客戶端就知道向哪個Redis節點操作數據。
Redis Sharding採用客戶端Sharding方式,服務端Redis還是一個個相對獨立的Redis實例節點,沒有做任何變動。同時,我們也不需要增加額外的中間處理組件,這是一種非常輕量、靈活的Redis多實例集群方法。客戶端sharding技術其優勢在於服務端的Redis實例彼此獨立,,相互無關聯,每個Redis實例像單伺服器一樣運行,非常容易線性擴展,系統的靈活性很強。其不足之處在於:①由於sharding處理放到客戶端,規模進步擴大時給運維帶來挑戰。②服務端Redis實例群拓撲結構有變化時,每個客戶端都需要更新調整。③連接不能共用,當應用規模增大時,資源浪費制約優化。
-
利用Redis代理中間件twemproxy實現大規模的Redis集群
twemproxy處於客戶端和伺服器的中間,將客戶端發來的請求,進行一定的處理後(如sharding),再轉發給後端真正的Redis伺服器。也就是說,客戶端不直接訪問Redis伺服器,而是通過twemproxy代理中間件間接訪問。
twemproxy中間件的內部處理是無狀態的,它本身可以很輕鬆地集群,這樣可避免單點壓力或故障。由於使用了中間件,twemproxy可以通過共用與後端系統的連接,降低客戶端直接連接後端伺服器的連接數量。同時,它也提供sharding功能,支持後端伺服器集群水平擴展。統一運維管理也帶來了方便。
-
-