Java實現排行榜基於Redis


訪問我的博客

前言

排行榜作為互聯網應用中幾乎必不可少的一個元素,其能夠勾起人類自身對比的欲望,從而來增加商品的銷量。排行榜的實現方式基本大同小異,大部分都基於 Redis 的有序集合 sorted set 來實現。不久前,負責開發一個活動,就有排行榜這個需求,筆者也使用 Redis 進行了實現。本文通過了商品銷售排行榜這一模型,來進行演示。

需求

  1. 按照商品銷量進行排行
  2. 可以獲得指定商品的排名
  3. 顯示實時銷售動態情況

需求分析

分析需求,以上這些都可以通過 Redis 的有序集合相關命令進行實現,首先看一下使用到的具體 Redis 命令。

redis> ZADD bangdan 1 "one"
(integer) 1
# 對有序集合中指定成員的分數加上增量

redis> zadd bangdan 1 "one" 4 "three" 3 "two"
(integer) 2
# 將一個或多個成員以及分數加入到有序集合中

redis> zrange bangdan 0 1
1) "one"
2) "three"
# 按照 score 升序排列 ,取出前兩名

redis> zscore bangdan three
"4"
# 獲得榜單中指定元素的score

redis> zrank bangdan one
(integer) 0
# 在升序榜中的名次 第一返回0

# 第三個需求需要使用 Redis 的 list 來進行實現

redis> LPUSH dynamic abc
(integer) 1
# 向隊列左側頭部 push 數據

redis> LPUSH dynamic 0
"abc"
# 通過索引獲取列表中的元素

redis> LTRIM dynamic 0 2
"abc"
# 對一個列表進行修剪(trim),就是說,讓列表只保留指定區間內的元素,不在指定區間之內的元素都將被刪除

排行榜預覽

按照需求開發,最后的效果如下:

以下通過 Java 代碼實現。

通過 Java 實現排行榜

引入依賴

項目中使用到了 Redis,因此需要引入相關依賴,為了簡明演示,這里沒有使用 JedisPool。

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.7.3</version>
</dependency>

開發邏輯

  1. 頁面上點擊一次購買按鈕,則對該手機的銷量加 1,同時將銷售動態添加到隊列當中

    jedis.zincrby(Constants.SALES_LIST, 1, String.valueOf(phoneId));
    jedis.lpush(Constants.BUY_DYNAMIC, msg);
    
  2. 獲得排行榜

    // 按照scope升序排名,取出前五
    jedis.zrevrangeWithScores(Constants.SALES_LIST, 0, 4);
    
  3. 獲得指定手機的排名情況

    jedis.zrevrank(Constants.SALES_LIST, String.valueOf(phoneId));
    
  4. 獲得銷售動態,此處只取 3 條,同時隊列只保存最新的 20 條動態

    List<DynamicVO> dynamicList = new ArrayList<>();
    for (int i = 0; i < 3; i++) {
            String result = jedis.lindex(Constants.BUY_DYNAMIC, i);
            if (StringUtils.isEmpty(result)) {
                break;
            }
            String[] arr = result.split(Constants.separator);
            long time = Long.valueOf(arr[0]);
            String phone = arr[1];
            DynamicVO vo = new DynamicVO();
            vo.setPhone(phone);
            vo.setTime(StringUtil.showTime(new Date(time)));
            dynamicList.add(vo);
    }
    jedis.ltrim(Constants.BUY_DYNAMIC, 0, 19);
    
    
  5. 因為排行榜這種實時性比較強的數據,更新比較快,個人覺得沒有必要進行持久化,如果 Redis 的排行榜數據丟失,可以通過代碼重新計算排行,通過 zadd 命令,重新添加到 Redis 中即可。

    Map<String, Double> map = new HashMap<>();
        map.put("1", 4.0);
        map.put("2", 2.0);
        map.put("3", 3.0);
    jedis.zadd(Constants.SALES_LIST, map);
    

源碼下載

點我下載


免責聲明!

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



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