居安思危Redis读取的优势(Redis 读多写少)
居安思危,这句话源自春秋时期的思想家苏秦,比喻要尊重安全,时刻准备应对危机。随着互联网的发展和研究进步,同样也适用于我们的redis读取操作,每一次读取都要加入安全防护,因为可能存在各种不可预知的危险。
就Redis读取而言,首先要做好缓存击穿处理,避免因缓存击穿而造成大量没有缓存命中的数据库访问,进而出现读写压力瞬间猛然增大的情况。具体做法是,可以采用了分布式锁的机制,在一定的时间内,当有一个用户请求对同一个key进行读取操作时,其他请求会阻塞,直到超时或者刚刚获取了锁的请求释放key,这样就避免了大量的击穿现象。具体的实现代码示例如下:
//锁的唯一标识
String lockKey = "business_lock";//获取表示锁的key
String lockVal = randomVal();//锁的超时时间(毫秒)
int timeout = 10 * 1000;//设置锁并获取锁是否被设置成功
boolean setOk = setLock.setNX(lockKey, lockVal, timeout);if (setOk) {
// 设置锁成功,执行业务处理 doSomething();
//释放锁 String retVal = getValue(lockKey);
if (lockVal.equals(retVal)) { //解锁成功
deleteKey(lockKey); }
}
针对Redis读取操作,这也要加入熔断机制,因为Redis服务有可能出现异常状况,导致无法正常的读取数据,在短时间内大量业务请求集中导致Redis雪崩。熔断机制的实现方式是,当Redis读取的5次失败都会,触发熔断保护机制,中断原有连接和请求,直接转入熔断执行逻辑,代码实现如下:
//计数字段key
String count_key = "count_key";//最大失败次数
int MAX_FL_NUM = 5;//最大重试时间(秒)
int MAX_TRY_TIME = 10;//获取Redis计数
int count = getValue(count_key);//如果达到最大失败次数或者超过最大重试时间,就进行熔断
if (count >= MAX_FL_NUM || System.currentTimeMillis() - startTime > MAX_TRY_TIME * 1000) { //触发熔断
System.out.println("熔断处理"); return;
}//尝试从Redis读取
try { // 读取操作
Object object = readDataFromRedis(key); //操作成功,计数回归0
setValue(count_key, 0); //处理结果
processData(object); } catch (Exception e) {
//计数加1 incrInt(count_key);
System.out.println("重试中"); //重试
readRedisRetry(); }
我们要引入缓存雪崩保护机制,缓存雪崩,是指同时大量缓存失效,造成请求同时大量打到后台DB,造成数据库瞬时压力猛增,会造成服务不可用的情况,所以引入此机制就能有效的保护其中的安全。缓存雪崩机制的实现方式是,当Redis缓存访问数量突然增大时,通过一定的规则,逐步让请求慢慢的进入DB的访问,来缓解DB的访问压力,代码如下:
//判断访问量
String countKey = "access_count";//假设最大并发数为10
int MAX_CONCURENCY = 10;int count = getValue(countKey);
if (count > MAX_CONCURENCY) { //访问量大于最大并发数,采用缓存降级处理
return readDataFromDb();} else {
//返回缓存 return readDataFromRedis(key);
}
居安思危,对于Redis