一、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 指令來建構計數器系統。
5、Uniq 操作,擷取某段時間所有資料排重值
這個使用Redis 的set 資料結構最合适了,隻需要不斷地将資料往set 中扔就行了,set 意為集合,集合中的元素是唯一的,是以會自動排重。
6、實時系統,反垃圾系統
通過上面說到的set 功能,你可以知道一個終端使用者是否進行了某個操作,可以找到其操作的集合并進行分析統計對比等。沒有做不到,隻有想不到。
7、Pub/Sub 建構實時消息系統
Redis 的Pub/Sub 系統可以建構實時的消息系統,比如很多用Pub/Sub 建構的實時聊天系統的例子。
8、建構隊列系統
使用list 可以建構隊列系統,使用sorted set 甚至可以建構有優先級的隊列系統。
9、緩存
這個不必說了,性能優于Memcached,資料結構更多樣化
三、推薦一些Redis學習資源
1.網站
http://redis.io Redis官網
https://github.com/antirez/redis Redis源代碼
https://github.com/huangz1990/redis-3.0-annotated 注釋版的Redis 3.0源碼
http://doc.redisfans.com Redis指令參考中文翻譯版
2.書籍
《redis入門指南(第2版)》 一本适合Redis入門的書籍
《Redis 設計與實作》 剖析了Redis的源碼
《Redis實戰》 Redis在實戰中的應用
上面這三本書分别從入門、源碼、 實戰三個次元講解了Redis,這也是我認為Redis非常值得學習的三個方面。redis的源碼隻有三萬多行,很值得研究學習下,同時也友善自己團隊在使用過程中去根據業務需求量身打造Redis。
參考資料:部分文字内容或插圖來自于以上書籍或網絡搜集