redis 有用 Sorted-Set 應用場景


1.1.1Set數據類型的 使用場景

1、可以使用Redis的Set數據類型跟蹤一些唯一性數據,比如訪問某一博客的唯一IP地址信息。對於此場景,我們僅需在每次訪問該博客時將訪問者的IP存入Redis中,Set數據類型會自動保證IP地址的唯一性。

2、充分利用Set類型的服務端聚合操作方便、高效的特性,可以用於維護數據對象之間的關聯關系。比如所有購買某一電子設備的客戶ID被存儲在一個指定的Set中,而購買另外一種電子產品的客戶ID被存儲在另外一個Set中,如果此時我們想獲取有哪些客戶同時購買了這兩種商品時,Set的intersections交集命令就可以充分發揮它的方便和效率的優勢了。

 

 

 

1.1 存儲sortedset

 

1.1.1 概述

 

Sorted-Set和Set類型極為相似,它們都是字符串的集合,都不允許重復的成員出現在一個Set中。它們之間的主要差別是Sorted-Set中的每一個成員都會有一個分數(score)與之關聯,Redis正是通過分數來為集合中的成員進行從小到大的排序。然而需要額外指出的是,盡管Sorted-Set中的成員必須是唯一的,但是分數(score)卻是可以重復的。

 

在Sorted-Set中添加、刪除或更新一個成員都是非常快速的操作,其時間復雜度為集合中成員數量的對數。由於Sorted-Set中的成員在集合中的位置是有序的,因此,即便是訪問位於集合中部的成員也仍然是非常高效的。事實上,Redis所具有的這一特征在很多其它類型的數據庫中是很難實現的,換句話說,在該點上要想達到和Redis同樣的高效,在其它數據庫中進行建模是非常困難的。

 

例如:游戲排名、微博熱點話題等使用場景。

 

 

1.1.1 擴展命令(了解)

 

l zrangebyscore key min max [withscores] [limit offset count]:返回分數在[min,max]的成員並按照分數從低到高排序。[withscores]:顯示分數;[limit offset count]:offset,表明從腳標為offset的元素開始並返回count個成員。   分頁排名

 

 

 

 

 

 

 

 

 

l zincrby key increment member:設置指定成員的增加的分數。返回值是更改后的分數。

 

 

 

 

 

l zcount key min max:獲取分數在[min,max]之間的成員

 

 

 

 

 

 

 

l zrank key member:返回成員在集合中的排名。(從小到大)

 

 

 

 

 

l zrevrank key member:返回成員在集合中的排名。(從大到小)

 

 

 

 

 

 

1.1.1 使用場景

 

1、可以用於一個大型在線游戲的積分排行榜。每當玩家的分數發生變化時,可以執行ZADD命令更新玩家的分數,此后再通過ZRANGE命令獲取積分TOPTEN的用戶信息。當然我們也可以利用ZRANK命令通過username來獲取玩家的排行信息。最后我們將組合使用ZRANGE和ZRANK命令快速的獲取和某個玩家積分相近的其他用戶的信息。

 

2、Sorted-Set類型還可用於構建索引數據。

 

 

 

 

1.1 消息訂閱與發布

 

l subscribe channel:訂閱頻道,例:subscribe mychat,訂閱mychat這個頻道

 

l psubscribe channel*:批量訂閱頻道,例:psubscribe s*,訂閱以”s”開頭的頻道

 

l publish channel content:在指定的頻道中發布消息,如 publish mychat ‘today is a newday’

 

 

 

l 步驟1:在第一個連接中,訂閱mychat頻道。此時如果沒有人“發布”消息,當前窗口處於等待狀態。

 

 

 

 

l 步驟2:在另一個窗口中,在mychat頻道中,發布消息。

 

 

 

 

 

 

 

l 步驟3:再第三個窗口,批量訂閱以my開頭所有頻道。

 

 

 

 

 

 

 

l 步驟4:在第二個窗口,分別在“mychat”和“mychat2”發布消息

 

 

 

 

1.1.1 redis事務特征

1、 在事務中的所有命令都將會被串行化的順序執行事務執行期間,Redis不會再為其它客戶端的請求提供任何服務,從而保證了事物中的所有命令被原子的執行

2、 和關系型數據庫中的事務相比,在Redis事務中如果有某一條命令執行失敗,其后的命令仍然會被繼續執行

3、 我們可以通過MULTI命令開啟一個事務,有關系型數據庫開發經驗的人可以將其理解為"BEGIN TRANSACTION"語句。在該語句之后執行的命令都將被視為事務之內的操作,最后我們可以通過執行EXEC/DISCARD命令來提交/回滾該事務內的所有操作。這兩個Redis命令可被視為等同於關系型數據庫中的COMMIT/ROLLBACK語句。

4、 在事務開啟之前,如果客戶端與服務器之間出現通訊故障並導致網絡斷開,其后所有待執行的語句都將不會被服務器執行。然而如果網絡中斷事件是發生在客戶端執行EXEC命令之后,那么該事務中的所有命令都會被服務器執行。

 

 

 

 

1.1.1 優勢

 

1、 該機制可以帶來更高的數據安全性,即數據持久性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事實上,每秒同步也是異步完成的,其效率也是非常高的,所差的是一旦系統出現宕機現象,那么這一秒鍾之內修改的數據將會丟失。而每修改同步,我們可以將其視為同步持久化,即每次發生的數據變化都會被立即記錄到磁盤中。可以預見,這種方式在效率上是最低的。至於無同步,無需多言,我想大家都能正確的理解它。

 

2、 由於該機制對日志文件的寫入操作采用的是append模式,因此在寫入過程中即使出現宕機現象,也不會破壞日志文件中已經存在的內容。然而如果我們本次操作只是寫入了一半數據就出現了系統崩潰問題,不用擔心,在Redis下一次啟動之前,我們可以通過redis-check-aof工具來幫助我們解決數據一致性的問題。

 

3、 如果日志過大,Redis可以自動啟用rewrite機制。即Redis以append模式不斷的將修改數據寫入到老的磁盤文件中,同時Redis還會創建一個新的文件用於記錄此期間有哪些修改命令被執行。因此在進行rewrite切換時可以更好的保證數據安全性。

 

4、 AOF包含一個格式清晰、易於理解的日志文件用於記錄所有的修改操作。事實上,我們也可以通過該文件完成數據的重建。

 

1.1.2 劣勢

 

1、 對於相同數量的數據集而言,AOF文件通常要大於RDB文件

 

2、 根據同步策略的不同,AOF在運行效率上往往會慢於RDB。總之,每秒同步策略的效率是比較高的,同步禁用策略的效率和RDB一樣高效。

 

 

 

 

第1章 redis使用場景(了解)

 

1、 取最新N個數據的操作

 

比如典型的取你網站的最新文章,通過下面方式,我們可以將最新的5000條評論的ID放在Redis的List集合中,並將超出集合部分從數據庫獲取

 

 (1)使用LPUSH latest.comments <ID>命令,向list集合中插入數據

 

 (2)插入完成后再用LTRIM latest.comments 0 5000命令使其永遠只保存最近5000個ID

 

 (3)然后我們在客戶端獲取某一頁評論時可以用下面的邏輯(偽代碼)

 

# 偽代碼

 

 

 

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

 

如果你還有不同的篩選維度,比如某個分類的最新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甚至可以構建有優先級的隊列系統。

 

 

 

 

 

 

第1章 redis持久化(了解)

 

1.1 概述

 

Redis的高性能是由於其將所有數據都存儲在了內存中,為了使Redis在重啟之后仍能保證數據不丟失,需要將數據從內存中同步到硬盤中,這一過程就是持久化。

 

Redis支持兩種方式的持久化,一種是RDB方式,一種是AOF方式。可以單獨使用其中一種或將二者結合使用。

 

1、 RDB持久化(默認支持,無需配置

 

該機制是指在指定的時間間隔內將內存中的數據集快照寫入磁盤。

 

2、 AOF持久化

 

該機制將以日志的形式記錄服務器所處理的每一個寫操作,在Redis服務器啟動之初會讀取該文件來重新構建數據庫,以保證啟動后數據庫中的數據是完整的。

 

3、 無持久化

 

我們可以通過配置的方式禁用Redis服務器的持久化功能,這樣我們就可以將Redis視為一個功能加強版的memcached了。

 

4、 redis可以同時使用RDB和AOF

 

1.2 RDB

 

1.2.1 優勢

 

1、 一旦采用該方式,那么你的整個Redis數據庫將只包含一個文件,這對於文件備份而言是非常完美的。比如,你可能打算每個小時歸檔一次最近24小時的數據,同時還要每天歸檔一次最近30天的數據。通過這樣的備份策略,一旦系統出現災難性故障,我們可以非常容易的進行恢復。

 

2、 對於災難恢復而言,RDB是非常不錯的選擇。因為我們可以非常輕松的將一個單獨的文件壓縮后再轉移到其它存儲介質上

 

3、 性能最大化。對於Redis的服務進程而言,在開始持久化時,它唯一需要做的只是fork(分叉)出子進程,之后再由子進程完成這些持久化的工作,這樣就可以極大的避免服務進程執行IO操作了。

 

4、 相比於AOF機制,如果數據集很大,RDB的啟動效率會更高。

 

1.2.2 劣勢

 

1、 如果你想保證數據的高可用性,即最大限度的避免數據丟失,那么RDB將不是一個很好的選擇。因為系統一旦在定時持久化之前出現宕機現象,此前沒有來得及寫入磁盤的數據都將丟失。

 

2、 由於RDB是通過fork子進程來協助完成數據持久化工作的,因此,如果當數據集較大時,可能會導致整個服務器停止服務幾百毫秒,甚至是1秒鍾

 

5、 當使用Append-Only模式時,Redis會通過調用系統函數write將該事務內的所有寫操作在本次調用中全部寫入磁盤。然而如果在寫入的過程中出現系統崩潰,如電源故障導致的宕機,那么此時也許只有部分數據被寫入到磁盤,而另外一部分數據卻已經丟失。Redis服務器會在重新啟動時執行一系列必要的一致性檢測,一旦發現類似問題,就會立即退出並給出相應的錯誤提示。此時,我們就要充分利用Redis工具包中提供的redis-check-aof工具,該工具可以幫助我們定位到數據不一致的錯誤,並將已經寫入的部分數據進行回滾。修復之后我們就可以再次重新啟動Redis服務器了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM