歡迎光臨
每天分享高質量文章

告訴你Redis是一個牛逼貨

來自:Monkey_D_lufy

鏈接:https://www.jianshu.com/p/01b37cdb3f33

概述:

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

Key-Value儲存系統


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


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

為什麼要選擇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命令,向 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 操作。


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


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


PS: Redis作者antirez曾笑稱Redis為一個資料結構服務器,我認為這個還是挺準確的,Redis的所有功能就是將資料以其固有的幾種結構來儲存,並提供給用戶操作這幾種結構的接口。


redis官方:https://redis.io/
redis中文:http://www.redis.cn/


●編號373,輸入編號直達本文

●輸入m獲取文章目錄

推薦↓↓↓

Web開發

更多推薦18個技術類公眾微信

涵蓋:程式人生、演算法與資料結構、黑客技術與網絡安全、大資料技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。

赞(0)

分享創造快樂