forked from github/dataease
feat: 视图缓存 增加互斥锁 避免出现 缓存击穿现象
This commit is contained in:
parent
6afe2bdb9c
commit
9db28c74a4
@ -34,6 +34,7 @@ import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -55,6 +56,9 @@ public class ChartViewService {
|
||||
@Resource
|
||||
private ExtChartGroupMapper extChartGroupMapper;
|
||||
|
||||
//默认使用非公平
|
||||
private ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
public ChartViewWithBLOBs save(ChartViewWithBLOBs chartView) {
|
||||
checkName(chartView);
|
||||
long timestamp = System.currentTimeMillis();
|
||||
@ -219,8 +223,7 @@ public class ChartViewService {
|
||||
} else {
|
||||
datasourceRequest.setQuery(qp.getSQL(tableName, xAxis, yAxis, customFilter, extFilterList));
|
||||
}
|
||||
// String key = "provider_sql_"+datasourceRequest.getDatasource().getId() + "_" + datasourceRequest.getTable() + "_" +datasourceRequest.getQuery();
|
||||
// 定时抽取使用缓存
|
||||
/*// 定时抽取使用缓存
|
||||
Object cache;
|
||||
// 仪表板有参数不实用缓存
|
||||
if (CollectionUtils.isNotEmpty(requestList.getFilter())) {
|
||||
@ -228,13 +231,15 @@ public class ChartViewService {
|
||||
}
|
||||
// 仪表板无参数 且 未缓存过该视图 则查询后缓存
|
||||
else if ((cache = CacheUtils.get(JdbcConstants.VIEW_CACHE_KEY, id)) == null) {
|
||||
lock.lock();
|
||||
data = datasourceProvider.getData(datasourceRequest);
|
||||
CacheUtils.put(JdbcConstants.VIEW_CACHE_KEY, id, data, null, null);
|
||||
}
|
||||
// 仪表板有缓存 使用缓存
|
||||
else {
|
||||
data = (List<String[]>) cache;
|
||||
}
|
||||
}*/
|
||||
data = cacheViewData(datasourceProvider, datasourceRequest, id);
|
||||
}
|
||||
if (StringUtils.containsIgnoreCase(view.getType(), "pie") && data.size() > 1000) {
|
||||
data = data.subList(0, 1000);
|
||||
@ -301,6 +306,35 @@ public class ChartViewService {
|
||||
return dto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 避免缓存击穿
|
||||
* 虽然流量不一定能够达到击穿的水平
|
||||
* @param datasourceProvider
|
||||
* @param datasourceRequest
|
||||
* @param viewId
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public List<String[]> cacheViewData(DatasourceProvider datasourceProvider, DatasourceRequest datasourceRequest, String viewId) throws Exception{
|
||||
List<String[]> result ;
|
||||
Object cache = CacheUtils.get(JdbcConstants.VIEW_CACHE_KEY, viewId);
|
||||
if (cache == null) {
|
||||
if (lock.tryLock()) {// 获取锁成功
|
||||
result = datasourceProvider.getData(datasourceRequest);
|
||||
if (result != null) {
|
||||
CacheUtils.put(JdbcConstants.VIEW_CACHE_KEY, viewId, result, null, null);
|
||||
}
|
||||
lock.unlock();
|
||||
}else {//获取锁失败
|
||||
Thread.sleep(100);//避免CAS自旋频率过大 占用cpu资源过高
|
||||
result = cacheViewData(datasourceProvider, datasourceRequest, viewId);
|
||||
}
|
||||
}else {
|
||||
result = (List<String[]>)cache;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void checkName(ChartViewWithBLOBs chartView) {
|
||||
// if (StringUtils.isEmpty(chartView.getId())) {
|
||||
// return;
|
||||
|
Loading…
Reference in New Issue
Block a user