说起缓存, 大家可能口若悬河, 各种类型的缓存都能一一分析, 但在 net 下找到一款合适的 Disk Cache 貌似还是有一点难度的
一: 背景
事情是这样的, 最近的一个项目中, 需要在 web 端绘制一些报表, 因为报表的基础数据源都是全内存式的, 所以内存相对我们来说是比较吃紧的, 大家可能
大家知道, 比如一些散点图, 这种类型的报表数据非常的多, 为了加速, 我需要缓存两种数据:
1. 根据基础数据源计算出中间结果, 为了下一次加速, 缓存个几十分钟, 这个数据量相对来说比较大
2. 将服务的 Response 进行 30 分钟缓存, 这个数据量也相对比较大, 大概 10-50M 的样子
刚才也说了, 内存比较吃紧, 如果把这些数据再放到内存里面就比较尴尬, 也是业务不允许的, 如果把这么大的数据块放在分布式缓存中, 流量起来之后带
宽也是一个问题, 会更多的面临超时的风险, 所以最好的方式就是使用本机磁盘缓存, 这样就可以在性能和内存中取一个平衡点~~~
二: 寻找解决方案
平衡点找到了, 貌似在. net 领域中很少听说有磁盘缓存这种概念, 既然听说的少, 那就在 nuget 中浪一浪, 然后就找到了一个 top1 的 diskcache, 如下图:
拉下来一测试, 卧槽, 就的一个 CURD 操作, 连 TTL 和 TTI 的功能都没有, 还要捐啥比特币, O(_)O
既然 net 下没有啥好的解决方案, 目光只能投到 java 下面看看, 很快就找到了 ehCache, 看下官方说明挺牛叉的, 介入方式还是和上一篇一样, 使用 thrift 做 C#
和 Java 之间的交互媒介就可以了 (thrift 的具体使用方法, 大概可以看上一篇) 如下图:
三: Ehcache 的配置
1. maven 的 ehcache 地址
- <!-- https://mvnrepository.com/artifact/org.ehcache/ehcache -->
- <dependency>
- <groupId>org.ehcache</groupId>
- <artifactId>ehcache</artifactId>
- <version>3.5.2</version>
- </dependency>
ehcache 的官方网址: http://www.ehcache.org/ , 大家可以简单了解下, 具体使用官方都有些 samples, 在 DBEngines 上的排名也还是非常不错的
2. 使用全代码模式的配置
接下来就可以写一段代码测试一下, 向 diskcache 中插入 10000 个字符大小的 cache, 插入 1000 次, 看看效率怎么样, 代码如下:
- public class App {
- public static void main(String[] args) throws CachePersistenceException {
- LocalPersistenceService persistenceService = new DefaultLocalPersistenceService(
- new DefaultPersistenceConfiguration(new File("C:\\1\\cache")));
- PersistentUserManagedCache<String, String> cache = UserManagedCacheBuilder
- .newUserManagedCacheBuilder(String.class, String.class)
- .with(new UserManagedPersistenceContext<String, String>("persistentCache", persistenceService))
- .withResourcePools(ResourcePoolsBuilder.newResourcePoolsBuilder().disk(10L, MemoryUnit.GB, true))
- .withExpiry(Expirations.timeToLiveExpiration(Duration.of(30, TimeUnit.MINUTES))).build(true);
- StringBuilder sBuilder = new StringBuilder();
- for (int i = 1; i < 10000; i++) {
- sBuilder.append(i);
- }
- long startTime = System.currentTimeMillis(); // 获取开始时间
- for (int i = 1; i < 1000; i++) {
- String key = "username" + i;
- String value = sBuilder.toString();
- cache.put(key, value);
- System.out.println(String.format("%s: 当前 key=%s 插入到缓存中", i, key));
- }
- long endTime = System.currentTimeMillis(); // 获取结束时间
- System.out.println("程序运行时间:" + (endTime - startTime) + "ms");
- }
- }
速度大概是 600 多毫秒, 时间还是可以接受的, 在我的项目中也是比较适合的
当然也可以采用 xml 的方式动态配置 ehcache, 或者采用 spring data 来集成这个 ehcache 都是可以的, 因为主要用 java 来打辅助, 就不具体深入介绍了,
好了, 本篇就说这么多吧, 希望对你有帮助
来源: https://www.cnblogs.com/huangxincheng/p/8655328.html