最近專案架構公升級,主要對效能方面進行公升級。之前熱門排行榜是通過對點讚量,閱讀量,收藏量等一系列的資料在db通過計算查出來的,效率方面不太好。因此考慮對該功能進行公升級優化,並且新增週期性排行榜如月排行,總排行。
在引入快取之後首先考慮的是通過快取實現熱門排行榜的功能,但是考慮到首次引入快取擔心快取出現問題導致功能不可用。所以在做方案的時候,採用優先使用快取,如果快取不可用則走db。因此db的設計也需要進行優化。
以點贊操作為例,點讚之後沒有直接去更新db活躍度表的資料量,而是去更新快取中資料(hash)對應的點讚數,因為在操作頻繁的情況下更新快取會比更新db效率快很多。並且將快取中被更新資料的key記錄下來,記錄在redis中設定5分鐘過期時間,並且通過setnx命令進行寫入,也就是如果該key還沒過期你是儲存不成功的。這麼做的目的是只是把這一步當作乙個屏障擋在寫入訊息之前,只有儲存成功才可以進行寫入訊息,以免頻繁的寫入訊息,如果儲存key成功則寫入訊息,訊息的消費端延遲1秒鐘去讀取訊息,其實這就類似於乙個週期為1秒的定時任務,讀取訊息之後可以從訊息體中獲取key,並通過該key去快取中找到對應的資料,將資料同步至db。
該流程我理解為乙個「偽同步資料庫的流程」,頁面的操作直接更新快取,而通過可延遲消費訊息的中介軟體非同步的將資料更新至資料庫。從根本來說來是更新了資料庫,並且從時間上來看基本上的同步更新資料庫的,但實際是通過訊息中介軟體非同步實現的。
優先從快取獲取,若快取不可用則走db。因此對db設計也需要優化。
榜之前的點讚數 收藏數 等一系列與活躍度相關的資料存在一張表中,稱之為活躍度表,該錶的資料量和文章表中的資料量大體上是一樣的。並且隨著時間積累資料量會越來越大,因此不再這張表中做手腳,新建一張表,新建的表專門用於各種各樣的排行。
新建表的主要字段:
1 型別:排行榜型別,如周排行榜,月排行榜。。
2 內容型別:如部落格,直播,主播。。。
3 例項id : 如部落格 id,直播code等
4 熱度 :活躍度
2 定時清除任務:在每月的1號0點,將上個月的月排行榜資料置為刪除態。
db這麼設計之後,月排行榜可以直接從這100條資料中根據熱度排序取出前幾條,查詢效率遠遠比之前要快。並且定時任務是通過 訊息中介軟體+定時器 配合完成的 集群中只有一台服務會進行定時處理資料以免重複處理。
快取的資料結構使用 redis的zset實現,因為zset支援根據score進行排序查詢。
zset的key為我們自己約定的key,score為文章熱度,member為文章資料
1 定時更新任務:同db一樣只不過是更新至 總排行榜的zset和月排行榜的zset
2 定時清除任務:同db
因此通過快取查詢排行榜可根據排行榜週期性的不同,分別取不同key對應的資料即可。
redis實現排行榜
排行榜功能是乙個很普遍的需求。設想在乙個遊戲中,有上百萬的玩家資料,如果現在需要你根據玩家的經驗值整理乙個前20名的排行榜,你會怎麼做呢?你不可能 order by limit 去實現 select from game socre order by score desc limit 0,20 使用 ...
Redis 實現排行榜
不再介紹資料庫做實時排行榜的弊端,直接介紹redis的有序集合的強大作用。有序集合的資料和集合一樣,不能重複,但每個元素又可以關聯乙個分數,這個分數可以重複。需要注意的是,redis版本和命令變化較大,注意執行環境。執行環境 redis 庫版本 3.3.11 redis版本 3.2.1 生成資料 i...
Redis排行榜的實現
遊戲闖關排行榜以通關次數正序 復活次數倒序和第一次通關的時間倒序來進行排序 第一步是組合排序分值,只有根據排序規則組合出來的分值,才能通過排序獲取到正確的排名。在排序規則中一般會有兩種方式,屬性正序和倒序。正序對於組合數字來說沒有影響,但是倒序就需要進行特殊的處理。那麼多說無益,上 排行榜顧名思義就...