一 :Redis 简介
redis 是目前最受欢迎的NoSql 数据库,是以内存作为数据存储介质,所以读写数据的效率极高,远远超过数据库。
redis的存储分为内存存储、磁盘存储和log文件三部分,重启后,Redis可以从磁盘重新将数据加载到内存中,此特性保证了数据的持久化。
今天主要简单的介绍下 redis的五种数据结构及其简单运用。
二 :String 结构与应用场景
1、单值缓存
set key value
get key
2、对象缓存
mset key value [key value …]
mget key [key …]
3、分布式锁
setnx key value [set if not exists]
key 不存在时,设置成功,返回 1,key 存在则不做任何操作 返回0
比如对一个商品 Logitech:gpw 进行加锁,因为redis 是单线程的,只有一个加锁成功,其他返回加锁失败,操作如下:
4、web集群session 共享
使用spring session + redis 实现 session 共享
5、计数器
incr key
应用场景 :
①:如右图的阅读数
②:对于自增需要的处理
@Autowired
private RedisTemplate redisTemplate;
/**
* TS+日期+4位数字
*
* @return
*/
public String getComplaintCode() {
SimpleDateFormat dfst = new SimpleDateFormat("yyyyMMdd");
String newDate = dfst.format(new Date());
String complaintCode = "";
Long incr = this.incr("complaintRepair" + newDate, 24);
if (incr == 0) {
incr = this.incr("complaintRepair" + newDate, 24);
}
DecimalFormat df = new DecimalFormat("0000");
complaintCode = "TS" + newDate + df.format(incr);
return complaintCode;
}
public Long incr(String key, long liveTime) {
RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
Long increment = entityIdCounter.getAndIncrement();
if ((null == increment || increment.longValue() == 0) && liveTime > 0) {//初始设置过期时间
entityIdCounter.expire(liveTime, TimeUnit.HOURS);
}
return increment;
}
三 :Hash 结构与应用场景
1、单值缓存
hset key field value
hset key field
2、对象缓存
hmset key field value [field value ...]
hmget key field [field ...]
3、举例说明
工作中很少用hset ,就举例说明:下图主要信息有 :购物车商品数量,购物车单个商品id及数量,可以全选商品,增加数量,删除商品等操作,具体如下
购物车 :
①:以用户id 为key
②:商品id 为field
③:商品数量为value
购物车操作 :
①:添加商品 hset wangch:7456 bose:1 1
②:增加数量 hincrby wangch:7456 bose:1 1
③:商品总数 hlen wangch:7456
④:删除商品 hdel wangch:7456 bose:1
⑤:获取购物车所有商品 hgetall wangch:7456
4、hash 结构的优缺点
优点 :
①:同类数据归类整合存储,方便数据管理
②:相比于string操作内存和cpu更小
③:相比于string存储更节省空间
缺点 :
①:过期功能不能使用在field上,只能使用在key上
②:redis集群架构下不适合大规模使用
四 :List 结构与应用场景
1、基础命令
lpush key value [value …]
value值 从左到右的顺序依次插入到表头
rpush key value [value ...]
value值 从右到左的顺序依次插入到表头
lpop key
移除并返回列表 key 的头元素
rpop key
移除并返回列表 key 的尾元素
lrange key start stop
返回列表key 指定区间内元素,区间以偏移量start和stop指定
blpop key [key …] timeout
从key列表表头弹出一个元素,若列表没有元素,阻塞等待timeout秒,如果timeout=0 ,一直等待下去
brpop key [key …] timeout
从key列表表尾弹出一个元素,若列表没有元素,阻塞等待timeout秒,如果timeout=0 ,一直等待下去
2、常用数据结构
Stack(栈)=lpush + lpop (先进后出)
Queue(队列)=lpush + rpop (先进先出)
Blocking MQ (阻塞队列)=lpush + brpop
3、微信公众号消息流
①:Java3y 推送消息,消息id为 222
lpush msg:wangch 222
②:Hollis 推送消息,消息id为 444
lpush msg:wangch 444
③:查看最新的公众号消息
lrange msg:wangch 0 4
此种方式适用于粉丝量小的公众号推送方式
五 :Set 结构与应用场景
1、set 常用操作
sadd key member [member] 新增元素 , 元素唯一不重复
srem key member [member] 删除元素
smembers key 获取集合key 所有元素
scard key 获取集合key 元素个数
sismember key member 判断元素是否存在于集合key
srandmember key [count] 从集合key中取出count个元素,元素不删除
spop key [count] 从集合key中取出count个元素,元素删除
2、应用实例 :微信抽奖小程序
①:点击参与抽奖加入集合
sadd key wangch
②:查看参与抽奖所有用户
smembers key
(scard key : 查看抽奖个数)
③:抽取count 名中奖者
srandmember key [count]/ spop key [count]
(也可以用于点赞,收藏等场景)
3、set 运算操作
sinter key [key …] 交集运算
sunion key [key …] 并集运算
sdiff key [key …] 差集运算
sinter set2 set3 set3 --> {c}
sunion set2 set3 set3 --> {a,b,c,d,e}
sdiff set2 set3 set3 --> {a}
4 、应用实例 :集合操作实现关注模型
①:wangch关注的人
sadd wangch zhangxh、lisi、wangwu
②:小明关注的人
sadd xiaom lisi、 wangwu、zhaol
③: 李四关注的人
sadd lisi xiaom 、zhaol、 xiaoq
获取 wangch 和小明的共同关注
sinter wangch xiaom --> {lisi、wangwu}
我关注的人也关注了他(小明)
sismember lisi xiaom --> 返回 1 存在,
则也关注了
我可能认识的人
sdiff wangch xiaom --> {zhangxh}
可用于淘宝推荐商品:共同关注的人越多,说明兴趣爱好相同。当A购买一件商品时,就可能给你也推荐
六 : ZSet 结构与应用场景
1、ZSet 常用操作
sadd key score member [[scoremember] …] 有序集合key加入带分值元素
srem key member [member] 有序集合删除元素
zscore key member 返回有序集合key中元素member分值
zcard key 有序集合key中的元素个数
zrange key start stop [withscores] 正序获取key从start下标到stop下标元素
zrevrange key start stop [withscores] 倒序获取key从start下标到stop下标元素
2、 ZSet 集合操作
zunionstore destkey numkeys key [key...] 并集操作
zinterstore destkey numkeys key [key...] 交集操作
3、 ZSet 实现微博排行榜
实现基础 : zset 数据会根据score自动排序,我们将点击次数作为zset ,随着用户点击实时变化
①:展示当日排行前十 (按照score倒序)
zrevrange hot:20201229 0 9 withscores
②:累计计算近七日点击次数
zunionstore hot:20201222-2021229 7hot:20201222 hot:20201223 … hot:2021229
③:展示七日排行前十
zrevrange hot:20201222-2021229 0 9 withscores
4、 ZSet 其他应用
zset 还可以用来实现延迟队列、接口限流等操作,主要是使用score 的特性,以时间戳作为score,来达到相应逻辑。