Jhipster Cache
Opened this issue · 0 comments
llccing commented
Background
参与 iCluster Web 项目一年的时间,80%时间在写前端Angular,20%时间在边学习边写Java,剩下10%也在思考和设计功能。
Jhipster 支持6种缓存
- Ehcache, https://www.cnblogs.com/bronya0/p/14715732.html
- 纯 Java 的进程内缓存,直接在 JVM虚拟机中缓存,速度非常快。缓存有两级,内存储存完自动存到磁盘上。数据可持久化到磁盘,VM(虚拟机)重启后数据恢复。
- 速度超过 Redis, Redis 通过 socket 访问缓存数据,效率没 Ehcache 高。
- 在分布式和集群情况下的缓存恢复、数据缓存的支持不是很好。
- 如果是大型缓存,存在缓存共享、分布式部署,建议用 Redis。
- 可以和 Redis 共同使用。
- Caffeine, https://ghh3809.github.io/2021/05/31/caffeine/
- Java 高性能的本地缓存库。缓存命中率已接近最优值。
- 支持并发,支持O(1)时间复杂度的数据存取。
- 提供以下功能
- 自动加载条目到缓存中,支持异步加载
- 根据频率和最近访问情况,支持将缓存数量设为移除策略
- 根据最近访问和修改时间,支持将时间设为移除策略
- 过期条目再次访问时异步加载
- key自动包装为弱引用
- value自动包装为弱引用/软引用
- 条目移除通知
- 对外部资源的写入
- 累计缓存使用统计
- Hazelcast, https://www.bianchengbaodian.com/hazelcast
- 分布式内存数据网格,用于存储键值对的分布式缓存、用于创建和使用分布式数据结构的构造,以及在集群中的节点之间分配计算和查询的方法。
- 支持多种数据结构,如锁、信号量、队列、列表等。
- 快速R/W访问
- 高可用性,支持跨机器分发数据以及额外的备份支持。
- 高性能,提供了可用于在多个工作机器之前分配负载/计算/查询的构造。
- 易于使用,hazelcast 实现并扩展了许多 java.util.concurrent 结构,使它非常容易使用和与代码集成。
- 与 Redis 相比
- 开始就是为分布式环境构建,而Redis开始作为单机缓存。
- Simple cluster scale in/out。维护添加或删除节点的集群非常简单。
- 支持故障转移所需的资源更少。Redis 主从节点,hazelcast所有节点平等。
- 简单分布式计算。hazelcast 提供了一个简单的接口来将代码发送到数据以进行并行处理,减少在线数据传输。Redis 也支持,但是需要需要 Lua 脚本。
- Infinispan, https://www.infoq.cn/article/infinispan-gridfs
- Infinispan, 是 JBoss Cache 缓存框架的后续项目,是一个开源的数据网格平台,用于访问分布式状态的集群节点。
- Memcached, https://www.cnblogs.com/davidesun/p/12770114.html
- 自由开源,高性能,分布式内存键值对缓存系统,用来存储小块的任意数据(字符串、对象),可以是数据库调用、API 调用或者是页面渲染的结果。
- 协议简单,使用文本协议,使用换行符作为命令结束
- 基于 libevent 的事件处理
- 内置内存存储方式
- 使用客户端哈希的不互相通信的方式。
- 和 Redis 比较如下,http://www.yunweipai.com/35551.html
- Redis, https://www.yiibai.com/redis/redis_quick_guide.html
- 开源,高级的键值存储解决方案
- Redis 将其数据库完全保存在内存中,仅使用磁盘进行持久化。
- Redis 提供相对丰富的数据类型
- Redis 可以将数据复制到任意数量的从机中。
- 优点
- 异常快。每秒可以执行11万次SET操作,每秒可以执行81000次的GET操作。
- 支持丰富的数据类型。列表,集合,排序集和散列等
- 操作具有原子性。所有操作都是原子操作,确保了两个客户端并发访问,Redis 服务器能够接收到新的值。
- 多实用工具。如缓存,消息队列(Redis本地支持发布/订阅);应用中任何短期数据,如会话,网页命中计数等。
- 竞品比较
- 包含更多复杂数据类型
- 内存数据库,实现非常高的读写速度。
- 复杂数据结构和内存中存储表示更容易操作。
- 开源,高级的键值存储解决方案
项目分析
-
[CacheConfiguration.java](http://CacheConfiguration.java) 定义类
-
Docker redis.yml 配置文件
-
实际使用的一个例子
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.io.Serializable;
@CacheConfig(cacheNames = {"replGroupsCaches"})
@Service
public class ReplGroupsCacheService implements Serializable {
private final static Logger logger = LoggerFactory.getLogger(ReplGroupsCacheService.class);
private static final long serialVersionUID = -2433804034194454964L;
public final static String REPLGROUPSCACHE = "replgroups";
// 这里的 #clusterId 是从参数取出来的值,
// 这样key/value就和cluster绑定在一起了,是个聪明的做法。
// 猜测这里使用 @Cacheable 注解后,response值会被自动缓存。
@Cacheable(cacheNames="replgroups", key="#clusterId")
public IcAgentService.GetReplicationGroupsResponse getCachedReplGroups(String clusterId, ICAgentServiceGrpc.ICAgentServiceBlockingStub agentStub) {
Empty request = Empty.newBuilder().build();
IcAgentService.GetReplicationGroupsResponse response;
try {
response = agentStub.getReplicationGroups(request);
} catch (StatusRuntimeException e) {
logger.error("getReplGroups RPC call failed: {}, {}", e.getStatus(), e.getMessage());
Status status = e.getStatus();
logger.debug("get groups gRPC failed: {}, {}", status.getCode(), status.getDescription());
throw new GetReplicationGroupsException(status.getDescription());
}
return response;
}
}
iCluster 中缓存使用的方式可能有些繁琐,暂时是这么觉得。待研究几个 Jhipster Redis best practise 后再回头看此结论是否能站住脚。
Summary
行文到此,初步发现项目中用的是 Redis,然后有一个 Groups 的使用例子。基于自己目前的认知,觉得使用方式还是不够简洁。后续在了解更多例子后,再看此结论是否能站住脚。