告訴你Redis是一個牛逼貨

概述:

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

Key-Value存儲系統(tǒng)

Key-Value Store 是當下比較流行的話題,尤其在構(gòu)建諸如搜索引擎、IM、P2P、游戲服務(wù)器、SNS 等大型互聯(lián)網(wǎng)應(yīng)用以及提供云計算服務(wù)的時候,怎樣保證系統(tǒng)在海量數(shù)據(jù)環(huán)境下的高性能、高可靠性、高擴展性、高可用性、低成本成為所有系統(tǒng)架構(gòu)們挖苦心思考慮的重點,而
怎樣解決數(shù)據(jù)庫服務(wù)器的性能瓶頸是最大的挑戰(zhàn)。
Key-Value Store 更加注重對海量數(shù)據(jù)存取的性能、分布式、擴展性支持上,并不需要傳統(tǒng)關(guān)系數(shù)據(jù)庫的一些特征,例如:Schema、事務(wù)、完整 SQL 查詢支持等等,因此在分布式環(huán)境下的性能相對于傳統(tǒng)的關(guān)系數(shù)據(jù)庫有較大的提升。

為什么要選擇Key-Value Store

  1. 大規(guī)?;ヂ?lián)網(wǎng)應(yīng)用
    一類是仍然采用RDBMS,然后通過對數(shù)據(jù)庫的垂直和水平切分將整個數(shù)據(jù)庫部署到一個集群上,缺點在于它是針對特定應(yīng)用,通用型不足
    另一類就是google采用的方法,拋棄RDBMS,采用Key-Value形式存儲,這樣可以極大增強系統(tǒng)的可擴展性。
  2. 云存儲
    如果說上一個問題還有可以替代的解決方案(切割數(shù)據(jù)庫)的話,那么對于云存儲來說,也許 key-value 的 store 就是唯一的解決方案了。云存儲簡單點說就是構(gòu)建一個大型的存儲平臺給別人用,這也就意味著在這上面運行的應(yīng)用其實是不可控的。如果其中某個客戶的應(yīng)用隨著用戶的增長而不斷增長時,云存儲供應(yīng)商是沒有辦法通過數(shù)據(jù)庫的切割來達到 scale 的,因為這個數(shù)據(jù)是客戶的,供應(yīng)商不了解這個數(shù)據(jù)自然就沒法作出切割。在這種情況下,key-value 的 store 就是唯一的選擇了,因為這種條件下的 scalability 必須是自動完成的,不能有人工干預(yù)。這也是為什么幾乎所有的現(xiàn)有的云存儲都是 key-value 形式的,例如 Amazon的 smipleDB,底層實現(xiàn)就是 key-value,還有 google 的 GoogleAppEngine,采用的是 BigTable的存儲形式。

Key-Value Store 最大的特點就是它的可擴展性,這也就是它最大的優(yōu)勢。所謂的可擴展性,
在我看來這里包括了兩方面內(nèi)容。一方面,是指 Key-Value Store 可以支持極大的數(shù)據(jù)的存儲,它的分布式的架構(gòu)決定了只要有更多的機器,就能夠保證存儲更多的數(shù)據(jù)。另一方面,是指它可以支持數(shù)量很多的并發(fā)的查詢。對于 RDBMS,一般幾百個并發(fā)的查詢就可以讓它很吃
力了,而一個 Key-Value Store,可以很輕松的支持上千的并發(fā)查詢。下面而簡單的羅列了一些特點:
? Key-value store:一個 key-value 數(shù)據(jù)存儲系統(tǒng),只支持一些基本操作,如: SET(key, value) 和 GET(key) 等;
? 分布式:多臺機器(nodes)同時存儲數(shù)據(jù)和狀態(tài),彼此交換消息來保持數(shù)據(jù)一致,可視為一個完整的存儲系統(tǒng)。
? 數(shù)據(jù)一致:所有機器上的數(shù)據(jù)都是同步更新的、不用擔心得到不一致的結(jié)果;
? 冗余:所有機器(nodes)保存相同的數(shù)據(jù),整個系統(tǒng)的存儲能力取決于單臺機器(node)的能力;
? 容錯:如果有少數(shù) nodes 出錯,比如重啟、當機、斷網(wǎng)、網(wǎng)絡(luò)丟包等各種 fault/fail 都不影響整個系統(tǒng)的運行;
? 高可靠性:容錯、冗余等保證了數(shù)據(jù)庫系統(tǒng)的可靠性。

初識Redis

Redis是一個開源的使用ANSI C語言編寫,支持網(wǎng)絡(luò)、可基于內(nèi)存且可持久化的日志型、Key-Value數(shù)據(jù)庫,并且提供多個語言的API,訪問十分便捷。

Redis數(shù)據(jù)類型:

作為 Key-value 型數(shù)據(jù)庫,Redis 也提供了鍵(Key)和鍵值(Value)的映射關(guān)系。但是,除
了常規(guī)的數(shù)值或字符串,Redis 的鍵值還可以是以下形式之一:
? Lists (列表)
? Sets (集合)
? Sorted sets (有序集合)
? Hashes (哈希表)
鍵值的數(shù)據(jù)類型決定了該鍵值支持的操作。Redis 支持諸如列表、集合或有序集合的交集、并集、查集等高級原子操作;同時,如果鍵值的類型是普通數(shù)字,Redis 則提供自增等原子操作。

Redis持久化:

通常,Redis 將數(shù)據(jù)存儲于內(nèi)存中,或被配置為使用虛擬內(nèi)存。通過兩種方式可以實現(xiàn)數(shù)據(jù)持久化:使用截圖的方式,將內(nèi)存中的數(shù)據(jù)不斷寫入磁盤;或使用類似 MySQL 的日志方式,記錄每次更新的日志。前者性能較高,但是可能會引起一定程度的數(shù)據(jù)丟失;后者相反。

Redis主從同步:

Redis支持將數(shù)據(jù)同步到多臺從庫,這種特性對提高讀取性能非常有益

Redis性能:

相比需要依賴磁盤記錄每個更新的數(shù)據(jù)庫,基于內(nèi)存的特性無疑給Redis帶來了非常優(yōu)秀的性能,讀寫操作之間有顯著的性能差異
性能測試結(jié)果:

SET操作每秒鐘 110000 次,GET操作每秒鐘 81000 次,服務(wù)器配置如下:
Linux 2.6, Xeon X3320 2.5Ghz.
stackoverflow 網(wǎng)站使用 Redis 做為緩存服務(wù)器。

適用場合:

Redis其實開創(chuàng)了一種新的數(shù)據(jù)存儲思路,使用Redis,我們不用再面對功能單調(diào)的數(shù)據(jù)庫時,把精力放在如何把大象放進冰箱的問題,而是利用Redis提供的靈活多變的數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)操作,為不同的大象構(gòu)建不同的冰箱。

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

1. 取最新N個數(shù)據(jù)的操作

比如典型的取你網(wǎng)站的最新文章,通過下面方式,我們可以將最新的 5000 條評論的 ID 放在Redis 的 List 集合中,并將超出集合部分從數(shù)據(jù)庫獲取。使用 LPUSH latest.comments<ID>命令,向 list 集合中插入數(shù)據(jù)插入完成后再用 LTRIM latest.comments 0 5000 命令使其永遠只保存最近 5000 個 ID如果你還有不同的篩選維度,比如某個分類的最新 N 條,那么你可以再建一個按此分類的List,只存 ID 的話,Redis 是非常高效的。

2. 排行榜應(yīng)用,取TOP N操作

這個需求與上面需求的不同之處在于,前面操作以時間為權(quán)重,這個是以某一個條件為權(quán)重,比如按購買的次數(shù)或者頂?shù)拇螖?shù),這時候就需要 sorted set 出馬,將你要排序的值設(shè)置為sorted set的score,將具體的數(shù)據(jù)設(shè)置為相應(yīng)的value,每次只需要執(zhí)行一條ZADD命令即可。

3. 需要精確設(shè)定過期時間的應(yīng)用

比如你可以把上面說到的 sorted set 的 score 值設(shè)置成過期時間的時間戳,那么就可以簡單地通過過期時間排序,定時清除過期數(shù)據(jù)了,不僅是清除 Redis 中的過期數(shù)據(jù),你完全可以把 Redis 里這個過期時間當成是對數(shù)據(jù)庫中數(shù)據(jù)的索引,用 Redis 來找出哪些數(shù)據(jù)需要過期刪除,然后再精準地從數(shù)據(jù)庫中刪除相應(yīng)的記錄。

4.計數(shù)器應(yīng)用
Redis的命令是原子性的,你可以輕松利用INCR、DECR命令來構(gòu)建計數(shù)器系統(tǒng)(底層的寫入是單線程模型,并發(fā)寫會按到位順序執(zhí)行)

5.Uniq操作,獲取某段時間所有數(shù)據(jù)去重值

這個使用Redis的Set數(shù)據(jù)結(jié)構(gòu)最合適,只需要不斷將數(shù)據(jù)往Set中扔就行,set就是集合,會自動去重

6.實時系統(tǒng)、發(fā)垃圾系統(tǒng)

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

7.Pub、Sub構(gòu)建實時消息系統(tǒng)

Redis 的 Pub/Sub 系統(tǒng)可以構(gòu)建實時的消息系統(tǒng),比如很多用 Pub/Sub 構(gòu)建的實時聊天系統(tǒng)的例子。

8. 構(gòu)建隊列系統(tǒng)

使用list可以構(gòu)建隊列系統(tǒng),使用sorted set 甚至可以構(gòu)建有優(yōu)先級的隊列系統(tǒng)。

9. 緩存

性能優(yōu)于Memcached,并且更優(yōu)秀的在于數(shù)據(jù)結(jié)構(gòu)更加多樣化

Redis作者的宣言

宣言中,作者列舉了Redis的7大原則,可以向大家闡明Redis的思想,看了之后我覺得Redis的作者的確牛叉,Redis這款產(chǎn)品這的是程序猿的福利:

  1. Redis 是一個操作數(shù)據(jù)結(jié)構(gòu)的語言工具,它提供基于 TCP 的協(xié)議以操作豐富的數(shù)據(jù)結(jié)構(gòu)。
    在 Redis 中,數(shù)據(jù)結(jié)構(gòu)這個詞的意義不僅表示在某種數(shù)據(jù)結(jié)構(gòu)上的操作,更包括了結(jié)構(gòu)本身及這些操作的時間空間復(fù)雜度。
  2. Redis 定位于一個內(nèi)存數(shù)據(jù)庫,正是由于內(nèi)存的快速訪問特性,才使得 Redis 能夠有如此高的性能,才使得 Redis 能夠輕松處理大量復(fù)雜的數(shù)據(jù)結(jié)構(gòu),Redis 會嘗試其它的存儲方面的選擇,但是永遠不會改變它是一個內(nèi)存數(shù)據(jù)庫的角色。
  3. Redis 使用基礎(chǔ)的 API 操作基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu), Redis 的 API 與數(shù)據(jù)結(jié)構(gòu)一樣,都是一些最基礎(chǔ)的元素,你幾乎可以將任何信息交互使用此 API 格式表示。作者調(diào)侃說,如果有其它非人類的智能生物存在,他們也能理解 Redis 的 API。因為它是如此的基礎(chǔ)。(作者大大很有趣)
  4. Redis 有著詩一般優(yōu)美的代碼,經(jīng)常有一些不太了解 Redis 有的人會建議 Redis 采用一些其它人的代碼,以實現(xiàn)一些 Redis 未實現(xiàn)的功能,但這對我們來說就像是非要給《紅樓夢》接上后四十回一樣。
    5.Redis 始終避免復(fù)雜化,我們認為設(shè)計一個系統(tǒng)的本質(zhì),就是與復(fù)雜化作戰(zhàn)。我們不會為了一個小功能而往源碼里添加上千行代碼,解決復(fù)雜問題的方法就是讓復(fù)雜問題永遠不要提復(fù)雜的問題。
    6.Redis 支持兩個層成的 API,第一個層面包含部分操作 API,但它支持用于分布式環(huán)境下的 Redis。第二個層面的 API 支持更復(fù)雜的 multi-key 操作。它們各有所長,但是我們不會推出兩者都支持的 API,但我們希望能夠提供實例間數(shù)據(jù)遷移的命令,并執(zhí)行 multi-key 操作。
  5. 我們以優(yōu)化代碼為樂,我們相信編碼是一件辛苦的工作,唯一對得起這辛苦的就是去享受它。如果我們在編碼中失去了樂趣,那最好的解決辦法就是停下來。我們決不會選擇讓Redis不好玩的開發(fā)模式。

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

PS: Redis作者antirez曾笑稱Redis為一個數(shù)據(jù)結(jié)構(gòu)服務(wù)器,我認為這個還是挺準確的,Redis的所有功能就是將數(shù)據(jù)以其固有的幾種結(jié)構(gòu)來保存,并提供給用戶操作這幾種結(jié)構(gòu)的接口。

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概述:Key-Value存儲系統(tǒng)為什么要選擇Key-Value Store初識RedisRedis數(shù)據(jù)類型:Red...
    極課編程閱讀 457評論 0 0
  • 概述:Key-Value存儲系統(tǒng)為什么要選擇Key-Value Store初識RedisRedis數(shù)據(jù)類型:Red...
    G_慧慧閱讀 460評論 0 5
  • NOSQL類型簡介鍵值對:會使用到一個哈希表,表中有一個特定的鍵和一個指針指向特定的數(shù)據(jù),如redis,volde...
    MicoCube閱讀 4,150評論 2 27
  • Redis是一個 Key-Value 存儲系統(tǒng)。和 Memcached 類似,它支持存儲的 value 類型相對更...
    vivi_wong閱讀 13,477評論 2 4
  • Redis是啥 Redis是一個開源的key-value存儲系統(tǒng),由于擁有豐富的數(shù)據(jù)結(jié)構(gòu),又被其作者戲稱為數(shù)據(jù)結(jié)構(gòu)...
    一凡呀閱讀 1,232評論 0 5

友情鏈接更多精彩內(nèi)容