redis实战(五)

redis使用场景(zset)

前言

zset,有序set。看过我redis第一篇文章的小伙伴应该都知道,底层数据结构为跳表,通过跳表结构减小插入排序的时间复杂度(这里不知道的同学可以去看下第一篇文章)。同时查询时间复杂度也会减小。那么有序集合有什么作用呢?我们首先看一下redis zset的相关命令。

// 常见命令
#增加元素 (增加元素 A B C  对应积分 1 2 3 (排序的根据))
zadd myzset 1 A 2 B 3 C
#删除元素
zrem myzset A
#集合数量
zcard myzset
#增加某个元素的积分 加1
zincrby myzset increment A
#返回指定key对应的有序集合中,分值在min~max之间的元素个数
zcount myzset 0 10 (返回积分在0-10之间的元素数量)
#返回指定key对应的有序集合中,指定元素member在集合中排名,从0开始切分值是从小到大升序
zrank myzset A
#返回指定key对应的集合中,指定member在其中的排名,注意排名从0开始且按照分值从大到小降序
zrevrank myzset A
#返回指定key中的集合中指定member元素对应的分值
zscore myzset A
#返回指定key对应的有序集合中,索引在min~max之间的元素信息,如果带上 withscores 属性的话,可以将分值也带出来
zrange myzset 0 10 [withscores]
#指定key对应的集合中,分值在 start~end之间的降序,加上 withscores 的话可以将分值以及value都显示出来
zrevrange myzset 0 10 [withscores]
#同 zrange命令不同的是,zrange命令是索引在start~end范围的查询,而zrangebyscore命令是根据分值在start~end之间的查询且升序展示
zrangebyscore myzset 0 10 [withscores]

//当然 也有set的交并补命令 大家可以自行了解

正文

大家看了命令是不是颇有感触! 积分成为大多命令的关键字,通过积分我们会想到什么? 没错,排行榜! 这也就是redis zset的使用场景啦。在这个从出生就开始比来比去的时代,排行榜无非是从小就环绕着我们。(成绩排名什么的,最讨厌了。(#^.^#))。那么企业一般会用它来做什么呢? 微博的周榜?斗鱼刷礼物的日榜?运动步数排行?下面带大家了解下!

排行榜

排行榜的功能,无非增删改查,直接上代码。

@Autowired
private RedisTemplate redisTemplate;

//向排行榜中增加一个元素
public void add(Object element) throws ItemRankException {
    redisTemplate.opsForZSet().incrementScore(getKey(), element, 1);
}

//取指定排名的数据
public Set<E> range(Long rankStart, Long rankEnd) {
    return redisTemplate.opsForZSet().range(getKey(), rankStart, rankEnd);
}

//删除一个元素
public void remove(Long rankStart, Long rankEnd) {
    redisTemplate.opsForZSet().removeRange(getKey(), rankStart, rankEnd);
}

//是否包含
public boolean constants(Object element) {
    if (null == redisTemplate.opsForZSet().score(getKey(), element)) {
        return false;
    }
    return true;
}

//根据分数获取元素
public Set rangByScore(Long startScore, Long endScore) {
   return redisTemplate.opsForZSet().rangeByScore(getKey(), startScore, endScore);
}

//删除一个元素
public void remove(Object element) {
    redisTemplate.opsForZSet().remove(getKey(), element);
}

延时队列

上篇文章,我们讲了异步消息队列,那这个延时队列是什么鬼?队列不应该是基于list做吗? 别着急,我带大家一起来看一下。首先,什么是延时队列? 顾名思义,延时就是不立即执行,等到合适的时间再执行。那么延时队列有什么使用场景呢?其实无处不在,比如订单超过30分钟未付款自动取消。那这跟有序队列有什么关系呢? 大家不妨转变一下思维,积分未必非要是分数,如果把它设置为该数据需要执行的时间呢?也就是排行榜维护的积分是执行时间,那么启动一个线程去消费排行榜的数据,不就做到了延时队列的效果。

//伪代码

@Autowired
private RedisTemplate redisTemplate;

public static String REDIS_KEY = "redis_key";

//入队
public void add(Object element) throws ItemRankException {
    long curTime = System.currentTime();
    redisTemplate.opsForZSet().incrementScore(REDIS_KEY, element, curTime+30*60*100);
}


//消费队列
public void consume(){
    while(true){
        Set set = redisTemplate.opsForZSet().range(REDIS_KEY , 0, 10);
        if(CollectionUtils.isEmpty(set)){
            Thread.sleep(100);
        }
        set.forEach(//todo 处理逻辑)
    }
}

redis使用场景(hash)

redis的hash用来存储对象数据,但是通常会把对象序列化为string,然后使用string结构存储数据。 那么hash和string如何选取呢?我给大家列了一个表格,如下。

 stringhash
效率很高
容量
灵活性
序列化简单复杂
  • 如果对象某个元素经常更改,可以用hash或string+json
  • 如果对象中套对象(复杂的数据结构,使用string+json。

我觉得大部分情况用string+json就行了,hash很少用到。(个人见解)

结语

redis数据结构以及使用场景到此都已经讲完了,无论大家有没有收获,在这里都感谢大家阅读,欢迎批评指正。下面会介绍redis单机、哨兵、集群相关的知识,敬请期待。

关注不迷路

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值