Java 缓存请求元素集
Java cache Set of requested elements
我遇到了以下问题,想听听大家的意见和建议。
我有第三方 API 具有以下查询参数:
假设有 10000 个 storeId,调用 API 将导致 10k 次调用
?storeId=1&status=active
我有自己的服务,它使用从我自己的端点请求的 N 个 storeId 调用这个 API。假设我调用我的服务,例如 100 家商店
http://localhost:8080?storeIds=[1,2,3,4,5...] up to 100
此调用也可能是来自筛选商店的请求:
http://localhost:8080?storeIds=[78,99,104,320,123...] up to N
List<Store> stores = new ArrayList<>(storeIds.size());
storeIds.forEach(storeId -> {
Store store = thirdPartyService.call(storeId);
stores.add(store);
});
Making a parallel call would cause the third party system to collapse since it can not support that many requests x second.
I can not change the third party endpoint to accept N storeIds
为了解决这个问题,我仍然实现了缓存,因为我将每个存储 1 个存储在我的缓存中,这也会导致性能问题,因为如果您必须调用缓存 10.000 次。
由于我从端点收到的 storeId 列表并不总是相同的,它可能包含一些在缓存中的 storeId,而另一些则不在缓存中,我无法从缓存中检索所有内容,因此我必须制作向第三方求助 api.
我想知道是否有另一种观点可以解决这个问题,因为将一组 storeId 存储为缓存并不能解决这个问题,例如:
第一次调用:storeIds:[1,2,3,4,5,732,2321](我们这里有更多,但我简化了这个)storedSet on cache
第二次调用:[1,2,3,99,102,232,732](我们还有很多)
在第二次调用中,有些元素在缓存中,有些不在缓存中,甚至有些元素没有被请求。先前存储在缓存中的 Set 包含其中一些的数据,但也包含一些我不需要的数据,这就是为什么我将数据存储为缓存中的 1 个 storeId = 1 个条目。
非常感谢!
很多缓存实现都提供了所谓的批量获取方法:Cache.getAll
。那就是做你想要的把戏。这是基于 cache2k 的解决方案草图。缓存设置为:
Cache<Integer, Store> cache =
new Cache2kBuilder<Integer, Store>() {}
.loader(id -> {
// http call to get Store data for given id
return new Store();
})
.loaderThreadCount(4) // numbers of parallel loads
.build();
然后您可以像这样检索数据:
// request some data, everything will be retrieved via the loader
Map<Integer, Store> result = cache.getAll(Arrays.asList(1, 2, 3, 4, 5, 6, 7));
// ids 4 and 5 will be taken from the cache, the others are loaded
Map<Integer, Store> result2 = cache.getAll(Arrays.asList(4, 5,10, 12, 17));
这将向您的数据源发出最多 4 个并行加载请求。异步变体也可用。
该解决方案类似于其他缓存,如 Caffeine、EHCache 或任何 JCache 兼容缓存。
我遇到了以下问题,想听听大家的意见和建议。
我有第三方 API 具有以下查询参数: 假设有 10000 个 storeId,调用 API 将导致 10k 次调用
?storeId=1&status=active
我有自己的服务,它使用从我自己的端点请求的 N 个 storeId 调用这个 API。假设我调用我的服务,例如 100 家商店
http://localhost:8080?storeIds=[1,2,3,4,5...] up to 100
此调用也可能是来自筛选商店的请求:
http://localhost:8080?storeIds=[78,99,104,320,123...] up to N
List<Store> stores = new ArrayList<>(storeIds.size());
storeIds.forEach(storeId -> {
Store store = thirdPartyService.call(storeId);
stores.add(store);
});
Making a parallel call would cause the third party system to collapse since it can not support that many requests x second.
I can not change the third party endpoint to accept N storeIds
为了解决这个问题,我仍然实现了缓存,因为我将每个存储 1 个存储在我的缓存中,这也会导致性能问题,因为如果您必须调用缓存 10.000 次。
由于我从端点收到的 storeId 列表并不总是相同的,它可能包含一些在缓存中的 storeId,而另一些则不在缓存中,我无法从缓存中检索所有内容,因此我必须制作向第三方求助 api.
我想知道是否有另一种观点可以解决这个问题,因为将一组 storeId 存储为缓存并不能解决这个问题,例如:
第一次调用:storeIds:[1,2,3,4,5,732,2321](我们这里有更多,但我简化了这个)storedSet on cache 第二次调用:[1,2,3,99,102,232,732](我们还有很多)
在第二次调用中,有些元素在缓存中,有些不在缓存中,甚至有些元素没有被请求。先前存储在缓存中的 Set 包含其中一些的数据,但也包含一些我不需要的数据,这就是为什么我将数据存储为缓存中的 1 个 storeId = 1 个条目。
非常感谢!
很多缓存实现都提供了所谓的批量获取方法:Cache.getAll
。那就是做你想要的把戏。这是基于 cache2k 的解决方案草图。缓存设置为:
Cache<Integer, Store> cache =
new Cache2kBuilder<Integer, Store>() {}
.loader(id -> {
// http call to get Store data for given id
return new Store();
})
.loaderThreadCount(4) // numbers of parallel loads
.build();
然后您可以像这样检索数据:
// request some data, everything will be retrieved via the loader
Map<Integer, Store> result = cache.getAll(Arrays.asList(1, 2, 3, 4, 5, 6, 7));
// ids 4 and 5 will be taken from the cache, the others are loaded
Map<Integer, Store> result2 = cache.getAll(Arrays.asList(4, 5,10, 12, 17));
这将向您的数据源发出最多 4 个并行加载请求。异步变体也可用。
该解决方案类似于其他缓存,如 Caffeine、EHCache 或任何 JCache 兼容缓存。