访问我的博客

前言

排行榜作为互联网应用中几乎必不可少的一个元素,其能够勾起人类自身对比的欲望,从而来增加商品的销量。排行榜的实现方式基本大同小异,大部分都基于 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);

源码下载

点我下载

Java实现排行榜基于Redis的更多相关文章

  1. 基于Redis位图实现用户签到功能

    场景需求 适用场景如签到送积分.签到领取奖励等,大致需求如下: 签到1天送1积分,连续签到2天送2积分,3天送3积分,3天以上均送3积分等. 如果连续签到中断,则重置计数,每月初重置计数. 当月签到满 ...

  2. 基于redis排行榜的实战总结

    前言: 之前写过排行榜的设计和实现, 不同需求其背后的架构和设计模型也不一样. 平台差异, 有的立足于游戏平台, 为多个应用提供服务, 有的仅限于单个游戏.排名范围差异, 有的面向全局排名, 有的只做 ...

  3. 想知道谁是你的最佳用户?基于Redis实现排行榜周期榜与最近N期榜

    本文由云+社区发表 前言 业务已基于Redis实现了一个高可用的排行榜服务,长期以来相安无事.有一天,产品说:我要一个按周排名的排行榜,以反映本周内用户的活跃情况.于是周榜(按周重置更新的榜单)诞生了 ...

  4. Java基于redis实现分布式锁(SpringBoot)

    前言 分布式锁,其实原理是就是多台机器,去争抢一个资源,谁争抢成功,那么谁就持有了这把锁,然后去执行后续的业务逻辑,执行完毕后,把锁释放掉. 可以通过多种途径实现分布式锁,例如利用数据库(mysql等 ...

  5. 基于redis分布式缓存实现(新浪微博案例)

    第一:Redis 是什么? Redis是基于内存.可持久化的日志型.Key-Value数据库 高性能存储系统,并提供多种语言的API. 第二:出现背景 数据结构(Data Structure)需求越来 ...

  6. 基于redis分布式缓存实现

    Redis的复制功能是完全建立在之前我们讨论过的基 于内存快照的持久化策略基础上的,也就是说无论你的持久化策略选择的是什么,只要用到了Redis的复制功能,就一定会有内存快照发生,那么首先要注意你 的 ...

  7. 基于redis实现的分布式锁

    基于redis实现的分布式锁 我们知道,在多线程环境中,锁是实现共享资源互斥访问的重要机制,以保证任何时刻只有一个线程在访问共享资源.锁的基本原理是:用一个状态值表示锁,对锁的占用和释放通过状态值来标 ...

  8. 基于Redis的CAS服务端集群

    为了保证生产环境CAS(Central Authentication Service)认证服务的高可用,防止出现单点故障,我们需要对CAS Server进行集群部署. CAS的Ticket默认是以Ma ...

  9. 基于Redis的在线用户列表解决方案

    前言: 由于项目需求,需要在集群环境下实现在线用户列表的功能,并依靠在线列表实现用户单一登陆(同一账户只能一处登陆)功能: 在单机环境下,在线列表的实现方案可以采用SessionListener来完成 ...

随机推荐

  1. Shell编程-09-Shell中的函数

    目录 基本语法 函数执行 函数示例     函数可以简化程序的代码量,达到更好的代码复用度,因此会让程序变得更加易读.简洁和易修改.其作用就是将需要多次使用的代码整合到一块,使其成为一个整体,然后通过 ...

  2. 【python-excel】Selenium+python自动化之读取Excel数据(xlrd)

    Selenium2+python自动化之读取Excel数据(xlrd) 转载地址:http://www.cnblogs.com/lingzeng86/p/6793398.html ·········· ...

  3. Spring的两种代理JDK和CGLIB的区别浅谈

    一.原理区别: java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理. 而cglib动态代理是利用asm开源包,对代理对象类的class文件 ...

  4. [转]Windows中使用命令行方式编译打包Android项目

    http://my.oschina.net/liux/blog/37875 网上很多用Ant来编译打包Android应用的文章,毕竟Ant是纯Java语言编写的,具有很好的跨平台性.今天想写个纯win ...

  5. SPRING框架中ModelAndView、Model、ModelMap区别及详细分析

    转载内容:http://www.cnblogs.com/google4y/p/3421017.html 1. Model Model 是一个接口, 其实现类为ExtendedModelMap,继承了M ...

  6. Android创建AVD模拟器

    Android创建AVD模拟器 1. 新建一个安卓工程如下: 2. 点击windows里的 Android Virtual Device Manager,如果第一次安装 adt-bundle启动会出现 ...

  7. debian7(wheezy)升级安装mercurial hg最新版2.8-RC,解决tortoisehg2.9.2不能使用。

    debian&(wheezy)之前的仓库版本是2.2.2.  注: 本文以 # 为开始的行是工作在root下的模式,在终端显示为root的提示符# ,用户目录的($:)需要切换到root(使用 ...

  8. spring boot 整合 mybatis 以及原理

    同上一篇文章一样,spring boot 整合 mybatis过程中没有看见SqlSessionFactory,sqlsession(sqlsessionTemplate),就连在spring框架整合 ...

  9. <string.h>的学习

    感觉学习代码库最好的方法就是运行一下. 下面附上结果和示例代码 #include <stdio.h> #include <string.h> int main(){ const ...

  10. WPF 嵌入Winform GDI 、 开启AllowsTransparenc问题

    此文章可以解决2至少2个问题: 1.开启AllowsTransparenc造成的GDI+组件不显示问题 2.WPF 组件无法覆盖嵌入WPF窗口的任何第三方GDI+组件上层 方案1:自制双层 原理:用一 ...