如何使用Redis进行排序操作

本篇文章来介绍如何借助redis的zSet集合有序特性来帮助我们进行数据排序。

前言

我们在实际的开发过程中经常会遇到这样一个问题,需要高频次德对某个业务数据集进行某种规则的排序,如果是普通的排序,一般的方法就可以实现,我们这里强调的是海量数据、高频次的更新排序场景,如对上千万、上亿的数据进行排序操作。这时候需要我们花大量的时间和精力去寻找一种高效的排序算法,但往往需要各种因素的取舍,搞不好就要内存溢出,cpu爆棚等等负面影响,我们需要一种更好的算法,来解决这些问题。

原理

Redis支持多种数据类型,有String、List、Hash、Set、sorted set等等。
其中sorted Set有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数(score)却可以重复。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

通过对sortedSet特性分析:元素是String类型的集合、成员不重复、排序因子可以重复、hash表数据结构降低了操作复杂度、成员数量庞大
看完这些优良的特性,是不是感觉如果不用来进行海量数据的排序都浪费了。

实践

生成1000W条数据,并对这些数据进行排序,拿出前30条

    public void sortedUserList(int size) {
        Long startTime = System.currentTimeMillis();
        logger.info("Begin program:{}", startTime);
        while (size > 0) {
            redisTemplate.opsForZSet().incrementScore("userSet", size, size);
            size--;
        }
        Long numSize = redisTemplate.opsForZSet().size("userSet");
        Set set = redisTemplate.opsForZSet().range("userSet", 0, 30);
        logger.info("First 30 :[{}]", set);
        logger.info("End program:{}[{}ms]", numSize, System.currentTimeMillis() - startTime);
    }

在这里插入图片描述

这是简单的数据结构,所以1000W条耶只用了2.7秒就插入了

对前面的10条数据的score进行修改

    public void sortedUserList(int size) {
        Long startTime = System.currentTimeMillis();
        logger.info("Begin program:{}", startTime);
        while (size > 0) {
            redisTemplate.opsForZSet().incrementScore("userSet", size, 10);
            size--;
        }
        Long numSize = redisTemplate.opsForZSet().size("userSet");
        Set set = redisTemplate.opsForZSet().range("userSet", 0, 30);
        logger.info("First 30 :[{}]", set);
        logger.info("End program:{}[{}ms]", numSize, System.currentTimeMillis() - startTime);
    }

再取出30条

在这里插入图片描述
由上可以看出,把元素的score修改之后,其对应的顺序会自动排序。

在实际业务场景中可以灵活应用score的选择来达到对应的排序目的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章