一、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。
參考資料:部分文字內容或插圖來自於以上書籍或網絡搜集