告訴你Redis是多麼牛

我不喜歡以前的標題,可是一篇介紹性的文章,讀一讀還不錯。先轉載一篇介紹的文章,有機會和你們一塊兒討論下redis內部的結構和實現原理。

概述:

Redis 是一個 Key-Value 存儲系統。和 Memcached 相似,它支持存儲的 value 類型相對更多,包括 string(字符串)、 list(鏈表)、 set(集合)和 zset(有序集合)。這些數據類型都支持 push/pop、add/remove 及取交集並集和差集及更豐富的操做,並且這些操做都是原子性的。在此基礎上,Redis 支持各類不一樣方式的排序。與 memcached 同樣,爲了保證效率,數據都是緩存在內存中。區別的是 Redis 會週期性的把更新的數據寫入磁盤或者把修改操做寫入追加的記錄文件,而且在此基礎上實現了 master-slave(主從)同步。node

Key-Value存儲系統

Key-Value Store 是當下比較流行的話題,尤爲在構建諸如搜索引擎、IM、P2P、遊戲服務器、SNS 等大型互聯網應用以及提供雲計算服務的時候,怎樣保證系統在海量數據環境下的高性能、高可靠性、高擴展性、高可用性、低成本成爲全部系統架構們挖苦心思考慮的重點,而
怎樣解決數據庫服務器的性能瓶頸是最大的挑戰。
Key-Value Store 更加註重對海量數據存取的性能、分佈式、擴展性支持上,並不須要傳統關係數據庫的一些特徵,例如:Schema、事務、完整 SQL 查詢支持等等,所以在分佈式環境下的性能相對於傳統的關係數據庫有較大的提高。redis

爲何要選擇Key-Value Store

  1. 大規模互聯網應用
    一類是仍然採用RDBMS,而後經過對數據庫的垂直和水平切分將整個數據庫部署到一個集羣上,缺點在於它是針對特定應用,通用型不足
    另外一類就是google採用的方法,拋棄RDBMS,採用Key-Value形式存儲,這樣能夠極大加強系統的可擴展性。數據庫

  2. 雲存儲
    若是說上一個問題還有能夠替代的解決方案(切割數據庫)的話,那麼對於雲存儲來講,也許 key-value 的 store 就是惟一的解決方案了。雲存儲簡單點說就是構建一個大型的存儲平臺給別人用,這也就意味着在這上面運行的應用實際上是不可控的。若是其中某個客戶的應用隨着用戶的增加而不斷增加時,雲存儲供應商是沒有辦法經過數據庫的切割來達到 scale 的,由於這個數據是客戶的,供應商不瞭解這個數據天然就無法做出切割。在這種狀況下,key-value 的 store 就是惟一的選擇了,由於這種條件下的 scalability 必須是自動完成的,不能有人工干預。這也是爲何幾乎全部的現有的雲存儲都是 key-value 形式的,例如 Amazon的 smipleDB,底層實現就是 key-value,還有 google 的  GoogleAppEngine,採用的是 BigTable的存儲形式。緩存


Key-Value Store 最大的特色就是它的可擴展性,這也就是它最大的優點。所謂的可擴展性,
在我看來這裏包括了兩方面內容。一方面,是指 Key-Value Store 能夠支持極大的數據的存儲,它的分佈式的架構決定了只要有更多的機器,就可以保證存儲更多的數據。另外一方面,是指它能夠支持數量不少的併發的查詢。對於 RDBMS,通常幾百個併發的查詢就可讓它很吃
力了,而一個 Key-Value Store,能夠很輕鬆的支持上千的併發查詢。下面而簡單的羅列了一些特色:
  Key-value store:一個  key-value  數據存儲系統,只支持一些基本操做,如: SET(key, value) 和  GET(key)  等;
  分佈式:多臺機器(nodes)同時存儲數據和狀態,彼此交換消息來保持數據一致,可視爲一個完整的存儲系統。
  數據一致:全部機器上的數據都是同步更新的、不用擔憂獲得不一致的結果;
  冗餘:全部機器(nodes)保存相同的數據,整個系統的存儲能力取決於單臺機器(node)的能力;
  容錯:若是有少數  nodes  出錯,好比重啓、當機、斷網、網絡丟包等各類  fault/fail  都不影響整個系統的運行;
  高可靠性:容錯、冗餘等保證了數據庫系統的可靠性。服務器

初識Redis

Redis是一個開源的使用ANSI C語言編寫,支持網絡、可基於內存且可持久化的日誌型、Key-Value數據庫,而且提供多個語言的API,訪問十分便捷。網絡

Redis數據類型:

做爲 Key-value 型數據庫,Redis 也提供了鍵(Key)和鍵值(Value)的映射關係。可是,除
了常規的數值或字符串,Redis 的鍵值還能夠是如下形式之一:
  Lists  (列表)
  Sets  (集合)
  Sorted sets  (有序集合)
  Hashes  (哈希表)
鍵值的數據類型決定了該鍵值支持的操做。Redis 支持諸如列表、集合或有序集合的交集、並集、查集等高級原子操做;同時,若是鍵值的類型是普通數字,Redis 則提供自增等原子操做。數據結構

Redis持久化:

一般,Redis 將數據存儲於內存中,或被配置爲使用虛擬內存。經過兩種方式能夠實現數據持久化:使用截圖的方式,將內存中的數據不斷寫入磁盤;或使用相似 MySQL 的日誌方式,記錄每次更新的日誌。前者性能較高,可是可能會引發必定程度的數據丟失;後者相反。架構

Redis主從同步:

Redis支持將數據同步到多臺從庫,這種特性對提升讀取性能很是有益併發

Redis性能:

相比須要依賴磁盤記錄每一個更新的數據庫,基於內存的特性無疑給Redis帶來了很是優秀的性能,讀寫操做之間有顯著的性能差別
性能測試結果:分佈式

SET操做每秒鐘 110000 次,GET操做每秒鐘 81000 次,服務器配置以下:
Linux 2.6, Xeon X3320 2.5Ghz.
stackoverflow 網站使用 Redis 作爲緩存服務器。

適用場合:

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做者的宣言

宣言中,做者列舉了Redis的7大原則,能夠向你們闡明Redis的思想,看了以後我以爲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 操做。

  5. 咱們以優化代碼爲樂,咱們相信編碼是一件辛苦的工做,惟一對得起這辛苦的就是去享受它。若是咱們在編碼中失去了樂趣,那最好的解決辦法就是停下來。咱們決不會選擇讓Redis很差玩的開發模式。


我只能感嘆道:Redis乃神物,出污泥而不染,濯清漣而不妖

PS: Redis做者antirez曾笑稱Redis爲一個數據結構服務器,我認爲這個仍是挺準確的,Redis的全部功能就是將數據以其固有的幾種結構來保存,並提供給用戶操做這幾種結構的接口。

redis:官方傳送門
redis中文:中文傳送門


原文出處:https://www.jianshu.com/p/01b37cdb3f33  做者:Monkey_D_lufy

相關文章
相關標籤/搜索