久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Redis中的5種數據類型怎么應用

161次閱讀
沒有評論

共計 12065 個字符,預計需要花費 31 分鐘才能閱讀完成。

本文丸趣 TV 小編為大家詳細介紹“Redis 中的 5 種數據類型怎么應用”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Redis 中的 5 種數據類型怎么應用”文章能幫助大家解決疑惑,下面跟著丸趣 TV 小編的思路慢慢深入,一起來學習新知識吧。

MySql+Memcached 架構的問題

實際 MySQL 是適合進行海量數據存儲的,通過 Memcached 將熱點數據加載到 cache,加速訪問,很多公司都曾經使用過這樣的架構,但隨著業務數據量的不斷增加,和訪問量的持續增長,我們遇到了很多問題:

1.MySQL 需要不斷進行拆庫拆表,Memcached 也需不斷跟著擴容,擴容和維護工作占據大量開發時間。

2.Memcached 與 MySQL 數據庫數據一致性問題。

3.Memcached 數據命中率低或 down 機,大量訪問直接穿透到 DB,MySQL 無法支撐。

4. 跨機房 cache 同步問題。

眾多 NoSQL 百花齊放,如何選擇

最近幾年,業界不斷涌現出很多各種各樣的 NoSQL 產品,那么如何才能正確地使用好這些產品,最大化地發揮其長處,是我們需要深入研究和思考的問題,實際歸根結底最重要的是了解這些產品的定位,并且了解到每款產品的 tradeoffs,在實際應用中做到揚長避短,總體上這些 NoSQL 主要用于解決以下幾種問題

1. 少量數據存儲,高速讀寫訪問。此類產品通過數據全部 in-momery 的方式來保證高速訪問,同時提供數據落地的功能,實際這正是 Redis 最主要的適用場景。【相關推薦:Redis 視頻教程】

2. 海量數據存儲,分布式系統支持,數據一致性保證,方便的集群節點添加 / 刪除。

3. 這方面最具代表性的是 dynamo 和 bigtable 2 篇論文所闡述的思路。前者是一個完全無中心的設計,節點之間通過 gossip 方式傳遞集群信息,數據保證最終一致性,后者是一個中心化的方案設計,通過類似一個分布式鎖服務來保證強一致性, 數據寫入先寫內存和 redo log,然后定期 compat 歸并到磁盤上,將隨機寫優化為順序寫,提高寫入性能。

4.Schema free,auto-sharding 等。比如目前常見的一些文檔數據庫都是支持 schema-free 的,直接存儲 json 格式數據,并且支持 auto-sharding 等功能,比如 mongodb。

Redis 最適合所有數據 in-momory 的場景,雖然 Redis 也提供持久化功能,但實際更多的是一個 disk-backed 的功能,跟傳統意義上的持久化有比較大的差別,那么可能大家就會有疑問,似乎 Redis 更像一個加強版的 Memcached,那么何時使用 Memcached, 何時使用 Redis 呢?

如果簡單地比較 Redis 與 Memcached 的區別,大多數都會得到以下觀點:

1、Redis 不僅僅支持簡單的 k / v 類型的數據,同時還提供 list,set,zset,hash 等數據結構的存儲。
    2、Redis 支持數據的備份,即 master-slave 模式的數據備份。
    3、Redis 支持數據的持久化,可以將內存中的數據保持在磁盤中,重啟的時候可以再次加載進行使用。

通過一張圖了解下 Redis 內部內存管理中是如何描述這些不同數據類型的:

首先 Redis 內部使用一個 redisObject 對象來表示所有的 key 和 value,redisObject 最主要的信息如上圖所示:type 代表一個 value 對象具體是何種數據類型,encoding 是不同數據類型在 redis 內部的存儲方式,比如:type=string 代表 value 存儲的是一個普通字符串,那么對應的 encoding 可以是 raw 或者是 int,如果是 int 則代表實際 redis 內部是按數值型類存儲和表示這個字符串的,當然前提是這個字符串本身可以用數值表示,比如: 123 456 這樣的字符串。

這里需要特殊說明一下 vm 字段,只有打開了 Redis 的虛擬內存功能,此字段才會真正的分配內存,該功能默認是關閉狀態的。通過上圖我們可以發現 Redis 使用 redisObject 來表示所有的 key/value 數據是比較浪費內存的,當然這些內存管理成本的付出主要也是為了給 Redis 不同數據類型提供一個統一的管理接口,實際作者也提供了多種方法幫助我們盡量節省內存使用,我們隨后會具體討論。

Redis 支持 5 種數據類型:string(字符串),hash(哈希),list(列表),set(集合)及 zset(sorted set:有序集合)。

① string 是 redis 最基本的類型,你可以理解成與 Memcached 一模一樣的類型,一個 key 對應一個 value。value 其實不僅是 String,也可以是數字。string 類型是二進制安全的。意思是 redis 的 string 可以包含任何數據。比如 jpg 圖片或者序列化的對象。string 類型是 Redis 最基本的數據類型,string 類型的值最大能存儲 512MB。

常用命令:get、set、incr、decr、mget 等。

應用場景:String 是最常用的一種數據類型,普通的 key/ value 存儲都可以歸為此類,即可以完全實現目前 Memcached 的功能,并且效率更高。還可以享受 Redis 的定時持久化,操作日志及 Replication 等功能。除了提供與 Memcached 一樣的 get、set、incr、decr 等操作外,Redis 還提供了下面一些操作:

獲取字符串長度

往字符串 append 內容

設置和獲取字符串的某一段內容

設置及獲取字符串的某一位(bit)

批量設置一系列字符串的內容

使用場景:常規 key-value 緩存應用。常規計數: 微博數, 粉絲數。

實現方式:String 在 redis 內部存儲默認就是一個字符串,被 redisObject 所引用,當遇到 incr,decr 等操作時會轉成數值型進行計算,此時 redisObject 的 encoding 字段為 int。

redis 127.0.0.1:6379  SET name  runoob 
 OK redis 127.0.0.1:6379  GET name
 runoob

在以上實例中我們使用了 Redis 的 SET 和 GET 命令。鍵為 name,對應的值為 runoob。

注意:一個鍵最大能存儲 512MB。

② Redis hash 是一個鍵值 (key = value) 對集合。Redis hash 是一個 string 類型的 field 和 value 的映射表,hash 特別適合用于存儲對象。

常用命令:hget,hset,hgetall 等。

應用場景:我們簡單舉個實例來描述下 Hash 的應用場景,比如我們要存儲一個用戶信息對象數據,包含以下信息:

用戶 ID 為查找的 key,存儲的 value 用戶對象包含姓名,年齡,生日等信息,如果用普通的 key/value 結構來存儲,主要有以下 2 種存儲方式:

第一種方式將用戶 ID 作為查找 key, 把其他信息封裝成一個對象以序列化的方式存儲,這種方式的缺點是,增加了序列化 / 反序列化的開銷,并且在需要修改其中一項信息時,需要把整個對象取回,并且修改操作需要對并發進行保護,引入 CAS 等復雜問題。

第二種方法是這個用戶信息對象有多少成員就存成多少個 key-value 對兒,用用戶 ID+ 對應屬性的名稱作為唯一標識來取得對應屬性的值,雖然省去了序列化開銷和并發問題,但是用戶 ID 為重復存儲,如果存在大量這樣的數據,內存浪費還是非常可觀的。

那么 Redis 提供的 Hash 很好的解決了這個問題,Redis 的 Hash 實際是內部存儲的 Value 為一個 HashMap,并提供了直接存取這個 Map 成員的接口,如下圖:

也就是說,Key 仍然是用戶 ID, value 是一個 Map,這個 Map 的 key 是成員的屬性名,value 是屬性值,這樣對數據的修改和存取都可以直接通過其內部 Map 的 Key(Redis 里稱內部 Map 的 key 為 field), 也就是通過 key(用戶 ID) + field(屬性標簽) 就可以操作對應屬性數據了,既不需要重復存儲數據,也不會帶來序列化和并發修改控制的問題,很好的解決了問題。

這里同時需要注意,Redis 提供了接口 (hgetall) 可以直接取到全部的屬性數據,但是如果內部 Map 的成員很多,那么涉及到遍歷整個內部 Map 的操作,由于 Redis 單線程模型的緣故,這個遍歷操作可能會比較耗時,而另其它客戶端的請求完全不響應,這點需要格外注意。

使用場景:存儲部分變更數據,如用戶信息等。

實現方式:上面已經說到 Redis Hash 對應 Value 內部實際就是一個 HashMap,實際這里會有 2 種不同實現,這個 Hash 的成員比較少時 Redis 為了節省內存會采用類似一維數組的方式來緊湊存儲,而不會采用真正的 HashMap 結構,對應的 value redisObject 的 encoding 為 zipmap,當成員數量增大時會自動轉成真正的 HashMap,此時 encoding 為 ht。

redis  HSET myhash field1  Hello  field2  World 
redis  HGET myhash field1
 Hello 
redis  HGET myhash field2
 World

實例中我們使用了 Redis HMSET, HGET 命令,HMSET 設置了兩個 field= value 對, HGET 獲取對應 field 對應的 value。每個 hash 可以存儲 232 -1 鍵值對(40 多億)。

③ Redis list 列表是簡單的字符串列表,按照插入順序排序。你可以添加一個元素到列表的頭部(左邊)或者尾部(右邊)。

常用命令:lpush(添加左邊元素),rpush,lpop(移除左邊第一個元素),rpop,lrange(獲取列表片段,LRANGE key start stop)等。

應用場景:Redis list 的應用場景非常多,也是 Redis 最重要的數據結構之一,比如 twitter 的關注列表,粉絲列表等都可以用 Redis 的 list 結構來實現。

List 就是鏈表,相信略有數據結構知識的人都應該能理解其結構。使用 List 結構,我們可以輕松地實現最新消息排行等功能。List 的另一個應用就是消息隊列,
可以利用 List 的 PUSH 操作,將任務存在 List 中,然后工作線程再用 POP 操作將任務取出進行執行。Redis 還提供了操作 List 中某一段的 api,你可以直接查詢,刪除 List 中某一段的元素。

實現方式:Redis list 的實現為一個雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內存開銷,Redis 內部的很多實現,包括發送緩沖隊列等也都是用的這個數據結構。

Redis 的 list 是每個子元素都是 String 類型的雙向鏈表,可以通過 push 和 pop 操作從列表的頭部或者尾部添加或者刪除元素,這樣 List 即可以作為棧,也可以作為隊列。獲取越接近兩端的元素速度越快,但通過索引訪問時會比較慢。

使用場景:

消息隊列系統:使用 list 可以構建隊列系統,使用 sorted set 甚至可以構建有優先級的隊列系統。比如:將 Redis 用作日志收集器,實際上還是一個隊列,多個端點將日志信息寫入 Redis,然后一個 worker 統一將所有日志寫到磁盤。

取最新 N 個數據的操作:記錄前 N 個最新登陸的用戶 Id 列表,超出的范圍可以從數據庫中獲得。

// 把當前登錄人添加到鏈表里
ret = r.lpush(login:last_login_times , uid)
// 保持鏈表只有 N 位
ret = redis.ltrim(login:last_login_times , 0, N-1)
// 獲得前 N 個最新登陸的用戶 Id 列表
last_login_list = r.lrange(login:last_login_times , 0, N-1)

比如微博:

在 Redis 中我們的最新微博 ID 使用了常駐緩存,這是一直更新的。但是我們做了限制不能超過 5000 個 ID,因此我們的獲取 ID 函數會一直詢問 Redis。只有在 start/count 參數超出了這個范圍的時候,才需要去訪問數據庫。我們的系統不會像傳統方式那樣“刷新”緩存,Redis 實例中的信息永遠是一致的。SQL 數據庫(或是硬盤上的其他類型數據庫)只是在用戶需要獲取“很遠”的數據時才會被觸發,而主頁或第一個評論頁是不會麻煩到硬盤上的數據庫了。

redis 127.0.0.1:6379  lpush runoob redis
(integer) 1
redis 127.0.0.1:6379  lpush runoob mongodb
(integer) 2
redis 127.0.0.1:6379  lpush runoob rabitmq
(integer) 3
redis 127.0.0.1:6379  lrange runoob 0 10
1)  rabitmq 
2)  mongodb 
3)  redis 
redis 127.0.0.1:6379

列表最多可存儲 232 – 1 元素 (4294967295, 每個列表可存儲 40 多億)。

④ Redis set 是 string 類型的無序集合。集合是通過 hashtable 實現的,概念和數學中個的集合基本類似,可以交集,并集,差集等等,set 中的元素是沒有順序的。所以添加,刪除,查找的復雜度都是 O(1)。

sadd 命令:添加一個 string 元素到 key 對應的 set 集合中,成功返回 1,如果元素已經在集合中返回 0,如果 key 對應的 set 不存在則返回錯誤。

常用命令:sadd,spop,smembers,sunion 等。

應用場景:Redis set 對外提供的功能與 list 類似是一個列表的功能,特殊之處在于 set 是可以自動排重的,當你需要存儲一個列表數據,又不希望出現重復數據時,set 是一個很好的選擇,并且 set 提供了判斷某個成員是否在一個 set 集合內的重要接口,這個也是 list 所不能提供的。

Set 就是一個集合,集合的概念就是一堆不重復值的組合。利用 Redis 提供的 Set 數據結構,可以存儲一些集合性的數據。

案例:在微博中,可以將一個用戶所有的關注人存在一個集合中,將其所有粉絲存在一個集合。Redis 還為集合提供了求交集、并集、差集等操作,可以非常方便的實現如共同關注、共同喜好、二度好友等功能,對上面的所有集合操作,你還可以使用不同的命令選擇將結果返回給客戶端還是存集到一個新的集合中。

實現方式:set 的內部實現是一個 value 永遠為 null 的 HashMap,實際就是通過計算 hash 的方式來快速排重的,這也是 set 能提供判斷一個成員是否在集合內的原因。

使用場景:

①交集,并集,差集:(Set)

//book 表存儲 book 名稱
set book:1:name ”The Ruby Programming Language”set book:2:name ”Ruby on rail”set book:3:name ”Programming Erlang”//tag 表使用集合來存儲數據,因為集合擅長求交集、并集
sadd tag:ruby 1
sadd tag:ruby 2
sadd tag:web 2
sadd tag:erlang 3
// 即屬于 ruby 又屬于 web 的書?inter_list = redis.sinter(tag.web ,  tag:ruby) 
// 即屬于 ruby,但不屬于 web 的書?inter_list = redis.sdiff(tag.ruby ,  tag:web) 
// 屬于 ruby 和屬于 web 的書的合集?inter_list = redis.sunion(tag.ruby ,  tag:web)

②獲取某段時間所有數據去重值

這個使用 Redis 的 set 數據結構最合適了,只需要不斷地將數據往 set 中扔就行了,set 意為集合,所以會自動排重。

sadd key member
redis 127.0.0.1:6379  sadd runoob redis
(integer) 1
redis 127.0.0.1:6379  sadd runoob mongodb
(integer) 1
redis 127.0.0.1:6379  sadd runoob rabitmq
(integer) 1
redis 127.0.0.1:6379  sadd runoob rabitmq
(integer) 0
redis 127.0.0.1:6379  smembers runoob
1)  redis 
2)  rabitmq 
3)  mongodb

注意:以上實例中 rabitmq 添加了兩次,但根據集合內元素的唯一性,第二次插入的元素將被忽略。集合中最大的成員數為 232 – 1(4294967295, 每個集合可存儲 40 多億個成員)。

⑤ Redis zset 和 set 一樣也是 string 類型元素的集合, 且不允許重復的成員。

zadd 命令:添加元素到集合,元素在集合中存在則更新對應 score。

常用命令:zadd,zrange,zrem,zcard 等

使用場景:Redis sorted set 的使用場景與 set 類似,區別是 set 不是自動有序的,而 sorted set 可以通過用戶額外提供一個優先級 (score) 的參數來為成員排序,并且是插入有序的,即自動排序。當你需要一個有序的并且不重復的集合列表,那么可以選擇 sorted set 數據結構,比如 twitter 的 public timeline 可以以發表時間作為 score 來存儲,這樣獲取時就是自動按時間排好序的。和 Set 相比,Sorted Set 關聯了一個 double 類型權重參數 score,使得集合中的元素能夠按 score 進行有序排列,redis 正是通過分數來為集合中的成員進行從小到大的排序。zset 的成員是唯一的, 但分數 (score) 卻可以重復。比如一個存儲全班同學成績的 Sorted Set,其集合 value 可以是同學的學號,而 score 就可以是其考試得分,這樣在數據插入集合的時候,就已經進行了天然的排序。另外還可以用 Sorted Set 來做帶權重的隊列,比如普通消息的 score 為 1,重要消息的 score 為 2,然后工作線程可以選擇按 score 的倒序來獲取工作任務。讓重要的任務優先執行。

實現方式:Redis sorted set 的內部使用 HashMap 和跳躍表 (SkipList) 來保證數據的存儲和有序,HashMap 里放的是成員到 score 的映射,而跳躍表里存放的是所有的成員,排序依據是 HashMap 里存的 score, 使用跳躍表的結構可以獲得比較高的查找效率,并且在實現上比較簡單。

zadd key score member
redis 127.0.0.1:6379  zadd runoob 0 redis
(integer) 1
redis 127.0.0.1:6379  zadd runoob 0 mongodb
(integer) 1
redis 127.0.0.1:6379  zadd runoob 0 rabitmq
(integer) 1
redis 127.0.0.1:6379  zadd runoob 0 rabitmq
(integer) 0
redis 127.0.0.1:6379    ZRANGEBYSCORE runoob 0 1000
1)  mongodb 
2)  rabitmq 
3)  redis

各個數據類型應用場景:

類型簡介特性場景 String(字符串)二進制安全可以包含任何數據, 比如 jpg 圖片或者序列化的對象, 一個鍵最大能存儲 512M—Hash(字典)鍵值對集合, 即編程語言中的 Map 類型適合存儲對象, 并且可以像數據庫中 update 一個屬性一樣只修改某一項屬性值 (Memcached 中需要取出整個字符串反序列化成對象修改完再序列化存回去) 存儲、讀取、修改用戶屬性 List(列表)鏈表 (雙向鏈表) 增刪快, 提供了操作某一段元素的 API1、最新消息排行等功能 (比如朋友圈的時間線) 2、消息隊列 Set(集合) 哈希表實現, 元素不重復 1、添加、刪除、查找的復雜度都是 O(1)  2、為集合提供了求交集、并集、差集等操作 1、共同好友 2、利用唯一性, 統計訪問網站的所有獨立 ip 3、好友推薦時, 根據 tag 求交集, 大于某個閾值就可以推薦 Sorted Set(有序集合)將 Set 中的元素增加一個權重參數 score, 元素按 score 有序排列數據插入集合時, 已經進行天然排序 1、排行榜 2、帶權重的消息隊列

Redis 實際應用場景

Redis 在很多方面與其他數據庫解決方案不同:它使用內存提供主存儲支持,而僅使用硬盤做持久性的存儲;它的數據模型非常獨特,用的是單線程。另一個大區別在于,你可以在開發環境中使用 Redis 的功能,但卻不需要轉到 Redis。

轉向 Redis 當然也是可取的,許多開發者從一開始就把 Redis 作為首選數據庫;但設想如果你的開發環境已經搭建好,應用已經在上面運行了,那么更換數據庫框架顯然不那么容易。另外在一些需要大容量數據集的應用,Redis 也并不適合,因為它的數據集不會超過系統可用的內存。所以如果你有大數據應用,而且主要是讀取訪問模式,那么 Redis 并不是正確的選擇。

然而我喜歡 Redis 的一點就是你可以把它融入到你的系統中來,這就能夠解決很多問題,比如那些你現有的數據庫處理起來感到緩慢的任務。這些你就可以通過 Redis 來進行優化,或者為應用創建些新的功能。在本文中,我就想探討一些怎樣將 Redis 加入到現有的環境中,并利用它的原語命令等功能來解決 傳統環境中碰到的一些常見問題。在這些例子中,Redis 都不是作為首選數據庫。

1、顯示最新的項目列表

下面這個語句常用來顯示最新項目,隨著數據多了,查詢毫無疑問會越來越慢。

SELECT * FROM foo WHERE ... ORDER BY time DESC LIMIT 10

在 Web 應用中,“列出最新的回復”之類的查詢非常普遍,這通常會帶來可擴展性問題。這令人沮喪,因為項目本來就是按這個順序被創建的,但要輸出這個順序卻不得不進行排序操作。

類似的問題就可以用 Redis 來解決。比如說,我們的一個 Web 應用想要列出用戶貼出的最新 20 條評論。在最新的評論邊上我們有一個“顯示全部”的鏈接,點擊后就可以獲得更多的評論。

我們假設數據庫中的每條評論都有一個唯一的遞增的 ID 字段。我們可以使用分頁來制作主頁和評論頁,使用 Redis 的模板,每次新評論發表時,我們會將它的 ID 添加到一個 Redis 列表:

LPUSH latest.comments  ID

我們將列表裁剪為指定長度,因此 Redis 只需要保存最新的 5000 條評論:

LTRIM latest.comments 0 5000

每次我們需要獲取最新評論的項目范圍時,我們調用一個函數來完成(使用偽代碼):

FUNCTION get_latest_comments(start, num_items): 
 id_list = redis.lrange(latest.comments ,start,start+num_items - 1) 
 IF id_list.length   num_items 
 id_list = SQL_DB(SELECT ... ORDER BY time LIMIT ...) 
 END 
 RETURN id_list 
END

這里我們做的很簡單。在 Redis 中我們的最新 ID 使用了常駐緩存,這是一直更新的。但是我們做了限制不能超過 5000 個 ID,因此我們的獲取 ID 函數會一直詢問 Redis。只有在 start/count 參數超出了這個范圍的時候,才需要去訪問數據庫。我們的系統不會像傳統方式那樣“刷新”緩存,Redis 實例中的信息永遠是一致的。SQL 數據庫(或是硬盤上的其他類型數據庫)只是在用戶需要獲取“很遠”的數據時才會被觸發,而主頁或第一個評論頁是不會麻煩到硬盤上的數據庫了。

2、刪除與過濾

我們可以使用 LREM 來刪除評論。如果刪除操作非常少,另一個選擇是直接跳過評論條目的入口,報告說該評論已經不存在。

redis 127.0.0.1:6379  LREM KEY_NAME COUNT VALUE

有些時候你想要給不同的列表附加上不同的過濾器。如果過濾器的數量受到限制,你可以簡單的為每個不同的過濾器使用不同的 Redis 列表。畢竟每個列表只有 5000 條項目,但 Redis 卻能夠使用非常少的內存來處理幾百萬條項目。

3、排行榜相關

另一個很普遍的需求是各種數據庫的數據并非存儲在內存中,因此在按得分排序以及實時更新這些幾乎每秒鐘都需要更新的功能上數據庫的性能不夠理想。

典型的比如那些在線游戲的排行榜,比如一個 Facebook 的游戲,根據得分你通常想要:

– 列出前 100 名高分選手

– 列出某用戶當前的全球排名

這些操作對于 Redis 來說小菜一碟,即使你有幾百萬個用戶,每分鐘都會有幾百萬個新的得分。

模式是這樣的,每次獲得新得分時,我們用這樣的代碼:

 ZADD leaderboard  score   username

你可能用 userID 來取代 username,這取決于你是怎么設計的。

得到前 100 名高分用戶很簡單:ZREVRANGE leaderboard 0 99。

用戶的全球排名也相似,只需要:ZRANK leaderboard username。

4、按照用戶投票和時間排序

排行榜的一種常見變體模式就像 Reddit 或 Hacker News 用的那樣,新聞按照類似下面的公式根據得分來排序:

score = points / time^alpha

因此用戶的投票會相應的把新聞挖出來,但時間會按照一定的指數將新聞埋下去。下面是我們的模式,當然算法由你決定。

模式是這樣的,開始時先觀察那些可能是最新的項目,例如首頁上的 1000 條新聞都是候選者,因此我們先忽視掉其他的,這實現起來很簡單。

每次新的新聞貼上來后,我們將 ID 添加到列表中,使用 LPUSH + LTRIM,確保只取出最新的 1000 條項目。

有一項后臺任務獲取這個列表,并且持續的計算這 1000 條新聞中每條新聞的最終得分。計算結果由 ZADD 命令按照新的順序填充生成列表,老新聞則被清除。這里的關鍵思路是排序工作是由后臺任務來完成的。

5、處理過期項目

另一種常用的項目排序是按照時間排序。我們使用 unix 時間作為得分即可。

模式如下:

– 每次有新項目添加到我們的非 Redis 數據庫時,我們把它加入到排序集合中。這時我們用的是時間屬性,current_time 和 time_to_live。

– 另一項后臺任務使用 ZRANGE…SCORES 查詢排序集合,取出最新的 10 個項目。如果發現 unix 時間已經過期,則在數據庫中刪除條目。

6、計數

Redis 是一個很好的計數器,這要感謝 INCRBY 和其他相似命令。

我相信你曾許多次想要給數據庫加上新的計數器,用來獲取統計或顯示新信息,但是最后卻由于寫入敏感而不得不放棄它們。

好了,現在使用 Redis 就不需要再擔心了。有了原子遞增(atomic increment),你可以放心的加上各種計數,用 GETSET 重置,或者是讓它們過期。

例如這樣操作:

INCR user: id  EXPIRE 
user: id  60

你可以計算出最近用戶在頁面間停頓不超過 60 秒的頁面瀏覽量,當計數達到比如 20 時,就可以顯示出某些條幅提示,或是其它你想顯示的東西。

7、特定時間內的特定項目

另一項對于其他數據庫很難,但 Redis 做起來卻輕而易舉的事就是統計在某段特點時間里有多少特定用戶訪問了某個特定資源。比如我想要知道某些特定的注冊用戶或 IP 地址,他們到底有多少訪問了某篇文章。

每次我獲得一次新的頁面瀏覽時我只需要這樣做:

SADD page:day1: page_id   user_id

當然你可能想用 unix 時間替換 day1,比如 time()-(time()%3600*24)等等。

想知道特定用戶的數量嗎?只需要使用

SCARD page:day1: page_id

需要測試某個特定用戶是否訪問了這個頁面?

SISMEMBER page:day1: page_id

8、實時分析正在發生的情況,用于數據統計與防止垃圾郵件等

我們只做了幾個例子,但如果你研究 Redis 的命令集,并且組合一下,就能獲得大量的實時分析方法,有效而且非常省力。使用 Redis 原語命令,更容易實施垃圾郵件過濾系統或其他實時跟蹤系統。

9、Pub/Sub

Redis 的 Pub/Sub 非常非常簡單,運行穩定并且快速。支持模式匹配,能夠實時訂閱與取消頻道。

10、隊列

你應該已經注意到像 list push 和 list pop 這樣的 Redis 命令能夠很方便的執行隊列操作了,但能做的可不止這些:比如 Redis 還有 list pop 的變體命令,能夠在列表為空時阻塞隊列。

現代的互聯網應用大量地使用了消息隊列(Messaging)。消息隊列不僅被用于系統內部組件之間的通信,同時也被用于系統跟其它服務之間的交互。消息隊列的使用可以增加系統的可擴展性、靈活性和用戶體驗。非基于消息隊列的系統,其運行速度取決于系統中最慢的組件的速度(注:短板效應)。而基于消息隊列可以將系統中各組件解除耦合,這樣系統就不再受最慢組件的束縛,各組件可以異步運行從而得以更快的速度完成各自的工作。

此外,當服務器處在高并發操作的時候,比如頻繁地寫入日志文件。可以利用消息隊列實現異步處理。從而實現高性能的并發操作。

11、緩存

Redis 的緩存部分值得寫一篇新文章,我這里只是簡單的說一下。Redis 能夠替代 memcached,讓你的緩存從只能存儲數據變得能夠更新數據,因此你不再需要每次都重新生成數據了。

讀到這里,這篇“Redis 中的 5 種數據類型怎么應用”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注丸趣 TV 行業資訊頻道。

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-15發表,共計12065字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 平乐县| 淮北市| 怀来县| 靖宇县| 虞城县| 丹棱县| 泰安市| 南通市| 牡丹江市| 南皮县| 饶平县| 秭归县| 略阳县| 菏泽市| 黄陵县| 富锦市| 江门市| 仪征市| 乡城县| 泊头市| 饶阳县| 安达市| 安福县| 富平县| 屏山县| 保康县| 莱阳市| 大余县| 武清区| 邢台市| 墨玉县| 迭部县| 乐昌市| 江津市| 安化县| 武安市| 泰安市| 尼勒克县| 儋州市| 奉化市| 湖北省|