zoukankan      html  css  js  c++  java
  • Redis缓存实现排序功能

    如果对实时并发排序感兴趣,请关注这个项目(java):https://github.com/xuerong/hqrank,欢迎参与开发,pass:支持多字段排行

    最近遇到一个问题就是根据需求需要对所有的用户根据积分,显示他的全站排名,数据量大概200万左右,积分是实时更改的,怎么能让这个排名尽量的实时呢?一直很困惑,之前用过db的count查,速度很慢,并且高峰时候db也容易堵住。

    这个实时性排序要求高,不建议用db做,db只是恢复数据用,排序及前端获取排行列表,我推荐用redis,数据结构采用其内置的sorted list,性能非常好,redis只保存最简单的id+积分这么一个数据,关闭实体化选项,全部用内存来保存数据,搭建主从防止宕机,然后自己实现一个从db到redis的数据恢复过程即可。
    数据保存的话,根据你实际并发量考虑,并发不高的话可以定时写入db,并发很高的话,中间需要再做一个缓冲队列。

    Jedis 是 Redis 官方首选的 Java 客户端开发包。这篇文章我们将介绍如何使用 Sorted Set 排序集合(zsets)。

    Sorted Set 跟一个集合一样,它是不会存在重复的数值,最大的不同是 Sorted Set 中每个元素都是经过排序的。

    我们先看一些命令:

    import java.util.HashMap;
    import java.util.Map;
    
    import redis.clients.jedis.Jedis;
    public class TestJedis {
    
    public static void main(String[] args) {
     String key = "mostUsedLanguages";
     Jedis jedis = new Jedis("localhost");
     //Adding a value with score to the set
     jedis.zadd(key,100,"Java");//ZADD
    
     //We could add more than one value in one calling
     Map<Double, String> scoreMembers = new HashMap<Double, String>();
     scoreMembers.put(90d, "Python");
     scoreMembers.put(80d, "Javascript");
     jedis.zadd(key, scoreMembers);
    
     //We could get the score for a member
     System.out.println("Number of Java users:" + jedis.zscore(key, "Java"));
    
     //We could get the number of elements on the set
     System.out.println("Number of elements:" + jedis.zcard(key));//ZCARD
     }
    }

    上述例子中我们看到了 Zset 命令,为了将元素添加到 zet 中,我们使用 zadd 方法,不同的是我们还传递了一个元素的评分值,我们可以使用 Map 对象来一次传递很多个对象,而 zadd 方法可用于增加和更新已有元素的评分值。

    我们可使用 zscore 来获取某元素的评分,通过 zcard 获取元素个数。

    下面的例子我们可看到来自 zsets 的其他命令:

    import java.util.Set;
    
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.Tuple;
    public class TestJedis {
    
    public static void main(String[] args) {
     String key = "mostUsedLanguages";
     Jedis jedis = new Jedis("localhost");
    
     //get all the elements sorted from bottom to top
     System.out.println(jedis.zrange(key, 0, -1));
    
     //get all the elements sorted from top to bottom
     System.out.println(jedis.zrevrange(key, 0, -1));
     //We could get the elements with the associated score
     Set<Tuple> elements = jedis.zrevrangeWithScores(key, 0, -1);
     for(Tuple tuple: elements){
     System.out.println(tuple.getElement() + "-" + tuple.getScore());
     }
    
     //We can increment a score for a element using ZINCRBY
     System.out.println("Score before zincrby:" + jedis.zscore(key, "Python"));
     //Incrementing the element score
     jedis.zincrby(key, 1, "Python");
     System.out.println("Score after zincrby:" + jedis.zscore(key, "Python"));
     }
    }

    通过 zrange 我们能获取给定范围的元素,它将返回经过排序后的元素列表(自底向上),也可以通过 zrevrrange 获取自顶向下的元素列表。Redis 还允许我们通过关联的评分来获取元素,传递 “withscores“ 参数即可。使用 Jedis API 的 zrevrangeWithScores 方法可返回对象集合。另外一个有用的命令是 zincrby 可用于增加元素的评分值。

    zsets 还有其他的命令,这里我们只是介绍跟 Jedis API 相关的一些基本用法。这里还有一些关于排序集合的介绍。

  • 相关阅读:
    Java性能权威指南读书笔记--之二
    Java性能权威指南读书笔记--之一
    深入理解JVM-java字节码文件结构剖析(练习解读字节码)
    深入理解JVM-java字节码文件结构剖析(1)
    jvm(5)---垃圾回收(回收算法和垃圾收集器)
    jvm(4)---垃圾回收(哪些对象可以被回收)
    jvm(3)---常用监控工具指令
    jvm(2)---类加载机制
    jvm(1)---java内存结构
    Eureka客户端源码流程梳理
  • 原文地址:https://www.cnblogs.com/barrywxx/p/8476320.html
Copyright © 2011-2022 走看看