Redis系列之(二)——應用場景

weixin_33936401發表於2018-03-10

1、快取功能

3951014-077850301ba016d8.png
redis.png

快取設計主要問題:
快取穿透;
快取擊穿;
快取與資料庫不一致;
快取熱點資料;
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

3951014-ea4a7d8408f9061b.png
session.png

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 {
            return false;
        }
    }
}

6、分散式佇列

用於秒殺、任務佇列等
https://www.jianshu.com/p/7e7070a0abd2

相關文章