Unverified 提交 6ba4d182 authored 作者: fit2cloud-chenyw's avatar fit2cloud-chenyw 提交者: GitHub

Merge pull request #101 from dataease/pr@dev@cyw

feat: 视图缓存 增加互斥锁 避免出现 缓存击穿现象
...@@ -34,6 +34,7 @@ import javax.annotation.Resource; ...@@ -34,6 +34,7 @@ import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.util.*; import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
...@@ -55,6 +56,9 @@ public class ChartViewService { ...@@ -55,6 +56,9 @@ public class ChartViewService {
@Resource @Resource
private ExtChartGroupMapper extChartGroupMapper; private ExtChartGroupMapper extChartGroupMapper;
//默认使用非公平
private ReentrantLock lock = new ReentrantLock();
public ChartViewWithBLOBs save(ChartViewWithBLOBs chartView) { public ChartViewWithBLOBs save(ChartViewWithBLOBs chartView) {
checkName(chartView); checkName(chartView);
long timestamp = System.currentTimeMillis(); long timestamp = System.currentTimeMillis();
...@@ -219,8 +223,7 @@ public class ChartViewService { ...@@ -219,8 +223,7 @@ public class ChartViewService {
} else { } else {
datasourceRequest.setQuery(qp.getSQL(tableName, xAxis, yAxis, customFilter, extFilterList)); datasourceRequest.setQuery(qp.getSQL(tableName, xAxis, yAxis, customFilter, extFilterList));
} }
// String key = "provider_sql_"+datasourceRequest.getDatasource().getId() + "_" + datasourceRequest.getTable() + "_" +datasourceRequest.getQuery(); /*// 定时抽取使用缓存
// 定时抽取使用缓存
Object cache; Object cache;
// 仪表板有参数不实用缓存 // 仪表板有参数不实用缓存
if (CollectionUtils.isNotEmpty(requestList.getFilter())) { if (CollectionUtils.isNotEmpty(requestList.getFilter())) {
...@@ -228,13 +231,15 @@ public class ChartViewService { ...@@ -228,13 +231,15 @@ public class ChartViewService {
} }
// 仪表板无参数 且 未缓存过该视图 则查询后缓存 // 仪表板无参数 且 未缓存过该视图 则查询后缓存
else if ((cache = CacheUtils.get(JdbcConstants.VIEW_CACHE_KEY, id)) == null) { else if ((cache = CacheUtils.get(JdbcConstants.VIEW_CACHE_KEY, id)) == null) {
lock.lock();
data = datasourceProvider.getData(datasourceRequest); data = datasourceProvider.getData(datasourceRequest);
CacheUtils.put(JdbcConstants.VIEW_CACHE_KEY, id, data, null, null); CacheUtils.put(JdbcConstants.VIEW_CACHE_KEY, id, data, null, null);
} }
// 仪表板有缓存 使用缓存 // 仪表板有缓存 使用缓存
else { else {
data = (List<String[]>) cache; data = (List<String[]>) cache;
} }*/
data = cacheViewData(datasourceProvider, datasourceRequest, id);
} }
if (StringUtils.containsIgnoreCase(view.getType(), "pie") && data.size() > 1000) { if (StringUtils.containsIgnoreCase(view.getType(), "pie") && data.size() > 1000) {
data = data.subList(0, 1000); data = data.subList(0, 1000);
...@@ -301,6 +306,35 @@ public class ChartViewService { ...@@ -301,6 +306,35 @@ public class ChartViewService {
return dto; 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) { private void checkName(ChartViewWithBLOBs chartView) {
// if (StringUtils.isEmpty(chartView.getId())) { // if (StringUtils.isEmpty(chartView.getId())) {
// return; // return;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论