1. 程式人生 > >Redis初識、設計思想與一些學習資源推薦

Redis初識、設計思想與一些學習資源推薦

一、Redis簡介

1.什麼是Redis

  Redis 是一個開源的使用ANSI C 語言編寫、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value 資料庫,並提供多種語言的API。從2010 年3 月15 日起,Redis 的開發工作由VMware 主持。

  Redis 是一個Key-Value 儲存系統。和Memcached 類似,它支援儲存的value 型別相對更多, 包括string(字串)、hash(雜湊)、list(連結串列)、set(集合)和zset(有序集合)。這些資料型別支援push/pop、add/remove 及取交集並集和差集和更豐富的操作,而且這些操作都是原子性的。在此基礎上,Redis 支援各種不同方式的排序。與memcached 一樣,為了保證效率,資料都是快取在記憶體中。區別的是Redis 會週期性的把更新的資料寫入磁碟或者把修改操作寫入追加的記錄檔案,並且在此基礎上實現了master-slave(主從)同步。

2.Redis思想

  Redis 的作者antirez(Salvatore Sanfilippo)曾經發表了一篇名為Redis 宣言(Redis Manifesto) 的文章,文中列舉了Redis 的七個原則,以向大家闡明Redis的思想。

1、Redis 是一個操作資料結構的語言工具,它提供基於TCP 的協議以操作豐富的資料結構。在Redis 中,資料結構這個詞的意義不僅表示在某種資料結構上的操作,更包括了結構本身及這些操作的時間空間複雜度。

2、Redis 定位於一個記憶體資料庫,正是由於記憶體的快速訪問特性,才使得Redis 能夠有如此高的效能,才使得Redis 能夠輕鬆處理大量複雜的資料結構,Redis 會嘗試其它的儲存方面的選擇,但是永遠不會改變它是一個記憶體資料庫的角色。

3、Redis 使用基礎的API 操作基礎的資料結構,Redis 的API 與資料結構一樣,都是一些最基礎的元素,你幾乎可以將任何資訊互動使用此API 格式表示。作者調侃說,如果有其它非人類的智慧生物存在,他們也能理解Redis 的API。因為它是如此的基礎。

4、Redis 有著詩一般優美的程式碼,經常有一些不太瞭解Redis 有的人會建議Redis 採用一些其它人的程式碼,以實現一些Redis 未實現的功能,但這對我們來說就像是非要給《紅樓夢》接上後四十回一樣。

5、Redis 始終避免複雜化,我們認為設計一個系統的本質,就是與複雜化作戰。我們不會為了一個小功能而往原始碼裡新增上千行程式碼,解決複雜問題的方法就是讓複雜問題永遠不要提複雜的問題。

6、Redis 支援兩個層面的API,第一個層面包含部分操作API,但它支援用於分散式環境下的Redis。第二個層面的API 支援更復雜的multi-key 操作。它們各有所長,但是我們不會推出兩者都支援的API,但我們希望能夠提供例項間資料遷移的命令,並執行multi-key 操作。

7、我們以優化程式碼為樂,我們相信編碼是一件辛苦的工作,唯一對得起這辛苦的就是去享受它。如果我們在編碼中失去了樂趣,那最好的解決辦法就是停下來。我們決不會選擇讓Redis 不好玩的開發模式。

  Redis 的作者antirez 曾笑稱Redis 為一個數據結構伺服器(data structures server),其實可以認為這是一個非常準確的表述,Redis 的所有功能就是將資料以其固有的幾種結構來儲存,並提供給使用者操作這幾種結構的介面。本文將介紹Redis 支援的各種資料型別及其操作介面。

3.Key-Value 儲存系統簡介

  Key-Value Store 是當下比較流行的話題,尤其在構建諸如搜尋引擎、IM、P2P、遊戲伺服器、SNS 等大型網際網路應用以及提供雲端計算服務的時候,怎樣保證系統在海量資料環境下的高效能、高可靠性、高擴充套件性、高可用性、低成本成為所有系統架構們挖苦心思考慮的重點,而怎樣解決資料庫伺服器的效能瓶頸是最大的挑戰。

  按照分散式領域的CAP 理論(Consistency、 Availability、Tolerance to network Partitions 這三部分在任何系統架構實現時只可能同時滿足其中二點,沒法三者兼顧)來衡量,傳統的關係資料庫的ACID 只滿足了Consistency、Availability,因此在Partition tolerance 上就很難做得好。另外傳統的關係資料庫處理海量資料、分散式架構時候在Performance、Scalability、 Availability 等方面也存在很大的侷限性。

  而Key-Value Store 更加註重對海量資料存取的效能、分散式、擴充套件性支援上,並不需要傳統關係資料庫的一些特徵,例如:Schema、事務、完整SQL 查詢支援等等,因此在分散式環境下的效能相對於傳統的關係資料庫有較大的提升。

圖1.一些資料庫和快取伺服器的特性與功能 

4.Redis 實際應用案例

  目前全球最大的Redis 使用者是新浪微博,在新浪有200 多臺物理機,400 多個埠正在執行著Redis, 有+4G 的資料跑在Redis 上來為微博使用者提供服務。

 

圖2.新浪微博Redis應用 

  在新浪微博Redis 的部署場景很多,大概分為如下的2 種:

  第一種是應用程式直接訪問Redis 資料庫

 

圖3. 應用程式直接訪問Redis 資料庫 

  第二種是應用程式直接訪問Redis,只有當Redis 訪問失敗時才訪問MySQL

 

圖4. 應用程式訪問Redis和MySQL資料庫

二、初識Redis

1.資料型別

  作為Key-value 型資料庫,Redis 也提供了鍵(Key)和鍵值(Value)的對映關係。但是,除了常規的數值或字串,Redis 的鍵值還可以是以下形式之一:

-Lists (列表)

-Hash (雜湊)

-Sets (集合)

-Sorted sets (有序集合)

-Hashes (雜湊表)

 

圖5.Redis提供的五種結構 

  鍵值的資料型別決定了該鍵值支援的操作。Redis 支援諸如列表、集合或有序集合的交集、並集、查集等高階原子操作;同時,如果鍵值的型別是普通數字,Redis 則提供自增等原子操作。

2.持久化

  通常,Redis 將資料儲存於記憶體中,或被配置為使用虛擬記憶體。通過兩種方式可以實現資料持久化:使用截圖的方式,將記憶體中的資料不斷寫入磁碟;或使用類似MySQ-的日誌方式, 記錄每次更新的日誌。前者效能較高,但是可能會引起一定程度的資料丟失;後者相反。

3.主從同步

  Redis 支援將資料同步到多臺從庫上,這種特性對提高讀取效能非常有益。

4.效能

  相比需要依賴磁碟記錄每個更新的資料庫,基於記憶體的特性無疑給Redis 帶來了非常優秀的效能。讀寫操作之間有顯著的效能差異。

5.提供API的語言

-C

-C++

-C#

-Clojure

-Common Lisp

-Erlang

-Haskell

-Java

-Javascript

-Lua

-Objective-C

-Perl

-PHP

-Python

-Ruby

-Scala

-Go

-Tcl

6.適用場合

  毫無疑問,Redis 開創了一種新的資料儲存思路,使用Redis,我們不用在面對功能單調的資料庫時,把精力放在如何把大象放進冰箱這樣的問題上,而是利用Redis 靈活多變的資料結構和資料操作,為不同的大象構建不同的冰箱。希望你喜歡這個比喻。

  下面是Redis 適用的一些場景:

1、取最新N 個數據的操作

  比如典型的取你網站的最新文章,通過下面方式,我們可以將最新的5000 條評論的ID 放在Redis 的List 集合中,並將超出集合部分從資料庫獲取。

  使用LPUSH latest.comments<ID>命令,向list 集合中插入資料

  插入完成後再用LTRIM latest.comments 0 5000 命令使其永遠只儲存最近5000 個ID。

  如果你還有不同的篩選維度,比如某個分類的最新N 條,那麼你可以再建一個按此分類的List,只存ID 的話,Redis 是非常高效的。

2、排行榜應用,取TOP N 操作

  這個需求與上面需求的不同之處在於,前面操作以時間為權重,這個是以某個條件為權重, 比如按頂的次數排序,這時候就需要我們的sorted set 出馬了,將你要排序的值設定成sorted set 的score,將具體的資料設定成相應的value,每次只需要執行一條ZADD 命令即可。

3、需要精準設定過期時間的應用

  比如你可以把上面說到的sorted set 的score 值設定成過期時間的時間戳,那麼就可以簡單地通過過期時間排序,定時清除過期資料了,不僅是清除Redis 中的過期資料,你完全可以把Redis 裡這個過期時間當成是對資料庫中資料的索引,用Redis 來找出哪些資料需要過期刪除,然後再精準地從資料庫中刪除相應的記錄。

4、計數器應用

  Redis 的命令都是原子性的,你可以輕鬆地利用INCR,DECR 命令來構建計數器系統。

5Uniq 操作,獲取某段時間所有資料排重值

  這個使用Redis 的set 資料結構最合適了,只需要不斷地將資料往set 中扔就行了,set 意為集合,集合中的元素是唯一的,所以會自動排重。

6、實時系統,反垃圾系統

  通過上面說到的set 功能,你可以知道一個終端使用者是否進行了某個操作,可以找到其操作的集合並進行分析統計對比等。沒有做不到,只有想不到。

7Pub/Sub 構建實時訊息系統

  Redis 的Pub/Sub 系統可以構建實時的訊息系統,比如很多用Pub/Sub 構建的實時聊天系統的例子。

8、構建佇列系統

  使用list 可以構建佇列系統,使用sorted set 甚至可以構建有優先順序的佇列系統。

9、快取

  這個不必說了,效能優於Memcached,資料結構更多樣化

三、推薦一些Redis學習資源

1.網站

2.書籍

《Redis 設計與實現》                             剖析了Redis的原始碼

《Redis實戰》                                       Redis在實戰中的應用

  上面這三本書分別從入門、原始碼、 實戰三個維度講解了Redis,這也是我認為Redis非常值得學習的三個方面。redis的原始碼只有三萬多行,很值得研究學習下,同時也方便自己團隊在使用過程中去根據業務需求量身打造Redis。