SoFunction
Updated on 2025-04-18

SpringBoot integrates Redisson to achieve high performance real-time rankings

In today's Internet applications, ranking functions are almost everywhere! Whether it is the sales list of e-commerce platforms, the ranking of players in the game, or the popularity list of social media, a real-time and efficient ranking system is the key to improving user experience. So the question is: How to quickly build a high-performance real-time ranking list with Spring Boot and Redisson? Today we will talk about this technical solution in detail!

Why choose Redisson

First of all, Redisson is a Java client based on Redis. It not only encapsulates the basic operations of Redis, but also provides advanced functions such as distributed locks, Bloom filters, rankings, etc. Compared to directly operating Redis, Redisson's API is more in line with the habits of Java developers and is optimized very well. For example, its RLexSortedSet and RScoredSortedSet can be directly used to implement rankings and support millisecond real-time updates!

// Example: Initialize the Redisson clientConfig config = new Config();
().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = (config);

// Get an ordered set with fractionsRScoredSortedSet<String> ranking = ("user_ranking");

How Spring Boot integrates Redisson

The integration process is very simple! Just a few steps:

Add dependencies: Add Redisson's Spring Boot Starter.

<dependency>
    <groupId></groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.16.8</version>
</dependency>

Configure Redis connection: Fill in the Redis address and password.

spring:
  redis:
    host: 127.0.0.1
    port: 6379

Inject RedissonClient: You can use Redisson's functions directly through @Autowired.

@Autowired
private RedissonClient redissonClient;

Isn't it very simple? But don't worry, this is just the beginning! Next is the real core logic.

Key logic for realizing real-time rankings

The core functions of the rankings usually include:

  • Update scores: For example, the user increases points after completing an order.
  • Get Ranking: Query a user's current ranking.
  • Get Top N: Showcase the top 100 list.

Implementing these functions with Redisson is very intuitive:

// Update user scores("user1", 100);

// Get user ranking (from high to low)int rank = ("user1");

// Get the top 10Collection&lt;String&gt; top10 = (0, 9);

Here is a tip: Redisson's valueRangeReversed method can directly return the reverse order result, avoiding the overhead of manual sorting!

Performance optimization and practical pitfalls

In actual projects, rankings may face the problem of high concurrent updates. For example, during Double Eleven, the sales list of e-commerce platforms will be updated thousands of times per second! At this time, the following points need to be considered:

  • Batch operation: Redisson supports pipelines and batch commands, which can significantly reduce network overhead.
  • Distributed lock: If complex calculations are involved (such as integral weighting), RLock can be used to avoid concurrency problems.
  • Memory optimization: Redis's zset uses ziplist to store a small amount of data by default, but when the data volume is large, it will automatically be converted to skiplist. At this time, you should pay attention to memory usage.
//Use pipeline batch updateRBatch batch = ();
("ranking").addScoreAsync("user1", 10);
("ranking").addScoreAsync("user2", 20);
();

Extension: Multi-dimensional ranking

Sometimes we need multi-dimensional rankings, such as the coexistence of "weekly list" and "total list". At this time, you can use Redisson's RScoredSortedSet to cooperate with different keys to achieve:

RScoredSortedSet&lt;String&gt; weeklyRanking = ("ranking:weekly");
RScoredSortedSet&lt;String&gt; totalRanking = ("ranking:total");

​​​​​​​// Clear the weekly list every week();

Conclusion

With Spring Boot and Redisson, we can easily implement a high-performance real-time ranking system. From basic functions to performance optimization, Redisson provides a simple and powerful API. If you are facing similar needs, you might as well try it! Don’t panic when you encounter problems. Check more documents and communicate more. This is how technical growth comes step by step.

Method supplement

SpringBoot+Redission implements ranking function

1. Introduce Redis and Redission dependencies

<!-- redis -->  
<dependency>  
    <groupId></groupId>  
    <artifactId>spring-boot-starter-data-redis</artifactId>  
</dependency>  
  
<!-- redisson -->  
<dependency>  
    <groupId></groupId>  
    <artifactId>redisson-spring-boot-starter</artifactId>  
    <version>3.20.1</version>  
</dependency>

Configuration

--- # redis configurationspring:  
  redis:  
    # address    host: localhost  
    # port, default is 6379    port: 6379  
    # Database Index    database: 0  
    # Password (please comment out if there is no password)    # password: # Connection timeout    timeout: 10s  
    # Whether to enable ssl    ssl: false  
  
--- # redisson configurationredisson:  
  # redis key prefix  keyPrefix: ${}  
  # Number of thread pools  threads: 4  
  #Netty thread pool number  nettyThreads: 8  
  # Single node configuration  singleServerConfig:  
    # Client name    clientName: ${}  
    # Minimum number of idle connections    connectionMinimumIdleSize: 8  
    # Connection pool size    connectionPoolSize: 32  
    # Connection idle timeout, unit: milliseconds    idleConnectionTimeout: 10000  
    # Command waiting timeout, unit: milliseconds    timeout: 3000  
    # Publish and Subscribe Connection Pool Size    subscriptionConnectionPoolSize: 50

Code

Constant

/**
  * @author Baidu
  * @classname RankingConstant
  * @description Ranking constant data
  * @since 2024/5/6
  */
public class RankingConstant {  
  
    public static final Long BASIC_QUANTITY = 10000000000000L;  
  
    public static final Long MAXIMUM_TIME_TIMIT = 29991231235959L;  
}

Controller

import ;  
import ;  
import ;  
import ;  
import ;  
import ;  
import ;  
import ;  
import ;  
import ;  
import .*;  
  
import ;  
import ;  
import ;  
  
/**  
 * @author Baisu  
 * @since 2024/4/28  
 */
@RestController  
public class DemoRankingController {  
  
    @Value("${}")  
    private String applicationName;  
  
    /**
      * Project start testing method
      *
      * @return applicationName
      */    
    @GetMapping("")  
    public String demo() {  
        return applicationName;  
    }  
  
    /**
      * Generate test data
      *
      * @return ok
      */    
    @GetMapping("/generate_test_data")  
    public R&lt;Object&gt; generateTestData() {  
        ((), 1L, "10001");  
        ((), 2L, "10002");  
        ((), 3L, "10003");  
        ((), 4L, "10004");  
        ((), 5L, "10005");  
        return ();  
    }  
  
    /**
      * Get ranking data
      *
      * @param top quantity
      * @return ranking data
      */  
    @GetMapping("/get_ranking")  
    public R&lt;Object&gt; getRanking(@RequestParam("top") Integer top) {  
        Collection&lt;ScoredEntry&lt;Object&gt;&gt; ranking = ((), 0, top - 1);  
        if (() == 0) {  
            return ("No ranking data yet");  
        }  
        List&lt;RankingVo&gt; list = new ArrayList&lt;&gt;();  
        for (ScoredEntry&lt;Object&gt; entry : ranking) {  
            RankingVo vo = new RankingVo();  
            (().toString());  
            ((()));  
            ((()));  
            (vo);  
        }  
        return (list);  
    }  
  
    /**
      * Increase member score value
      *
      * @param member
      * @return Whether it increases success
      */  
    @GetMapping("/add_score_by_member")  
    public R&lt;Object&gt; addScoreByMember(@RequestParam("member") String member) {  
        Double scoreByMember = ((), member);  
        if (scoreByMember == null) {  
            scoreByMember = 0.0;  
        }  
        ((), (scoreByMember) + 1, member);  
        return ();  
    }  
  
    /**
      * Get member score value
      *
      * @param member
      * @return Fraction value
      */  
    @GetMapping("/get_score_by_member")  
    public R&lt;Object&gt; getScoreByMember(@RequestParam("member") String member) {  
        Double scoreByMember = ((), member);  
        if (scoreByMember == null) {  
            return ("This member does not exist");  
        }  
        RankingVo vo = new RankingVo();  
        (member);  
        ((scoreByMember));  
        ((scoreByMember));  
        return (vo);  
    }  
  
}

Domain

import ;  
  
/**
  * @author Baidu
  * @classname RankingVo
  * @description Ranking Display Class
  * @since 2024/5/6
  */
@Data  
public class RankingVo {  
  
    /**
      * Members
      */  
    private String member;  
    /**
      * Score value
      */  
    private Long score;  
    /**
      * time  
      */  
    private String time;  
  
}

Utils

/**
  * @author Baidu
  * @classname RedisKey
  * @description Redis index
  * @since 2024/5/6
  */
public class RedisKey {  
  
    private static final String RANKING_DEMO_KEY = "ranking_demo";  
  
    public static String getRankingDemoKey() {  
        return RANKING_DEMO_KEY;  
    }  
}
import ;  
import ;  
import ;  
import ;  
import ;  
import ;  
import ;  
  
import ;  
  
/**
  * @author Baidu
  * @classname RedisUtil
  * @description Redis tool class
  * @since 2024/5/6
  */
public class RedisUtil {  
  
    private static final RedissonClient REDISSON_CLIENT = ();  
  
    /**
      * Add a member of the specified score to the ordered set
      *
      * @param key Ordered set index
      * @param score
      * @param member
      * @return Success
      */  
    public static boolean addScoreByMember(String key, Long score, String member) {  
        RScoredSortedSet&lt;String&gt; rScoredSortedSet = REDISSON_CLIENT.getScoredSortedSet(key);  
        double v = score * RankingConstant.BASIC_QUANTITY + (RankingConstant.MAXIMUM_TIME_TIMIT - (((), )));  
        return (v, member);  
    }  
  
    /**
      * Returns the score value of the members in the ordered set
      *
      * @param key Ordered set index
      * @param member
      * @return Score value (Double)
      */    
     public static Double getScoreByMember(String key, String member) {  
        RScoredSortedSet&lt;Object&gt; scoredSortedSet = REDISSON_CLIENT.getScoredSortedSet(key);  
        return (member);  
    }  
  
    /**
      * Returns a set of members in the specified location in the ordered set
      *
      * @param key Ordered set index
      * @param start Start indexing
      * @param end end index
      * @return Member collection
      */  
    public static Collection&lt;ScoredEntry&lt;Object&gt;&gt; getRanking(String key, int start, int end) {  
        RScoredSortedSet&lt;Object&gt; rScoredSortedSet = REDISSON_CLIENT.getScoredSortedSet(key);  
        return (start, end);  
    }  
  
}
import ;  
import ;  
  
/**
  * @author Baidu
  * @classname RankingUtil
  * @description ranking tool category
  * @since 2024/5/7
  */
 public class RankingUtil {  
  
    public static final String FORMAT = "yyyyMMddHHmmss";  
  
    public static Long getScore(Double score) {  
        return ((score / RankingConstant.BASIC_QUANTITY));  
    }  
  
    public static String getTimeStr(Double score) {  
        return (((RankingConstant.MAXIMUM_TIME_TIMIT - ((score)) % RankingConstant.BASIC_QUANTITY)));  
    }  
}

This is the article about SpringBoot integrating Redisson to achieve high-performance real-time rankings. For more relevant SpringBoot Redisson real-time rankings, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!