Redis 应用场景

1. 排行榜应用,取TOP N操作

    使用hash保存文章信息,用zset保存排行榜信息,方便直接获取最新的id。

   

public class ArticleService 
{
    private Jedis jedis = new Jedis("127.0.0.1", 6379);
    private static int VOTE_SCORE = 400;
    private static int ONE_WEEK_IN_SECONDS = 7 * 24 * 3600;
    private static int PAGE_COUNT = 7;
    
    // 发布文章
    public String postArticle(String title, String content, String userId) {
        
        String articleId = "article:" + jedis.incr("article:");
        long now = System.currentTimeMillis() / 1000;
        
        HashMap<String, String> articleData = new HashMap<String, String>();
        articleData.put("title", title);
        articleData.put("content", content);
        articleData.put("author", userId);
        articleData.put("datetime", String.valueOf(now));
        articleData.put("votes", "0");              // 初始化投票数为0
        jedis.hmset(articleId, articleData);        // 添加文章
        
        jedis.expire(getVoteId(articleId), ONE_WEEK_IN_SECONDS);   // 设置文章投票过期时间, 过期时会被自动删除
        jedis.zadd("timelist" , now, articleId);                   // 将文章添加到时间排行榜, 以时间戳进行排名
        jedis.zadd("scorelist", now + VOTE_SCORE, articleId);      // 将文章添加到分数排行榜, 以时间戳+投票数进行排名
        return articleId;
    }
    
    // 文章投票
    public void voteArticle(String articleId, String userId) {
        
        double expiretime = jedis.zscore("timelist", articleId) + ONE_WEEK_IN_SECONDS;
        if(System.currentTimeMillis() / 1000 > expiretime) { // 判断投票是否过期
            return;
        }
        if(jedis.sadd(getVoteId(articleId), userId) == 1) {    // 若用户已投票则返回0
            jedis.zincrby("scorelist", VOTE_SCORE, articleId);
            jedis.hincrBy(articleId, "votes", 1);
        }
    }
    
    // 获取文章列表
    public List<Map<String, String>> getArticles(int page, String orderKey) {
        
        int start = (page - 1) * PAGE_COUNT;
        int end = page * PAGE_COUNT - 1;
        Set<String> ids = jedis.zrevrange(orderKey, start, end); // 按分数倒序排序
        
        List<Map<String,String>> articles = new ArrayList<Map<String,String>>();
        for (String id : ids){
            Map<String,String> articleData = jedis.hgetAll(id);
            articleData.put("id", id);
            articleData.put("vote members:", jedis.smembers(getVoteId(id)).toString());
            articles.add(articleData);
        }
        return articles;
    }
    
    private String getVoteId(String articleId) {
        return "vote:" + articleId.split(":")[1];
    }
    
    public static void main( String[] args ) throws InterruptedException
    {    
        ArticleService service = new ArticleService();
        String articleId1 = service.postArticle("Python", "This is a python article", "z001");
        print("post " + articleId1);
        String articleId2 = service.postArticle("Java", "Hello World", "z002");
        print("post " + articleId2);
        service.voteArticle(articleId1, "z005");
        print("vote " + articleId1);
        print(service.getArticles(1, "timelist"));
        print(service.getArticles(1, "scorelist"));
    } 
    
    public static void print(Object obj) {
        System.out.println(obj);
    }
}

------------------------------  输出结果  ----------------------------------
第一篇文章得到一个投票(评分+400分),因此在分数排行榜排名靠前,但是在时间排行榜依旧靠后

post article:1
post article:2
vote article:1
[  -- 时间排行榜
{id=article:2, content=Hello World, author=z002, title=Java, votes=0, vote members:=[], datetime=1524191117},  
{id=article:1, content=This is a python article, author=z001, title=Python, votes=1, vote members:=[z005], datetime=1524191117}
]
[  -- 分数排行榜
{id=article:1, content=This is a python article, author=z001, title=Python, votes=1, vote members:=[z005], datetime=1524191117}, 
{id=article:2, content=Hello World, author=z002, title=Java, votes=0, vote members:=[], datetime=1524191117}
]

 

posted @ 2018-04-19 18:02  安小  阅读(136)  评论(0编辑  收藏  举报