Redis-07Redis数据结构--有序集合ZSet
文章目录
- 概述
- 有序集合的数据结构
- Redis 有序集合的部分命令
- spring-data-redis 对有序集合的封装
- 使用 Spring 操作有序集合
- 注意
- 代码
概述
有序集合和集合类似,只是说它是有序的,和无序集合的主要区别在于每一个元素除了值之外,它还会多一个分数。
- 分数是一个浮点数,在 Java 中是使用双精度表示的,根据分数, Redis 就可以支持对分数从小到大或者从大到小的排序
- 和无序集合一样,对于每一个元素都是唯一的 ,但是对于不同元素而言,它的分数可以一样
- 元素也是 String 数据类型,也是一种基于 hash 的存储结构。
- 集合是通过哈希表实现的,所以添加、删除、 查找的复杂度都是 0(1)
- 集合中最大的成员数为 2的32次方减 1 ( 40 多亿个成员)
有序集合的数据结构
有序集合是依赖 key 标示它是属于哪个集合,依赖分数进行排序,所以值和分数是必须的,而实际上不仅可以对分数进行排序,在满足一定的条件下,也可以对值进行排序 。
Redis 有序集合的部分命令
官网: https://redis.io/commands#sorted_set
有序集合和无序集合的命令是接近的,只是在这些命令的基础上,会增加对于排序的操作,这些是我们在使用的时候需要注意的细节.
有些时候 Redis 借助数据区间的表示方法来表示包含或者不包含,比如在数学的区间表示中[2,5 ]表示包含 2,但是不包含 5 的 区间。
命令 | 说明 | 备注 |
---|---|---|
zadd key score1 value1 [score2 value2 …] | 向有序集合的 key,增加一个或者多个成员 | 如果不存在对应的 key,则创建键为 key 的有序集合 |
zcard key | 获取有序集合的成员数 | ----- |
zcount key min max | 根据分数返回对应的成员列表 | min 为最小值, max为最大值,默认为包含min 和 max 值,采用数学区间表示的方法,如果需要不包含,则在分数前面加入“(”,注意不支持“[”表示 |
zincrby key increment member | 给有序集合成员值为 member 的分数增加 increment | ----- |
zinterstore desKey nurnkeys key1 [key2 key3 …] | 求多个有序集合的交集,并且将结果保存到 des Key 中 | numkeys 是一个整数,表示多少个有序集合 |
zlexcount key min max | 求有序集合 key 成员值在 min 和 max 的范围 | 这里范围为 key 的成员值, Redis 借助数据区间的表示方法,“[”表示包含该值,“(”表示不包含该值 |
zrange key start stop [withscores] | 按照分值的大小〈从小到大)返回成员,加入 start 和 stop 参数可以截取某一段返回.如果输入可选项 withscores,则连同分数一起返回 | 这里记集合最大长度为len,Redis 会将集合排序后,形成一个从 0 到len-1的下标,然后根据 start 和 stop 控制的下标(包含 start 和 stop)返回 |
zrank key member | 按从小到大求有序集合的排行 | 排名第一的为 0,第二的为 1 … |
zrangebylex key min max [limit offset count] | 根据值的大小,从小到大排序, min 为最小值, max 为最大值;limit 选项可选,当 Red is 求出范围集合后,会生产下标0到n,然后根据偏移量offset 和限定返回 数 count,返回对应的成员 | 这里范围为 key 的成员值, Red i s 借助数学区间的表示方法,“[”表示包含该值,“(”表示不包含该值 |
zrangebyscore key min max [withscores] [limit offset count] | 根据分数大小,从小到大求取范围,选项 withscores 和 limit 请参考 zrange 命令和zrangebylex 说明 | 根据分析求取集合的范围。这里默认包含 min和 max,如果不想包含,则在参数前加入“(”,注意不支持“ [”表示 |
zremrangebyscore key start stop | 根据分数区间进行删除 | 按照 socre 进行排序,然后排除 0 到len-1的下标,然后根据 start 和 stop 进行删除, Redis 借助数学区间的表示方法,“[”表示包含该值,“(”表示不包含该值 |
zremrangebyrank key start stop | 按照分数排行从小到大的排序删除,从0开始计算 | ----- |
zremrangebylex key min max | 按照值的分布进行删除 | ----- |
zrevrange key start stop [withscores] | 从大到小的按分数排序,参数请参见zrange | 与 zrange 相同,只是排序是从大到小 |
zrevrangebyscore key max min [withscores] | 从大到小的按分数排序,参数请参见zrangebyscore | 与 zrangebyscore 相同 ,只是排序是从大到小 |
zrevrank key member | 按从大到小的顺序,求元素的排行 | 排名第一位 0,第二位1 … |
zscore key member | 返回成员的分数值 | 返回成员的分数 |
zunionstore desKey numKeys key1 [key2 key3 key4 …] | 求多个有序集合的并集,其中 numKeys是有序,集合的个数 | ----- |
在对有序集合、下标、区间的表示方法进行操作的时候,需要十分小心命令,注意它是操作分数还是值,稍有不慎就会出现问题。
# 为了测试的数据干净,删除当前db的数据
127.0.0.1:6379> FLUSHDB
OK
127.0.0.1:6379>
127.0.0.1:6379>
# zadd key score1 value1 [score2 value2 …] 向有序集合zset1 ,增加9个成员
127.0.0.1:6379> ZADD zset1 1 x1 2 x2 3 x3 4 x4 5 x5 6 x6 7 x7 8 x8 9 x9
(integer) 9# zadd key score1 value1 [score2 value2 …] 向有序集合zset2 ,增加9个成员
127.0.0.1:6379> ZADD zset2 1 y1 2 x2 3 y3 4 x4 5 y5 6 x6 7 y7 8 x8 9 y9
(integer) 9# zcard key 获取有序集合zset1的成员数
127.0.0.1:6379> ZCARD zset1
(integer) 9# zcount key min max 根据分数返回对应的成员列表
127.0.0.1:6379> ZCOUNT zset1 1 4
(integer) 4# zinterstore desKey nurnkeys key1 [key2 key3 …] 求多个有序集合的交集,并且将结果保存到 des Key 中
127.0.0.1:6379> ZINTERSTORE des_key 2 zset1 zset2
(integer) 4# zlexcount key min max 求有序集合 zset1 成员值在 min 和 max 的范围 [ 表示包含该值,( 表示不包含该值
127.0.0.1:6379> ZLEXCOUNT zset1 (x1 [x5
(integer) 4# zrange key start stop [withscores] 按照分值的大小(从小到大)返回成员,加入 start 和 stop 参数可以截取某一段返回.如果输入可选项 withscores,则连同分数一起返回
127.0.0.1:6379> ZRANGE zset1 1 5 withscores1) "x2"2) "2"3) "x3"4) "3"5) "x4"6) "4"7) "x5"8) "5"9) "x6"
10) "6"# zrank key member 按从小到大求有序集合的排行
127.0.0.1:6379> ZRANK zset1 x5
(integer) 4# zrangebylex key min max [limit offset count]根据值的大小,从小到大排序 [表示包含该值 (表示不包含该值
127.0.0.1:6379> ZRANGEBYLEX zset1 (x1 [x6
1) "x2"
2) "x3"
3) "x4"
4) "x5"
5) "x6"
127.0.0.1:6379> # zrangebyscore key min max [withscores] [limit offset count] 根据分数大小,从小到大求取范围
127.0.0.1:6379> ZRANGEBYSCORE zset1 5 7
1) "x5"
2) "x6"
3) "x7"# zrangebyscore key min max [withscores] [limit offset count] 根据分数大小,从小到大求取范围
127.0.0.1:6379> ZRANGEBYSCORE zset1 2 7 withscores limit 1 5 1) "x3"2) "3"3) "x4"4) "4"5) "x5"6) "5"7) "x6"8) "6"9) "x7"
10) "7"# zrevrange key start stop [withscores] 从大到小的按分数排序
127.0.0.1:6379> ZREVRANGE zset1 1 5
1) "x8"
2) "x7"
3) "x6"
4) "x5"
5) "x4"# zrevrangebyscore key max min [withscores] 从大到小的按分数排序
127.0.0.1:6379> ZREVRANGEBYSCORE zset2 5 2 withscores
1) "y5"
2) "5"
3) "x4"
4) "4"
5) "y3"
6) "3"
7) "x2"
8) "2"# zrevrank key member 按从大到小的顺序,求元素的排行
127.0.0.1:6379> ZREVRANK zset1 x4
(integer) 5# zscore key member 返回成员的分数值
127.0.0.1:6379> ZSCORE zset1 x5
"5"# zunionstore desKey numKeys key1 [key2 key3 key4 …] 求多个有序集合的并集,其中 numKeys是有序,集合的个数
127.0.0.1:6379> ZUNIONSTORE des_key 2 zset1 zset2
(integer) 14# zincrby key increment member 给有序集合成员值为 member 的分数增加 increment
127.0.0.1:6379> ZINCRBY zset1 5 x9
"14"# zremrangebyscore key start stop 根据分数区间进行删除
127.0.0.1:6379> ZREMRANGEBYSCORE zset1 3 2
(integer) 0# zremrangebyscore key start stop 根据分数区间进行删除
127.0.0.1:6379> ZREMRANGEBYSCORE zset1 3 5
(integer) 3# zremrangebyrank key start stop 按照分数排行从小到大的排序删除,从0开始计算
127.0.0.1:6379> ZREMRANGEBYRANK zset1 1 3
(integer) 3# zremrangebylex key min max 按照值的分布进行删除
127.0.0.1:6379> ZREMRANGEBYLEX zset2 [y1 [y5
(integer) 6
127.0.0.1:6379>
127.0.0.1:6379> ZCARD zset1
(integer) 3
127.0.0.1:6379> ZCARD zset2
(integer) 3
127.0.0.1:6379>
127.0.0.1:6379> ZRANGE zset1 0 999
1) "x1"
2) "x8"
3) "x9"
127.0.0.1:6379> ZRANGE zset2 0 999
1) "y7"
2) "x8"
3) "y9"
127.0.0.1:6379>
spring-data-redis 对有序集合的封装
在 Spring 中使用 Redis 的有序集合,需要注意的是 Spring 对 Redis 有序集合的元素的值和分数的范围( Range )和限制( Limit)进行了封装。
我们来看下Spring是如何封装的。 先介绍一个主要的接口一一TypedTuple,它不是一个普通的接口,而一个内部接口.
org.springframework . data. redis.core .ZSetOperations 接口的内部接口,它定义了两个方
法
- getValue()是获取值, getScore()是获取分数,但是它只是一个接口,而不是一个实现类
- spring-data-red is 提供了 一个默认的实现类一DefaultTypedTuple
在默认的情况下 Spring 就会把带有分数的有序集合的值和分数封装到这个类中 ,这样就可以通过这个类对象读取对应的值和分数了 .
Spring 不仅对有序集合元素封装,而且对范围也进行了封装,方便使用.它是使用接口 org.springframe.work.data.redis.connection.RedisZSetCommands 下的内部类 Range 进行封装的,它有一个静态的 range()方法,使用它就可以生成一个 Range 对象了,只是要清楚 Range对象的几个方法才行.
// 设置大于等于 min
public Range gte(Object min)
// 设置大于 min
public Range gt(Object min)
// 设置小于等于 max
public Range lte(Object max)
// 设置小于 max
public Range lt(Object max)
这 4 个方法就是最常用的范围方法.
下面看一下limit,它是接口 org.springframework.data.redis.connection.RedisZSetCommands 下的内部类,它是一个简单的 POJO,它存在两个属性
通过属性的名称很容易知道:offset 代表从第几个开始截取,而 count 代表限制返回的总数量。
使用 Spring 操作有序集合
刚才讨论了 spring-data-redis 项目对有序集合的封装,在此基础上这里的演示示例代码在测试代码前,要把 RedisTemplate 的 keySerializer 和 valueSerializer属性都修改为字符串序列化器 StringRedisSerializer
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><context:property-placeholder location="classpath:redis/redis.properties" /><!--2,注意新版本2.3以后,JedisPoolConfig的property name,不是maxActive而是maxTotal,而且没有maxWait属性,建议看一下Jedis源码或百度。 --><!-- redis连接池配置 --><bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"><!--最大空闲数 --><property name="maxIdle" value="${redis.maxIdle}" /><!--连接池的最大数据库连接数 --><property name="maxTotal" value="${redis.maxTotal}" /><!--最大建立连接等待时间 --><property name="maxWaitMillis" value="${redis.maxWaitMillis}" /><!--逐出连接的最小空闲时间 默认1800000毫秒(30分钟) --><property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}" /><!--每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3 --><property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}" /><!--逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1 --><property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}" /><property name="testOnBorrow" value="true"></property><property name="testOnReturn" value="true"></property><property name="testWhileIdle" value="true"></property></bean><!--redis连接工厂 --><bean id="jedisConnectionFactory"class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"destroy-method="destroy"><property name="poolConfig" ref="jedisPoolConfig"></property><!--IP地址 --><property name="hostName" value="${redis.host.ip}"></property><!--端口号 --><property name="port" value="${redis.port}"></property><!--如果Redis设置有密码 --><property name="password" value="${redis.password}" /> <!--客户端超时时间单位是毫秒 --><property name="timeout" value="${redis.timeout}"></property><property name="usePool" value="true" /><!--<property name="database" value="0" /> --></bean><!-- 键值序列化器设置为String 类型 --><bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/><!-- redis template definition --><bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"p:connection-factory-ref="jedisConnectionFactory"p:keySerializer-ref="stringRedisSerializer"p:defaultSerializer-ref="stringRedisSerializer"p:valueSerializer-ref="stringRedisSerializer"></bean></beans>
package com.artisan.redis.baseStructure.zset;import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.redis.connection.RedisZSetCommands.Limit;
import org.springframework.data.redis.connection.RedisZSetCommands.Range;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;public class SpringRedisZSetDemo {private static final String ZSET1 = "zset1";private static final String ZSET2 = "zset2";@SuppressWarnings({ "unchecked", "rawtypes" })public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:spring/spring-redis-zset.xml");RedisTemplate redisTemplate = (RedisTemplate) ctx.getBean("redisTemplate");// 方便测试,清空数据redisTemplate.delete(ZSET1);redisTemplate.delete(ZSET2);// Spring 提供接口 TypedTuple 操作有序集合Set<TypedTuple> set1 = new HashSet<ZSetOperations.TypedTuple>();Set<TypedTuple> set2 = new HashSet<ZSetOperations.TypedTuple>();// 构造数据// 127.0.0.1:6379>// # zadd key score1 value1 [score2 value2 …] 向有序集合zset1 ,增加9个成员// >ZADD zset1 1 x1 2 x2 3 x3 4 x4 5 x5 6 x6 7 x7 8 x8 9 x9// (integer) 9// # zadd key score1 value1 [score2 value2 …] 向有序集合zset2 ,增加9个成员// > ZADD zset2 1 y1 2 x2 3 y3 4 x4 5 y5 6 x6 7 y7 8 x8 9 y9// (integer) 9int j = 9;String value1, value2 = null;double score1, score2 = 0.0;for (int i = 1; i <= 9; i++) {// 计算分数和值score1 = Double.valueOf(i);value1 = "x" + i;if (j > 0) {score2 = Double.valueOf(j);value2 = j % 2 == 1 ? "y" + j : "x" + j;j--;}// 使用 Spring提供的默认 TypedTuple-DefaultTypedTupleTypedTuple typedTuplel = new DefaultTypedTuple(value1,score1);set1.add(typedTuplel);TypedTuple typedTuple2 = new DefaultTypedTuple(value2,score2);set2.add(typedTuple2);}// 写入redisredisTemplate.opsForZSet().add(ZSET1, set1);redisTemplate.opsForZSet().add(ZSET2, set2);// 统计总数Long size = redisTemplate.opsForZSet().size(ZSET1);System.out.println(ZSET1 + "的size为" + size);// 计分数为 score ,那么下面的方法就是求 3<=score<=6 的元素Long count = redisTemplate.opsForZSet().count(ZSET1, 3, 6);System.out.println(ZSET1 + "中3<=score<=6 的count为" + count);// 从下标一开始截驭 5 个元素,但是不返回分数 , 每一个元素是 StringSet set = redisTemplate.opsForZSet().range(ZSET1, 1, 5);printSet(set);// 截取集合所有元素,并且对集合按分数排序,并返回分数 , 每一个元素是 TypedTupleSet<TypedTuple> typedTuples = redisTemplate.opsForZSet().rangeWithScores(ZSET1, 0, -1);printTypedTuple(typedTuples);// 将 zsetl 和 zset2 两个集合的交集放入集合 inter_zsetsize = redisTemplate.opsForZSet().intersectAndStore(ZSET1, ZSET2, "inter_zset");System.out.println("inter_zset size:" + size);// 查看交集inter_zset中的数据set = redisTemplate.opsForZSet().range("inter_zset", 0, redisTemplate.opsForZSet().size("inter_zset"));printSet(set);// 区间Range range = Range.range();range.lt("x8");// 小于range.gt("x1");// 大于set = redisTemplate.opsForZSet().rangeByLex(ZSET1, range);printSet(set);range.lte("x8");// 小于等于range.gte("x1");// 大于等于set = redisTemplate.opsForZSet().rangeByLex(ZSET1, range);printSet(set);// 限制返回个数Limit limit = Limit.limit();// 限制返回个数limit.count(4);// 限制从第2个开始截取limit.offset(2);// 求区间内的元素,并限制返回 4 条set = redisTemplate.opsForZSet().rangeByLex(ZSET1, range, limit);printSet(set);// 求排行,排名第 1 返回 0 ,第 2 返回 1Long rank = redisTemplate.opsForZSet().rank(ZSET1, "x4");System.out.println("rank=" + rank);// 删除元素 , 返回删除个数size = redisTemplate.opsForZSet().remove(ZSET1, "x5", "x6");System.out.println("remove " + size + " 个元素");// 按照排行删除从 0 开始算起,这里将删除第排名第 2 和第 3 的元素size = redisTemplate.opsForZSet().removeRange(ZSET1, 1, 2);System.out.println("removeRange " + size + " 个元素");// 获取所有集合的元索和分数 , 以 -1 代表全部元素typedTuples = redisTemplate.opsForZSet().rangeWithScores(ZSET1, 0, -1);printTypedTuple(typedTuples);// 删除指定的元素size = redisTemplate.opsForZSet().remove(ZSET2, "y3", "y5");System.out.println("remove " + size + " 个元素");// 给集合中的一个元素的分数加上 11Double double1 = redisTemplate.opsForZSet().incrementScore(ZSET2, "y1", 11);printTypedTuple(redisTemplate.opsForZSet().rangeWithScores(ZSET2, 0, redisTemplate.opsForZSet().size(ZSET2)));// 从大到小排列typedTuples = redisTemplate.opsForZSet().reverseRangeWithScores(ZSET2, 0, 99);printTypedTuple(typedTuples);}@SuppressWarnings("rawtypes")public static void printTypedTuple(Set<TypedTuple> typedTuples) {if (typedTuples != null && typedTuples.isEmpty()) {return;}Iterator<TypedTuple> iterator = typedTuples.iterator();while (iterator.hasNext()) {TypedTuple typedTuple = iterator.next();System.out.println("{value =" + typedTuple.getValue() + ", score=" + typedTuple.getScore() + "}");}System.out.println("----------------------");}@SuppressWarnings("rawtypes")public static void printSet(Set set) {if (set != null && set.isEmpty()) {return;}Iterator iterator = set.iterator();while (iterator.hasNext()) {Object val = iterator.next();System.out.println(val + "\t");}System.out.println("----------------------");}
}
输出
INFO : org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@73a8dfcc: startup date [Wed Sep 26 23:26:54 CST 2018]; root of context hierarchy
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [spring/spring-redis-zset.xml]
zset1的size为9
zset1中3<=score<=6 的count为4
x2
x3
x4
x5
x6
----------------------
{value =x1, score=1.0}
{value =x2, score=2.0}
{value =x3, score=3.0}
{value =x4, score=4.0}
{value =x5, score=5.0}
{value =x6, score=6.0}
{value =x7, score=7.0}
{value =x8, score=8.0}
{value =x9, score=9.0}
----------------------
inter_zset size:4
x2
x4
x6
x8
----------------------
x2
x3
x4
x5
x6
x7
----------------------
x1
x2
x3
x4
x5
x6
x7
x8
----------------------
x3
x4
x5
x6
----------------------
rank=3
remove 2 个元素
removeRange 2 个元素
{value =x1, score=1.0}
{value =x4, score=4.0}
{value =x7, score=7.0}
{value =x8, score=8.0}
{value =x9, score=9.0}
----------------------
remove 2 个元素
{value =x2, score=2.0}
{value =x4, score=4.0}
{value =x6, score=6.0}
{value =y7, score=7.0}
{value =x8, score=8.0}
{value =y9, score=9.0}
{value =y1, score=12.0}
----------------------
{value =y1, score=12.0}
{value =y9, score=9.0}
{value =x8, score=8.0}
{value =y7, score=7.0}
{value =x6, score=6.0}
{value =x4, score=4.0}
{value =x2, score=2.0}
----------------------
注意
使用 Spring 提供的 RedisTemplate 去展示多个命令可以学习到如何使用 RedisTemplate 操作 Redis 。 实际工作中并不是那么用的,因为每一 个操作会尝试从连接池里获取 一 个新的 Redis 连接,多个命令应该使用SessionCallback 接口进行操作 。
代码
代码托管到了 https://github.com/yangshangwei/redis_learn
Redis-07Redis数据结构--有序集合ZSet相关推荐
- php redis 搜索,PHP+Redis有序集合(zset)实现博客园阅读排行榜功能
许多网站都有排行榜的功能,比如球员人气榜单.阅读排行榜,对于一些小网站,通过查数据库就能实现排行榜的功能,但是对于稍微有点用户量而且还是实时排名的网站,使用一些关系型数据库如(MySQL.Oracle ...
- Redis—列表(List)、集合(Set)、哈希(Hash)、有序集合 Zset
Redis-列表List.集合Set.哈希Hash.有序集合 Zset 列表List 单键多值 常用命令 数据结构 Redis 集合(Set) 常用命令 数据结构 Redis 哈希(Hash) 常用命 ...
- redis有序集合zset详解
zset 概述 Redis有序集合zset与普通集合set非常相似,是一个没有重复元素的字符串集合. 不同之处是有序集合的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低 ...
- Redis 为什么这么快? Redis 的有序集合 zset 的底层实现原理是什么? —— 跳跃表 skiplist
Redis有序集合 zset 的底层实现--跳跃表skiplist Redis简介 Redis是一个开源的内存中的数据结构存储系统,它可以用作:数据库.缓存和消息中间件. 它支持多种类型的数据结构,如 ...
- redis延迟队列 实现_php使用redis的有序集合zset实现延迟队列
延迟队列就是个带延迟功能的消息队列,相对于普通队列,它可以在指定时间消费掉消息. 延迟队列的应用场景: 1.新用户注册,10分钟后发送邮件或站内信. 2.用户下单后,30分钟未支付,订单自动作废. 我 ...
- redis有序集合(Zset)
2019独角兽企业重金招聘Python工程师标准>>> Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员.不同的是每个元素都会关联一个double类型 ...
- 对 Redis 中的有序集合SortedSet的理解
本篇说一下Redis中的 有序集合类型,曾几何时,我们想把所有数据存到内存中的 数据结构 中,但为了多机器共享内存,不得不将这块内存包装成wcf单独部署,同时还要考虑怎么序列化,烦心事太多太多...后 ...
- PythonRedis 无序集合set、有序集合zset操作
1.Redis控制台操作无序集合set 无序集合 元素为string类型 元素具有唯一性,不重复 redis操作: 设置 添加元素 SADD key member [member ...] 获取 返回 ...
- redis 数据类型之有序集合(sorted set) 详细介绍
Redis的有序集合(sorted set)同时具有"有序"和"集合"两种性质,这种数据结构中的每个元素都由一个成员和一个与成员相关联的分值组成,其中成员以字符 ...
最新文章
- 原 史上最简单的SpringCloud教程 | 第八篇: 消息总线(Spring Cloud Bus)(Finchley版本)
- mysql mysqlhotcopy_MySQL备份工具之mysqlhotcopy
- macos 全局快捷键 打开 iterm_在 macOS 上实用的十大软件!你get了吗?
- 【图像分类】 基于Pytorch的细粒度图像分类实战
- 【8-20】java学习笔记02
- 合泰单片机c语言halt指令,holtek单片机图文全面详解
- php7 编译 pdo mysql_php7 编译 pdo_mysql 问题, [mysql_driver.lo] Error 1
- 25岁做什么,可在5年后受益匪浅?
- SQL Server中的表变量
- 一淘网是马云手中的防守牌
- 华为云学院-人人学loT学习笔记及扩展- 第一章 初识物联网
- 自然语言处理(NLP):国内会议
- vue音乐添加,控制开关
- 中国自媒体行业竞争格局与运营盈利模式分析报告2022年
- Eclipse之cannot be resolved to a type
- 度小满金融踩雷中粮信托近5000万,融资企业母公司为短融网大股东
- SQLSever 2000 安装环境
- 计算机相关专业宣讲会日程
- 金蝶星瀚人力云vs北森iTalentX 5.0,HR SaaS下半场如何开启?
- BN(Batch Normalization)层的详细介绍
热门文章
- N叉树的深度 python实现
- java json 教程,【简明教程】JSON
- 打开了悬浮窗权限但是没有_给你的手机添加“樱花雨”特效,打开手机樱花就满屏飘落,漂亮!...
- ssr pac_阴阳师新SSR千姬什么时候上线 ssr千姬活动上线时间一览
- ESIM (Enhanced LSTM for Natural Language Inference)
- 点云网络的论文理解(六)-Frustum PointNets 总体概括
- FCN全连接卷积网络(4)--Fully Convolutional Networks for Semantic Segmentation阅读(引言部分)
- 机器学习笔记:Transformer
- 文巾解题1738. 找出第 K 大的异或坐标值
- (经典)Hibernate多对一关系映射(四)