Redis系列之——应用场景
Posted jvstarblog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis系列之——应用场景相关的知识,希望对你有一定的参考价值。
转:jianshu.com/p/91c1d5e059bd
1、缓存功能
缓存设计主要问题:
缓存穿透;
缓存击穿;
缓存与数据库不一致;
缓存热点数据;
https://www.cnblogs.com/scholar-xie/p/7111132.html
http://www.cnblogs.com/codeon/p/8287563.html
https://www.cnblogs.com/codeon/p/8287582.html
2、计数
http://zhuanlan.51cto.com/art/201707/543851.htm
3、共享session
http://zhuanlan.51cto.com/art/201705/540250.htm
4、分布式限流
phoneNum = "138xxxxxxxx";
key = "shortMsg:limit:" + phoneNum;
// SET key value EX 60 NX
isExists = redis.set(key,1,"EX 60","NX");
if(isExists != null || redis.incr(key) <=5){
// 通过
}else{
// 限速
}
https://www.cnblogs.com/softidea/p/6229543.html 令牌桶算法
5、分布式锁实现
@Service("distributedLockHandler")
public class DistributedLockHandler {
private static final Integer Lock_Timeout = 3;
@Autowired
private RedisTemplate redisTemplate;
private boolean innerTryLock(String lockKey){
JedisCmd jedisCmd = redisTemplate.getJedisCmd();
long currentTime = System.currentTimeMillis();
String lockTimeDuration = String.valueOf(currentTime + Lock_Timeout + 1);
Long result = jedisCmd.setnx(lockKey, lockTimeDuration);
if(result == 1){
return true;
}else {
if(checkIfLockTimeout(currentTime, lockKey)){//检查锁是否超时未释放
String preLockTimeDuration = jedisCmd.getSet(lockKey,lockTimeDuration);//利用getSet原子性。
//锁是否超时未释放,如果直接del key然后setnx key,当多个客户端使用时就后者就会覆盖前者操作。
if(currentTime > Long.valueOf(preLockTimeDuration)){
return true;
}
}
return false;
}
}
//获取锁
public boolean tryLock(String lockKey, Long timeout){
try{
Long currentTime = System.currentTimeMillis();
boolean result = false;
while (true){
if((System.currentTimeMillis() - currentTime)/1000 > timeout){//获取超时
jobLog.info("Execute DistributedLockHandler.tryLock method, Time out.");
break;
}else {
result = innerTryLock(lockKey);
if(result){
break;
}else {//重试
jobLog.debug("Try to get the Lock,and wait 100 millisecond....");
Thread.sleep(100);
}
}
}
return result;
}catch (Exception e){
jobLog.error("Failed to run DistributedLockHandler.getLock method.", e);
return false;
}
}
//释放锁
public void realseLock(String lockKey){
JedisCmd jedisCmd = redisTemplate.getJedisCmd();
jedisCmd.del(lockKey);
}
//检查锁是否超时
public boolean checkIfLockTimeout(Long currentTime, String lockKey){
JedisCmd jedisCmd = redisTemplate.getJedisCmd();
if(currentTime > Long.valueOf(jedisCmd.get(lockKey))){
return true;
}else {