欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java使用Redis實(shí)現(xiàn)微博熱搜功能

 更新時(shí)間:2024年12月13日 09:26:29   作者:w_l666  
在社交平臺上,熱搜功能是一個(gè)非常重要的組成部分,它展示了當(dāng)前最熱門的話題,幫助用戶迅速了解最受關(guān)注的事件,Redis 是一個(gè)高性能的鍵值存儲系統(tǒng),通常用于緩存和實(shí)時(shí)數(shù)據(jù)存儲,本文將通過 Java 結(jié)合 Redis 實(shí)現(xiàn)一個(gè)簡化版的微博熱搜功能,需要的朋友可以參考下

介紹

在社交平臺上,熱搜功能是一個(gè)非常重要的組成部分。它展示了當(dāng)前最熱門的話題,幫助用戶迅速了解最受關(guān)注的事件。在微博等平臺上,熱搜榜單通常是實(shí)時(shí)變化的,可能會根據(jù)用戶的互動數(shù)據(jù)(如搜索頻次、點(diǎn)贊量、評論數(shù)等)動態(tài)調(diào)整。

Redis 是一個(gè)高性能的鍵值存儲系統(tǒng),通常用于緩存和實(shí)時(shí)數(shù)據(jù)存儲,特別適用于實(shí)現(xiàn)類似熱搜榜單這樣的功能。本文將通過 Java 結(jié)合 Redis 實(shí)現(xiàn)一個(gè)簡化版的微博熱搜功能,展示如何使用 Redis 提供的高效數(shù)據(jù)結(jié)構(gòu),如 SortedSet(有序集合)來維護(hù)熱搜榜單。

 熱度的計(jì)算方式,不同的產(chǎn)品的熱度計(jì)算方式不同:

例如:

熱度=評論數(shù)+轉(zhuǎn)發(fā)數(shù)+點(diǎn)贊數(shù) 

熱度=搜索量+點(diǎn)擊量

熱搜排行榜可以分為:當(dāng)前小時(shí)的熱搜榜,當(dāng)天的熱搜榜,當(dāng)月的熱搜榜,當(dāng)前周的熱搜榜等等。

思路: 一般情況下,我們按照存儲每個(gè)小時(shí)的小時(shí)榜,為最小單位。  同理,當(dāng)天的熱搜榜,就是這一天24小時(shí)的小時(shí)榜合并后的榜單。當(dāng)月的熱搜榜就是,這個(gè)月每天的熱搜榜合并后的榜單。

1. Redis 數(shù)據(jù)結(jié)構(gòu)介紹

在實(shí)現(xiàn)熱搜功能時(shí),Redis 提供的 SortedSet(有序集合)是非常合適的。SortedSet 會根據(jù)分?jǐn)?shù)(score)對成員(member)進(jìn)行排序,適用于我們要根據(jù)熱度(例如搜索頻次、點(diǎn)贊數(shù)等)排序展示的場景。

  • SortedSet(zset):是一個(gè)有序的集合,每個(gè)元素都有一個(gè)分?jǐn)?shù)(score),Redis 會自動根據(jù)分?jǐn)?shù)對元素進(jìn)行排序。適合實(shí)現(xiàn)需要排序的場景,如熱搜榜單、排行榜等。

2.當(dāng)前小時(shí)的key的設(shè)定思路:

1.使用當(dāng)前的時(shí)間戳來生成唯一的 key,通常使用 YYYY-MM-DD-HH 作為 key 的格式,這樣每天每小時(shí)的數(shù)據(jù)都會有獨(dú)立的 key。

例如:當(dāng)前時(shí)間為 2024-12-10 07:25:21,那么對應(yīng)的 key 為 2024-12-10-07。

2.當(dāng)前時(shí)間的毫秒的時(shí)間(T),當(dāng)前小時(shí)唯一key=T/1000*60*60;

例如:當(dāng)前時(shí)間為2024-12-10 16:10:40=1733818240000  ,那么對應(yīng)的key就是:1733818240000 /1000*60*60=481,616

以上兩種方式,都可以獲取到當(dāng)前時(shí)間的唯一的key。

3.代碼實(shí)現(xiàn)

1. 引入依賴

在你的 pom.xml 中加入以下依賴來使用 Redis 和 Jedis:

<dependencies>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>4.2.3</version>
    </dependency>
</dependencies>

主要需要實(shí)現(xiàn)的功能:熱搜的小時(shí)榜,天榜,月榜的榜單的實(shí)現(xiàn)。

首先編寫redis的基本操作的工具類:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
 
import java.util.Set;
 
public class RedisUtil {
    private static JedisPool pool;
 
    static {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(50);
        config.setMaxIdle(10);
        config.setMinIdle(5);
        config.setTestOnBorrow(true);
        pool = new JedisPool(config, "localhost", 6379);  // Redis 地址
    }
 
    public static Jedis getJedis() {
        return pool.getResource();
    }
 
    public static void close(Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }
 
    public static void incrementSearchCount(String key,String topic) {
        Jedis jedis = getJedis();
        try {
            // 使用 Redis 的 ZINCRBY 命令遞增話題的熱度
            jedis.zincrby(key, 1, topic);
        } finally {
            close(jedis);
        }
    }
 
    public static Set<String> getTopSearch(int topN) {
        Jedis jedis = getJedis();
        try {
            // 使用 Redis 的 ZREVRANGE 命令獲取熱搜榜單
            return jedis.zrevrange("hot_search", 0, topN - 1);
        } finally {
            close(jedis);
        }
    }
}

熱搜的增加,每次都是單個(gè)增加的,此處不做解釋。我們主要研究,如何查詢,小時(shí)榜,天榜,月榜的數(shù)據(jù)。 

具體代碼如下:

    @Autowired
    private RedisTemplate redisTemplate;
 
    /**
     * 更新天的熱搜數(shù)據(jù)
     */
    public void updateDaySearch(){
        long hour = System.currentTimeMillis()/(1000*60*60);
        //小時(shí)key的前綴
        String hourPrefix = "search:hour";
        //天的key
        String dayPrefix = "search:day";
        //計(jì)算最近24小時(shí)的key的集合
        ArrayList<Object> dayKeys = new ArrayList<>();
        //統(tǒng)計(jì)近24小時(shí)的key的集合
        for (int i = 1; i < 23; i++) {
            String key = hourPrefix+(hour-i);
            dayKeys.add(key);
            //設(shè)置當(dāng)天的key 40天過期,防止資源的浪費(fèi)
            redisTemplate.expire(key,40, TimeUnit.DAYS);
        }
        //將近24小時(shí)的key的值進(jìn)行合并
        //(redisTemplate.opsForZSet()。unionAndStore(a,b,c);把a(bǔ),b 兩個(gè)zset合并儲存到c集合中)
        redisTemplate.opsForZSet().unionAndStore(hourPrefix+hour,dayKeys,dayPrefix);
        log.info("*********************進(jìn)行天數(shù)據(jù)的更新************************");
    }
 
    public void updateMonthSearch(){
        long hour = System.currentTimeMillis()/(1000*60*60);
        //小時(shí)key的前綴
        String hourPrefix = "search:hour";
        //天的key
        String monthPrefix = "search:day";
        //計(jì)算最近24小時(shí)的key的集合
        ArrayList<Object> monthKeys = new ArrayList<>();
        //統(tǒng)計(jì)近24小時(shí)的key的集合
        for (int i = 1; i < 24*30-1; i++) {
            String key = hourPrefix+(hour-i);
            monthKeys.add(key);
        }
        //將近30天的key的值進(jìn)行合并
        redisTemplate.opsForZSet().unionAndStore(hourPrefix+hour,monthKeys,monthPrefix);
        log.info("***************進(jìn)行月數(shù)據(jù)的更新*********************");
    }
 
    /**
     * 更新最近7天的數(shù)據(jù)
     */
    public void updateWeekSearch(){
        long hour = System.currentTimeMillis()/(1000*60*60);
        //小時(shí)key的前綴
        String hourPrefix = "search:hour";
        //周的key
        String weekPrefix = "search:week";
        //計(jì)算最近24小時(shí)的key的集合
        ArrayList<Object> weekKeys = new ArrayList<>();
        //統(tǒng)計(jì)近24小時(shí)的key的集合
        for (int i = 1; i < 24*7-1; i++) {
            String key = hourPrefix+(hour-i);
            weekKeys.add(key);
        }
        //將近30天的key的值進(jìn)行合并
        redisTemplate.opsForZSet().unionAndStore(hourPrefix+hour,weekKeys,weekPrefix);
        log.info("************進(jìn)行周數(shù)據(jù)的更新******************");
    }
 
    /**
     * 定時(shí)器每小時(shí)調(diào)用一次次方法進(jìn)行,小時(shí)榜,天榜,周榜,月榜的更新
     */
    public void updateAllSearch(){
        //TODO 此方法建議使用定時(shí)框架,quartz ,xxl-job等進(jìn)行定時(shí)調(diào)用
        updateDaySearch();
        updateWeekSearch();
        updateMonthSearch();
    }

4. 優(yōu)化和擴(kuò)展

  1. 熱搜榜單過期策略:可以設(shè)置 Redis 中有序集合的過期時(shí)間,定期清理不再熱門的關(guān)鍵詞。
  2. 多維度排序:除了搜索次數(shù)外,可以根據(jù)時(shí)間窗口(例如過去一小時(shí)、一天內(nèi)的搜索量)來做更加復(fù)雜的排序。
  3. 高并發(fā)優(yōu)化:為了避免頻繁的 Redis 操作影響性能,可以考慮將熱搜數(shù)據(jù)批量更新或者使用消息隊(duì)列來異步處理。

總結(jié)

通過以上的實(shí)現(xiàn),我們展示了如何使用 Java 和 Redis 來實(shí)現(xiàn)一個(gè)簡單的微博熱搜功能。通過 Redis 的有序集合,我們能夠高效地記錄和排序搜索關(guān)鍵詞的熱度,并在用戶請求時(shí)實(shí)時(shí)返回當(dāng)前最熱門的話題。

這種基于 Redis 的熱搜功能不僅適用于微博,實(shí)際上可以廣泛應(yīng)用于各種需要統(tǒng)計(jì)熱門話題或關(guān)鍵詞的場景,如新聞網(wǎng)站、視頻平臺等。

以上就是Java使用Redis實(shí)現(xiàn)微博熱搜功能的詳細(xì)內(nèi)容,更多關(guān)于Java Redis微博熱搜的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • spring boot項(xiàng)目中MongoDB的使用方法

    spring boot項(xiàng)目中MongoDB的使用方法

    前段時(shí)間分享了關(guān)于Spring Boot中使用Redis的文章,除了Redis之后,我們在互聯(lián)網(wǎng)產(chǎn)品中還經(jīng)常會用到另外一款著名的NoSQL數(shù)據(jù)庫MongoDB。下面這篇文章主要給大家介紹了關(guān)于在spring boot項(xiàng)目中MongoDB的使用方法,需要的朋友可以參考下。
    2017-09-09
  • 最新評論