公司的員工風采欄目下,有文章需要處理點贊。搜索了網上的案例,普遍做法有兩種,一種是mysql 直接連數據庫,進行存儲。有點
缺點是熱門文章頻繁點贊時,對數據庫的訪問壓力變大。另外一種就是利用點贊的業務特征來扔到redis(或memcache)中, 然后離線刷回mysql等。
直接寫入Mysql
直接寫入Mysql是最簡單的做法。
做三個表即可,
-
comment_info
記錄文章的主要內容,主要有like_count,hate_count,score這三個字段是我們本次功能的主要字段。
-
comment_like
記錄文章被贊的次數,已有多少人贊過這種數據就可以直接從表中查到;
-
user_like_comment
記錄用戶贊過了哪些文章, 當打開文章列表時,顯示的有沒有贊過的數據就在這里面;
缺點
-
數據庫讀寫壓力大
熱門文章會有很多用戶點贊,甚至是短時間內被大量點贊, 直接操作數據庫從長久來看不是很理想的做法
redis存儲隨后批量刷回數據庫
redis主要的特點就是快, 畢竟主要數據都在內存嘛;
另外為啥我選擇redis而不是memcache的主要原因在於redis支持更多的數據類型, 例如hash, set, zset等。
下面具體的會用到這幾個類型。
優點
-
性能高
-
緩解數據庫讀寫壓力
其實我更多的在於緩解寫壓力, 至於讀壓力, 通過mysql主從甚至通過加入redis對熱點數據做緩存都可以解決,
寫壓力對於前面的方案確實是不大好使。
缺點
-
開發復雜
這個比直接寫mysql的方案要復雜很多, 需要考慮的地方也很多;
-
不能保證數據安全性
redis掛掉的時候會丟失數據, 同時不及時同步redis中的數據, 可能會在redis內存置換的時候被淘汰掉;
不過對於我們點贊而已, 稍微丟失一點數據問題不大;
其實上面第二點缺點是可以避免的,這就涉及到redis 的一些設計模式,不懂沒關系,我盡量詳細的寫,后面我會給出如何解決這個缺點。
設計功能前知識准備
1.將要用到的redis數據類型(具體的類型說明,請看底部鏈接,有詳細說明):
- zset 這個類型主要用來做排序或者數字的增減,這里被用作like 和hate的數字記錄,以及熱度的記錄。
- set 這個是無序集合,主要用來記錄今天需不需要更新,將今天被點贊(包括點討厭)過的文章id記錄下來,方便晚上或者有時間對這部分數據更新。
- hash 這個是散列,主要用來存儲數據以及索引。這里被用來記錄用戶對哪個文章點了什么,方便下次判斷(我看過一些網上的介紹使用set來記錄,那個也可以,但是本人覺得這樣做更省空間,以及方便管理,再有就是hash的速度快)。
- list 這個是隊列大佬,我們的數據能不能 安全 回到mysql就靠它了。
2.關於熱度如何去判斷:
大家都知道,文章獲得點贊數越高,文章的熱度就越高,那么怎么判斷呢?不就直接記錄點贊數就行啦,但是對於最新的文章怎么辦?例如有一篇文章一年前發布的,獲得50個贊,有篇最新文章獲得49個贊,但是按照上面所說的一年前的文章熱度還比最新的高,這就不合理了,文章都是時效性,誰都想看最新最熱的。
so!我們要換個方法去處理這個時效性,絕大部分語言都有 時間戳 生成的方法,時間戳隨着時間越新,數字越大,直接將時間戳初始化賦值給文章的score,這樣最新的文章相比以前的文章就會靠前了。接着是點贊對score的影響,我們假設一天得到20個贊算是一天最熱,一天60*60*24=86400秒,然后得到一個贊就是得到86400 / 20 = 4320分。具體數字看自己的業務需求定,我只是舉例子而已。點hate當然也會減去相應的數字。
代碼后面再詳細寫。