基于Redis实现分布式锁解决OLAP中SQL重复执行
在大数据的报表系统中,OLAP引擎处于一个报表初步制作、短期使用的阶段,此阶段报表处于需要固化,但还不能固化的状态,此时大量的查询会进入OLAP引擎,引擎层会承受巨大的压力
只是简单的将查询结果使用缓存保存,可能依旧存在风险
当用户的查询需要较长时间,且缓存中不存在时,用户可能因为焦虑等原因频繁发起查询请求。由于每一次的查询都无法命中缓存,造成缓存穿透,数据引擎压力继续加重,甚至面临崩溃
处理流程如下
接受查询请求
组装查询SQL,生成缓存key
缓存存在 —> 读取缓存 ,返回结果
缓存不存在 —> 尝试setNx 获取SQL执行锁
获取锁失败 —> 生成等待key,加入blockList —> 使用blpop,阻塞获取releaseList —> 获取release元素 —> 再次尝试获取key对应的缓存 —> 成功返回结果
再次获取失败,报错,用户重试
获取锁成功—>开始执行 —>执行完成—> 保存结果至redis—>释放写锁—>释放阻塞查询(将blockList 添加至releaseList)
使用Supplier作为参数,将具体的实现用Supplier传入,实现封装和代码的复用