专栏首页业余草手把手教你使用 Java 和 Redis 实现排行榜!

手把手教你使用 Java 和 Redis 实现排行榜!

编辑:业余草 来源:https://www.xttblog.com/?p=4937

前言

排行榜作为互联网应用中几乎必不可少的一个元素,其能够勾起人类自身对比的欲望,从而来增加商品的销量。排行榜的实现方式基本大同小异,大部分都基于 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> LINDEX dynamic 0
"abc"
# 通过索引获取列表中的元素
redis> LTRIM dynamic 0 2
"abc"
# 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除

排行榜预览

按照需求开发,最后的效果如下:

下面我们通过 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);

上面是主要的实现代码,还有不少细节需要完善。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 使用easydrag实现可拖动的DIV弹出框

    最近在工作中遇到了jquery的easydrag插件,我有一种相见恨晚的赶脚!easydrag极大的方法我们实现div弹框这个...

    业余草
  • 利用 Redis 实现“附近的人”功能!

    针对“附近的人”这一位置服务领域的应用场景,常见的可使用 PG、MySQL 和 MongoDB 等多种 DB 的空间索引进行实现。

    业余草
  • 手把手教你实现一个基于 Java 的分布式锁服务

    编辑:业余草 来源:https://www.xttblog.com/?p=4994

    业余草
  • Redis笔记(六):Java中使用Redis

    下载地址: http://central.maven.org/maven2/redis/clients/jedis/2.9.0/jedis-2.9.0.jar

    朝雨忆轻尘
  • 享元模式

    tanoak
  • DoubleAnimation方法

    现在silverlight中还不支持直接用c#代码来创建动画,只能通过XamlReader来加载storyboard。 今天看了DoubleAnimation...

    用户1172164
  • OC知识--Foundation框架详尽总结之『字典类』

    行走少年郎
  • 基于Spring的可扩展Schema进行开发自定义配置标签支持

      最近和朋友一起想开发一个类似alibaba dubbo的功能的工具,其中就用到了基于Spring的可扩展Schema进行开发自定义配置标签支持,通过上网查资...

    阿豪聊干货
  • Redis的高级特性与应用场景(一)

    redis 中可以使用 expire 命令设置一个键的生存时间,到期后 redis 会自动删除他

    憧憬博客
  • 25.Linux-Nor Flash驱动(详解)

    1.nor硬件介绍: ? 从原理图中我们能看到NOR FLASH有地址线,有数据线,它和我们的SDRAM接口相似,能直接读取数据,但是不能像SDRAM直接写入数...

    张诺谦

扫码关注云+社区

领取腾讯云代金券