在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ 大數(shù)據(jù)/ 從入門(mén)到精通(下)
使用 Redis 實(shí)現(xiàn) Twitter(上)
集群(下)
使用 Redis 實(shí)現(xiàn) Twitter(下)
使用 Redis 作為 LRU 緩存
高可用(上)
高可用客戶(hù)端指引
集群(中)
高可用(下)
持久化
Redis 介紹
集中插入
集群(上)
從入門(mén)到精通(上)
從入門(mén)到精通(下)
從入門(mén)到精通(中)
分片
數(shù)據(jù)類(lèi)型初探
復(fù)制

從入門(mén)到精通(下)

Redis 有序集合 (Sorted sets)

有序集合類(lèi)似于集合和哈希的混合體的一種數(shù)據(jù)類(lèi)型。像集合一樣,有序集合由唯一的,不重復(fù)的字符串元素組成,在某種意義上,有序集合也就是集合。

集合中的每個(gè)元素是無(wú)序的,但有序集合中的每個(gè)元素都關(guān)聯(lián)了一個(gè)浮點(diǎn)值,稱(chēng)為分?jǐn)?shù)(score,這就是為什么該類(lèi)型也類(lèi)似于哈希,因?yàn)槊恳粋€(gè)元素都映射到一個(gè)值)。

此外,有序集合中的元素是按序存儲(chǔ)的(不是請(qǐng)求時(shí)才排序的,順序是依賴(lài)于表示有序集合的數(shù)據(jù)結(jié)構(gòu))。他們按照如下規(guī)則排序:

  • 如果 A 和 B 是擁有不同分?jǐn)?shù)的元素,A.score > B.score,則 A > B。
  • 如果 A 和 B 是有相同的分?jǐn)?shù)的元素,如果按字典順序 A 大于 B,則 A > B。A 和 B 不能相同,因?yàn)榕判蚣现荒苡形ㄒ辉亍?/li>

讓我們開(kāi)始一個(gè)簡(jiǎn)單的例子,添加一些黑客的名字作為有序集合的元素,以他們的出生年份為分?jǐn)?shù)。

> zadd hackers 1940 "Alan Kay"  
(integer) 1  
> zadd hackers 1957 "Sophie Wilson"  
(integer 1)  
> zadd hackers 1953 "Richard Stallman"  
(integer) 1  
> zadd hackers 1949 "Anita Borg"  
(integer) 1  
> zadd hackers 1965 "Yukihiro Matsumoto"  
(integer) 1  
> zadd hackers 1914 "Hedy Lamarr"  
(integer) 1  
> zadd hackers 1916 "Claude Shannon"  
(integer) 1  
> zadd hackers 1969 "Linus Torvalds"  
(integer) 1  
> zadd hackers 1912 "Alan Turing"  
(integer) 1  

如你所見(jiàn),ZADD 命令類(lèi)似于 SADD,但是多一個(gè)參數(shù)(位于添加的元素之前),即分?jǐn)?shù)。ZADD 命令也是可變參數(shù)的,所以你可以自由的指定多個(gè)分?jǐn)?shù)值對(duì)(score-value pairs),盡管上面的例子中并沒(méi)有使用。

使用排序集合可以很容易返回按照出生年份排序的黑客列表,因?yàn)樗麄円呀?jīng)是排序好的。

實(shí)現(xiàn)注意事項(xiàng):有序集合是通過(guò)雙端(dual-ported)數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的,包括跳躍表(skiplist,后續(xù)文章會(huì)詳細(xì)介紹,譯者注)和哈希表(hashtable),所以我們每次添加元素時(shí) Redis 執(zhí)行 O(log(N)) 的操作。這還好,但是當(dāng)我們請(qǐng)求有序元素時(shí),Redis 根本不需要做什么工作,因?yàn)橐呀?jīng)是全部有序了:

> zrange hackers 0 -1  
1) "Alan Turing"  
2) "Hedy Lamarr"  
3) "Claude Shannon"  
4) "Alan Kay"  
5) "Anita Borg"  
6) "Richard Stallman"  
7) "Sophie Wilson"  
8) "Yukihiro Matsumoto"  
9) "Linus Torvalds"  

注意:0 和 - 1 表示從索引為 0 的元素到最后一個(gè)元素(-1 像 LRANGE 命令中一樣工作)。

如果我想按照相反的順序排序,從最年輕到最年長(zhǎng)?使用 ZREVRANGE 代替 ZRANGE:

> zrevrange hackers 0 -1  
1) "Linus Torvalds"  
2) "Yukihiro Matsumoto"  
3) "Sophie Wilson"  
4) "Richard Stallman"  
5) "Anita Borg"  
6) "Alan Kay"  
7) "Claude Shannon"  
8) "Hedy Lamarr"  
9) "Alan Turing"  

也可以同時(shí)返回分?jǐn)?shù),使用 WITHSCORES 參數(shù):

> zrange hackers 0 -1 withscores  
1) "Alan Turing"  
2) "1912"  
3) "Hedy Lamarr"  
4) "1914"  
5) "Claude Shannon"  
6) "1916"  
7) "Alan Kay"  
8) "1940"  
9) "Anita Borg"  
10) "1949"  
11) "Richard Stallman"  
12) "1953"  
13) "Sophie Wilson"  
14) "1957"  
15) "Yukihiro Matsumoto"  
16) "1965"  
17) "Linus Torvalds"  
18) "1969"  

范圍操作 (ranges)

有序集合遠(yuǎn)比這些要強(qiáng)大。他們可以在范圍上操作。讓我們獲取 1950 年前出生的所有人。我們使用 ZRANGEBYSCORE 命令來(lái)辦到:

> zrangebyscore hackers -inf 1950  
1) "Alan Turing"  
2) "Hedy Lamarr"  
3) "Claude Shannon"  
4) "Alan Kay"  
5) "Anita Borg"  

我們要求 Redis 返回分?jǐn)?shù)在負(fù)無(wú)窮到 1950 之間的所有元素(包括兩個(gè)極端)。

也可以刪除某個(gè)范圍的元素。讓我們從有序集合中刪除出生于 1940 年到 1960 年之間的黑客:

> zremrangebyscore hackers 1940 1960  
(integer) 4  

ZREMRANGEBYSCORE 也許不是最合適的命令名,但是非常有用,返回刪除的元素?cái)?shù)目。

另一個(gè)非常有用的操作是用來(lái)獲取有序集合中元素排行的操作。也就是可以詢(xún)問(wèn)集合中元素的排序位置。

> zrank hackers "Anita Borg"  
(integer) 4  

ZREVRANK 命令用來(lái)按照降序排序返回元素的排行。

字典分?jǐn)?shù) (Lexicographical scores)

最近的 Redis2.8 版本引入了一個(gè)新的特性,假定集合中的元素都具有相同的分?jǐn)?shù),允許按字典順序獲取范圍(元素按照 C 語(yǔ)言中的 memcmp 函數(shù)進(jìn)行比較,因此可以保證沒(méi)有整理,每個(gè) Redis 實(shí)例會(huì)有相同的輸出)。

操作字典順序范圍的主要命令是 ZRANGEBYLEX,ZREVRANGEBYLEX,ZREMRANGEBYLEX 和 ZLEXCOUNT。例如,我們?cè)俅翁砑游覀兊闹诳颓鍐?。但是這次為每個(gè)元素使用 0 分?jǐn)?shù):

> zadd hackers 0 "Alan Kay" 0 "Sophie Wilson" 0 "Richard Stallman" 0  
  "Anita Borg" 0 "Yukihiro Matsumoto" 0 "Hedy Lamarr" 0 "Claude Shannon"  
  0 "Linus Torvalds" 0 "Alan Turing"  

根據(jù)有序集合的排序規(guī)則,他們已經(jīng)按照字典順序排好了:

> zrange hackers 0 -1  
1) "Alan Kay"  
2) "Alan Turing"  
3) "Anita Borg"  
4) "Claude Shannon"  
5) "Hedy Lamarr"  
6) "Linus Torvalds"  
7) "Richard Stallman"  
8) "Sophie Wilson"  
9) "Yukihiro Matsumoto"  

使用 ZRANGEBYLEX 我們可以查詢(xún)字典順序范圍:

> zrangebylex hackers [B [P  
1) "Claude Shannon"  
2) "Hedy Lamarr"  
3) "Linus Torvalds"  

范圍可以是包容性的或者排除性的(取決于第一個(gè)字符,即開(kāi)閉區(qū)間,譯者注),+ 和 - 分別表示正無(wú)窮和負(fù)無(wú)窮。查看該命令的文檔獲取更詳細(xì)信息(該文檔后續(xù)即奉獻(xiàn),譯者注)。

這個(gè)特性非常重要,因?yàn)檫@允許有序集合作為通用索引。例如,如果你想用一個(gè) 128 位無(wú)符號(hào)整數(shù)來(lái)索引元素,你需要做的就是使用相同的分?jǐn)?shù)(例如 0)添加元素到有序集合中,元素加上由 128 位大端(big endian)數(shù)字組成的 8 字節(jié)前綴。由于數(shù)字是大端編碼,字典順序排序(原始 raw 字節(jié)順序)其實(shí)就是數(shù)字順序,你可以在 128 位空間查詢(xún)范圍,獲取元素后拋棄前綴。如果你想在一個(gè)更正式的例子中了解這個(gè)特性,可以看看 Redis 自動(dòng)完成范例(后續(xù)獻(xiàn)上,譯者注)。

更新分?jǐn)?shù):排行榜 (leader boards)

這一部分是開(kāi)始新的主題前最后一個(gè)關(guān)于有序集合的內(nèi)容。有序集合的分?jǐn)?shù)可以隨時(shí)更新。對(duì)一個(gè)存在于有序集合中的元素再次調(diào)用 ZADD,將會(huì)在 O(log(N))時(shí)間復(fù)雜度更新他的分?jǐn)?shù) (和位置),所以有序集合適合于經(jīng)常更新的場(chǎng)合。

由于這個(gè)特性,通常的一個(gè)使用場(chǎng)景就是排行榜。最典型的應(yīng)用就是 facebook 游戲,你可以組合使用按分?jǐn)?shù)高低存儲(chǔ)用戶(hù),以及獲取排名的操作,來(lái)展示前 N 名的用戶(hù)以及用戶(hù)在排行榜上的排行(你是第 4932 名最佳分?jǐn)?shù))。

位圖 (Bitmaps)

位圖不是一個(gè)真實(shí)的數(shù)據(jù)類(lèi)型,而是定義在字符串類(lèi)型上的面向位的操作的集合。由于字符串類(lèi)型是二進(jìn)制安全的二進(jìn)制大對(duì)象(blobs),并且最大長(zhǎng)度是 512MB,適合于設(shè)置 232 個(gè)不同的位。

位操作分為兩組:常量時(shí)間單個(gè)位的操作,像設(shè)置一個(gè)位為 1 或者 0,或者獲取該位的值。對(duì)一組位的操作,例如計(jì)算指定范圍位的置位數(shù)量。

位圖的最大優(yōu)勢(shì)是有時(shí)是一種非常顯著的節(jié)省空間來(lái)存儲(chǔ)信息的方式。例如,在一個(gè)系統(tǒng)中,不同用戶(hù)由遞增的用戶(hù) ID 來(lái)表示,可以使用 512MB 的內(nèi)存來(lái)表示 400 萬(wàn)用戶(hù)的單個(gè)位信息(例如他們是否需要接收信件)。

設(shè)置和檢索位使用 SETBIT 和 GETBIT 命令:

> setbit key 10 1  
(integer) 1  
> getbit key 10  
(integer) 1  
> getbit key 11  
(integer) 0  

SETBIT 命令把第一個(gè)參數(shù)作為位數(shù),第二個(gè)參數(shù)作為要給位設(shè)置的值,0 或者 。如果位的位置超過(guò)了當(dāng)前字符串的長(zhǎng)度,這個(gè)命令或自動(dòng)擴(kuò)充這個(gè)字符串。

GETBIT 命令只是返貨指定下標(biāo)處的位的值。超出范圍的位(指定的位超出了該鍵下字符串的長(zhǎng)度)被認(rèn)為是 0。

有 3 個(gè)操作一組位的命令:

  1. BITOP 命令對(duì)不同字符串執(zhí)行逐位操。提供的操作包括與,或,異或和非。
  2. BITCOUNT 命令執(zhí)行計(jì)數(shù)操作,返回被設(shè)置為 1 的位的數(shù)量。
  3. BITPOS 命令找到第一個(gè)值為指定值(0 或者 1)的位。

BITOPS 和 BITCOUNT 命令都可以操作字符串的字節(jié)范圍,而不僅僅是運(yùn)行于整個(gè)字符串長(zhǎng)度。下面是 BITCOUNT 調(diào)用的一個(gè)簡(jiǎn)單例子:

> setbit key 0 1  
(integer) 0  
> setbit key 100 1  
(integer) 0  
> bitcount key  
(integer) 2  

位圖的通用場(chǎng)景:

  • 各種實(shí)時(shí)分析
  • 需要高性能和高效率的空間利用來(lái)存儲(chǔ)與對(duì)象 ID 關(guān)聯(lián)的布爾信息。

例如,假設(shè)你想知道你的網(wǎng)站的用戶(hù)的最長(zhǎng)日訪(fǎng)問(wèn)曲線(xiàn)。你從 0 開(kāi)始計(jì)算天數(shù),也就是你的網(wǎng)站可訪(fǎng)問(wèn)的那天,并且每當(dāng)用戶(hù)訪(fǎng)問(wèn)你的網(wǎng)站的時(shí)候,就用 SETBIT 命令設(shè)置一個(gè)位。你可以使用當(dāng)前 unix 時(shí)間減去初始位移,然后除以 3600*24,作為位的下標(biāo)。

這種方式下每個(gè)用戶(hù)都有一個(gè)記錄每天訪(fǎng)問(wèn)信息的一個(gè)小字符串。使用 BITCOUNT 命令以及幾次 BITPOS 調(diào)用,可以很容易獲得指定用戶(hù)訪(fǎng)問(wèn)網(wǎng)站的天數(shù),或者只是獲取并在客戶(hù)端分析位圖,也很容易計(jì)算出最長(zhǎng)曲線(xiàn)。

位圖可以很容易的拆分為多個(gè)鍵,例如為了數(shù)據(jù)集分片,因?yàn)橥ǔR苊馐褂煤艽蟮逆I。為了將位圖拆分為不同的鍵,而不是將所有的位設(shè)置到一個(gè)鍵,一個(gè)簡(jiǎn)單的策略就是每個(gè)鍵只存儲(chǔ) M 位,并且使用位數(shù)除以 M 作為鍵名,在鍵中使用位數(shù)模 M 來(lái)定位第 N 位。

超重對(duì)數(shù) (HyperLogLogs)

超重對(duì)數(shù)是用于計(jì)算唯一事物數(shù)量的概率性數(shù)據(jù)結(jié)構(gòu)(學(xué)術(shù)上指的是估算集合的基數(shù))。通常計(jì)算唯一項(xiàng)數(shù)量需要使用和你想計(jì)算的項(xiàng)成正比的大量?jī)?nèi)存,因?yàn)槟阈枰涀∧阋呀?jīng)看到的元素,以避免被多次計(jì)算。然而,有一組用內(nèi)存換精度的算法:你會(huì)得到一個(gè)估算的測(cè)量,伴隨一個(gè)標(biāo)準(zhǔn)錯(cuò)誤,在 Redis 的實(shí)現(xiàn)中誤差低于 1%,但是這些算法的魔力在于,你不再需要使用和你要計(jì)算的量成比例的大量?jī)?nèi)存,你只需要使用常量?jī)?nèi)存!最壞情況下 12K 字節(jié),或者當(dāng)你的超重對(duì)數(shù)(后續(xù)稱(chēng)它們?yōu)?HLL)只發(fā)現(xiàn)了少量元素時(shí)更是省內(nèi)存。

Redis 中的超重對(duì)數(shù),雖然技術(shù)上是一個(gè)不同的數(shù)據(jù)結(jié)構(gòu),但被編碼為 Redis 字符串,所以你可以調(diào)用 GET 來(lái)序列化超重對(duì)數(shù),使用 SET 反序列化回服務(wù)器。

從概念上講,超重對(duì)數(shù)的 API 像是使用集合來(lái)做同樣的事情。你會(huì) SADD 元素到集合,使用 SCARD 來(lái)檢查集合中元素?cái)?shù)量,這些元素都是唯一的,因?yàn)?SCARD 捕獲重復(fù)添加已經(jīng)添加的元素。

你并沒(méi)有真正添加項(xiàng)到超重對(duì)數(shù)中,因?yàn)檫@種數(shù)據(jù)結(jié)構(gòu)只是包含了狀態(tài)而沒(méi)有包含真正的元素,其 API 也是一樣:

  • 每次你看到一個(gè)新元素,你就使用 PFADD 命令添加。
  • 每次你想檢索到目前為止當(dāng)前近似的已添加進(jìn)去的唯一元素?cái)?shù),你就使用 PFCOUNT 命令。
redis> PFADD hll a b c d  
(integer) 1  
redis> PFCOUNT hll  
(integer) 4  

這種數(shù)據(jù)結(jié)構(gòu)的使用場(chǎng)景的一個(gè)例子是,計(jì)算每天搜索的唯一請(qǐng)求數(shù)。

Redis 也可以執(zhí)行超重對(duì)數(shù)的并集,更多信息請(qǐng)繼續(xù)關(guān)注相關(guān)命令(請(qǐng)關(guān)注此公眾號(hào),逐一揭曉)。

其他值得注意的特性 (notable features)

還有一些重要的 Redis API 沒(méi)有在此文中探索,但是非常值得你關(guān)注:

你可以增量迭代鍵空間或者一個(gè)很大的集合。

你可以在服務(wù)端運(yùn)行 Lua 腳本以贏得延遲和帶寬。

Redis 還是也是一個(gè)訂閱發(fā)布服務(wù)器。

了解更多 (Learn more)

這個(gè)教程并不完整,只涵蓋了基本的 API。閱讀命令參考去發(fā)現(xiàn)更多。

歡迎閱讀此教程,和 Redis 一起狂舞!

上一篇:分片下一篇:高可用(上)