Redis詳解

光、夜雨微涼發表於2018-05-25

   Redis詳解

    • Redis的出現

      • NoSQL資料庫瞭解

        在過去幾年中,NoSQL資料庫一度成為高併發、海量資料儲存解決方案的代名詞,與之相應的產品也如同雨後春筍般出現,然而在眾多產品中,能夠脫穎而出的卻  屈指可數,如Redis、MongoDB、BerkeleyDB和CouchDB等。由於每種產品所擁有的特性不同,因此它們的應用場景也存在著一定差異。

    1. BerkeleyDB是一種極為流行的開源嵌入式資料庫,在更多情況下可用於儲存引擎,比如BerlkeyDB再被Oracle收購之前曾作為MySQL的儲存引擎,由此可見,該產品擁有極好的併發伸縮性,支援事物及巢狀事物,海量資料儲存等重要特性,在用於儲存實時資料方面具有極高的可用價值。

    2. MongDB定義為Oriented-Document資料庫伺服器,和BerkeleyDB不同的是,該資料庫可以像其他關係型資料庫伺服器那樣獨立的執行並提供相關的資料服務。MongoDB主要適用於論壇或部落格等型別的網站,這些網站具有併發訪問量高、多讀少些、資料量大、邏輯關係簡單、以文件資料作為主要資料來源等特點,適合用MongoDB提供資料服務。

    3. Memcahced,資料快取伺服器。在使用方式上,它和Redis最為相似,它們之間最大的區別是,memcached只是提供了資料快取服務,而沒有提供任何形式的資料持久化功能,而Redis則提供了這樣的功能。一旦Memcached伺服器當機,之前在記憶體中快取的資料也將全部消失。再有就是,Redis提供了更為豐富的資料儲存結構

    4. Redis,典型的NoSQL資料庫伺服器。與BerkeleyDB相比,它可以作為服務程式獨立執行於自己的伺服器主機。Redis除了Key/Value之外還支援List、Hash、Set和Ordered Set等資料結構,因此它的用途也更廣泛。

    • Redis是什麼

      Redis是由義大利人Salvatore Sanfilippo開發的一款記憶體快取記憶體資料庫。Redis本質上是一種鍵值資料庫,但是它在保持鍵值資料庫簡單快捷特點的同時,又吸收了部分關係型數庫的優點。從而使它的位置處於關聯式資料庫和鍵值資料庫之間。Redis不僅能儲存String型別的資料,還能保持lists型別(有序)和Sets型別(無序)的資料,而且還能完成排序(sort)等高階功能,在實現INCR,SETNX等功能的時候,保證了其操作的原子性,除此之外,還支援主從複製功能。

  • Redis的特點

    1. Redis用c語言編寫,以記憶體作為資料儲存介質,所以讀寫資料的效率極高,以設定和獲取一個256位元組字串為例,它的讀取速度可高達110000次/s,寫速度高達81000次/s。

    2. 儲存在Redis中的資料是持久化的,斷電或重啟後,資料也不會丟失。因為Redis的儲存分為記憶體儲存、硬碟儲存和log檔案三部分。重啟後,Redis可以從磁碟重新將資料載入到記憶體中,保證資料不會丟失

    3. 對不同資料型別的操作都是自動的,很安全

    4. Redis支援主從模式,可以配置叢集,這樣更利於支撐大型的專案

  • Redis的優勢

    1. 豐富的資料型別 。Redis支援二進位制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 資料型別操作。

    2. Redis的所有操作都是原子性的,同時Redis還支援對幾個操作全並後的原子性執行。

    3. 豐富的特性。 Redis還支援 publish/subscribe, 通知, key 過期等等特性。

    4. 易用性極高。可以利用Redis快速的搭建平臺

    5. Redis在解決了很多通用性問題的同時,也為一些個性化問題提供了相關的解決方案,如索引引擎、統計排名、訊息佇列服務等。

  • Redis的缺點

    資料庫容量受到實體記憶體的限制,不能用作海量資料的高效能讀寫。因此Redis適合的場景主要侷限在較小資料量的高效能操作和運算上。

  • Redis的應用場景

    1. 眾多語言都支援Redis,因為Redis交換資料快,所以在伺服器中常用來儲存一些需要頻繁調取的資料,這樣可以大大節省系統直接讀取磁碟來獲得資料的I/O開銷,更重要的是可以極大提升速度。

    2. 通常侷限點來說,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使用單程式單執行緒效率也很快的原因

    1. Redis採用的是基於記憶體的單程式單執行緒模型的KV資料庫,由c語言編寫

    2. 資料結構簡單,對資料操作也很簡單

    3. 使用多路 I/O複用模型。多路 I/O 複用模型是利用select、poll、epoll可以同時監察多個流的 I/O 事件的能力,在空閒的時候,會把當前執行緒阻塞掉,當有一個或多個流有I/O事件時,就從阻塞態中喚醒,於是程式就會輪詢一遍所有的流(epoll是隻輪詢那些真正發出了事件的流),並且只依次順序的處理就緒的流,這種做法就避免了大量的無用操作。這裡“多路”指的是多個網路連線,“複用”指的是複用同一個執行緒。採用多路 I/O 複用技術可以讓單個執行緒高效的處理多個連線請求(儘量減少網路IO的時間消耗),且Redis在記憶體中運算元據的速度非常快(記憶體內的操作不會成為這裡的效能瓶頸),主要以上兩點造就了Redis具有很高的吞吐量。

  • Redis叢集方案

    • 為什麼需要叢集

      通常,為了提高網站響應速度,總是把熱點資料儲存在記憶體中而不是從後端伺服器讀取。但是在大型網站,熱點資料往往資料量巨大,這需要由多臺主機協調提供服務,這需要由多臺主機協同提供服務,即分散式多個Redis例項協同執行

    • 叢集方案

      1. 官方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。

      2. Redis Sharding叢集

        Redis Sharding可以說是Redis Cluster出來之前,業界普遍使用的多Redis例項叢集方法。其主要思想是採用雜湊演算法將Redis資料的key進行雜湊,通過hash函式,特定的key會對映到特定的Redis節點上,這樣,客戶端就知道向哪個Redis節點運算元據。

        Redis Sharding採用客戶端Sharding方式,服務端Redis還是一個個相對獨立的Redis例項節點,沒有做任何變動。同時,我們也不需要增加額外的中間處理元件,這是一種非常輕量、靈活的Redis多例項叢集方法。客戶端sharding技術其優勢在於服務端的Redis例項彼此獨立,,相互無關聯,每個Redis例項像單伺服器一樣執行,非常容易線性擴充套件,系統的靈活性很強。其不足之處在於:①由於sharding處理放到客戶端,規模進步擴大時給運維帶來挑戰。②服務端Redis例項群拓撲結構有變化時,每個客戶端都需要更新調整。③連線不能共享,當應用規模增大時,資源浪費制約優化。

      3. 利用Redis代理中介軟體twemproxy實現大規模的Redis叢集

        twemproxy處於客戶端和伺服器的中間,將客戶端發來的請求,進行一定的處理後(如sharding),再轉發給後端真正的Redis伺服器。也就是說,客戶端不直接訪問Redis伺服器,而是通過twemproxy代理中介軟體間接訪問。

        twemproxy中介軟體的內部處理是無狀態的,它本身可以很輕鬆地叢集,這樣可避免單點壓力或故障。由於使用了中介軟體,twemproxy可以通過共享與後端系統的連線,降低客戶端直接連線後端伺服器的連線數量。同時,它也提供sharding功能,支援後端伺服器叢集水平擴充套件。統一運維管理也帶來了方便。

相關文章