redis 常用的命令、redis缓存机制、redis数据结构、redis分布式锁

本篇博客将结合redis在电商项目中的使用,说明redis的常用命令

redis中的数据结构:

业务场景一:缓存商城首页不同分类栏中的商品信息,以优化商城首页的访问速度。For example:以淘宝网为例

1.1.有好货分类栏中的商品广告信息

1.2.爱逛街分类栏中的商品广告信息

等等(可以去淘宝网自己参考)。

1.3 redis实现的缓存机制:(缓存机制的一般规则:先查缓存,再查数据库,如果缓存中没有,则将查询到数据写入缓存)

1.3.1.选择的数据类型为hash,key固定为CONTENT_LIST,field为分类栏id,value为商品信息(数据类型为字符串,这里利用json工具类将java集合对象转换为json字符串),部分业务逻辑代码示例如下:

1.3.2.根据cid查询缓存,将value(json字符串)转换为java的list对象,部分业务逻辑代码示例如下:

1.3.3.缓存同步,当添加新的内容,将相应的缓存删除,这样再次查询的时候回查询数据库并回写缓存

1.3.4.使用到的redis命令

hset key field value
hget key field
hedl key field
hgetall key

使用示例如下

 

业务场景二:redis实现的分布式锁

2.1.加锁代码

public class RedisTool {

private static final String LOCK_SUCCESS = "OK";
private static final String SET_IF_NOT_EXIST = "NX";
private static final String SET_WITH_EXPIRE_TIME = "PX";

/**
* 尝试获取分布式锁
* @param jedis Redis客户端
* @param lockKey 锁
* @param requestId 请求标识
* @param expireTime 超期时间
* @return 是否获取成功
*/
public static boolean tryGetDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) {

String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);

if (LOCK_SUCCESS.equals(result)) {
return true;
}
return false;

}

}

可以看到,我们加锁就一行代码:jedis.set(String key, String value, String nxxx, String expx, int time),这个set()方法一共有五个形参:

  • 第一个为key,我们使用key来当锁,因为key是唯一的。
  • 第二个为value,我们传的是requestId,很多童鞋可能不明白,有key作为锁不就够了吗,为什么还要用到value?原因就是我们在上面讲到可靠性时,分布式锁要满足第四个条件解铃还须系铃人,通过给value赋值为requestId,我们就知道这把锁是哪个请求加的了,在解锁的时候就可以有依据。requestId可以使用UUID.randomUUID().toString()方法生成。
  • 第三个为nxxx,这个参数我们填的是NX,意思是SET IF NOT EXIST,即当key不存在时,我们进行set操作;若key已经存在,则不做任何操作;
  • 第四个为expx,这个参数我们传的是PX,意思是我们要给这个key加一个过期的设置,具体时间由第五个参数决定。
  • 第五个为time,与第四个参数相呼应,代表key的过期时间。

总的来说,执行上面的set()方法就只会导致两种结果:1. 当前没有锁(key不存在),那么就进行加锁操作,并对锁设置个有效期,同时value表示加锁的客户端。2. 已有锁存在,不做任何操作。

心细的童鞋就会发现了,我们的加锁代码满足我们可靠性里描述的三个条件。首先,set()加入了NX参数,可以保证如果已有key存在,则函数不会调用成功,也就是只有一个客户端能持有锁,满足互斥性。其次,由于我们对锁设置了过期时间,即使锁的持有者后续发生崩溃而没有解锁,锁也会因为到了过期时间而自动解锁(即key被删除),不会发生死锁。最后,因为我们将value赋值为requestId,代表加锁的客户端请求标识,那么在客户端在解锁的时候就可以进行校验是否是同一个客户端。由于我们只考虑Redis单机部署的场景,所以容错性我们暂不考虑。

2.2. 解锁逻辑:首先获取锁对应的value值,检查是否与requestId相等,如果相等则删除锁(解锁)。

2.3.主要使用到的redis命令

#即当key不存在时,我们进行set操作;若key已经存在,则不做任何操作;设置成功返回“1”,设置失败返回“0”
setnx key value

expire key seconds
del key 

使用示例

业务场景三:使用redis的原子计数器incr生成订单号

3.1.Redis原子计数器incr,具有原子性,可以避免高并发下生成重复订单号的情况,测试如下。

模拟100个用户并发的情况

可以得到正确结果

订单生成类,部分逻辑代码

3.2.使用到的redis命令

incr key
decr ordeid

使用示例

业务场景四:将购物车中的商品缓存到redis中

4.1.redis使用的缓存机制:使用hash数据类型,key为cart前缀+用户ID,field为商品ID,value为商品信息(包含了商品的数量)

4.2.添加购物车的部分业务逻辑代码如下所示:

4.3.使用到的redis命令,同业务场景一。(redis中hash数据类型的操作)

4.4.何时清空购物车,订单创建完成之时。

最后一些常用的redis命令

①查询所有key

keys *

使用示例

②list 是有序列表,这个可以玩出很多花样。

比如可以通过 list 存储一些列表型的数据结构,类似粉丝列表文章的评论列表之类的东西。比如可以通过 lrange 命令,读取某个闭区间内的元素,可以基于 list 实现分页查询,这个是很棒的一个功能,基于 redis 实现简单的高性能分页,可以做类似微博那种下拉不断分页的东西,性能高,就一页一页走。

# 0开始位置,-1结束位置,结束位置为-1时,表示列表的最后一个位置,即查看所有。

lrange mylist 0 -1

比如可以搞个简单的消息队列,从 list 头怼进去,从 list 尾巴那里弄出来。

lpush mylist 1

lpush mylist 2

lpush mylist 3 4 5


rpop mylist

rpush与lpush的区别

rpush(key, value):在名称为key的list尾添加一个值为value的元素

lpush(key, value):在名称为key的list头添加一个值为value的 元素

使用示例

set 是无序集合,自动去重。

直接基于 set 将系统里需要去重的数据扔进去,自动就给去重了,如果你需要对一些数据进行快速的全局去重,你当然也可以基于 jvm 内存里的 HashSet 进行去重,但是如果你的某个系统部署在多台机器上呢?得基于 redis 进行全局的 set 去重。

可以基于 set 玩交集、并集、差集的操作,比如交集吧,可以把两个人的粉丝列表整一个交集,看看俩人的共同好友是谁?对吧。

把两个大 V 的粉丝都放在两个 set 中,对两个 set 做交集。

#-------操作一个set-------
# 添加元素
sadd mySet 1

# 查看全部元素
smembers mySet

# 判断是否包含某个值
sismember mySet 3

# 删除某个/些元素
srem mySet 1
srem mySet 2 4

# 查看元素个数
scard mySet

# 随机删除一个元素
spop mySet

#-------操作多个set-------
# 将一个set的元素移动到另外一个set
smove yourSet mySet 2

# 求两set的交集
sinter yourSet mySet

# 求两set的并集
sunion yourSet mySet

# 求在yourSet中而不在mySet中的元素
sdiff yourSet mySet

④sorted set 是排序的 set,去重但可以排序,写进去的时候给一个分数,自动根据分数排序。

zadd board 85 zhangsan
zadd board 72 lisi
zadd board 96 wangwu
zadd board 63 zhaoliu

# 获取排名前三的用户(默认是升序,所以需要 rev 改为降序)
zrevrange board 0 3

# 获取某用户的排名
zrank board zhaoliu

使用示例

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值