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)) {
redis支持的数据结构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个⽤户并发的情况
可以得到正确结果
订单⽣成类,部分逻辑代码
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论