居安思危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


数据运维技术 » 居安思危Redis读取的优势(Redis 读多写少)