在Kubernetes的pod之间分配缓存,在Spring启动应用中使用Hazelcast



我有一个启用Hibernate L2缓存的Spring启动应用程序。我将Hazelcast集成为Hibernate的缓存提供者。我的应用程序运行在Kubernetes上,部署在2个pod上。我验证了hibernate l2缓存成功地分布在一个集群内的两个pod之间。因此,如果一个实体在一个pod中放入缓存,我看到缓存大小在所有pod中均匀增加。

另外,我想使用Hazelcast与春@Cacheable但是这个缓存不是分布在两个pod之间,而是在每个实例中单独工作。因此,如果我在第一个pod中触发@Cacheable方法,并且它的结果被缓存,那么如果我尝试在第二个pod上执行相同的方法(它的结果必须已经在缓存中,在第一个pod上执行后),它将不会从缓存中获取它的结果。

我需要向配置中添加什么才能使其按预期工作?如有任何建议,我将不胜感激。谢谢。

部署。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: hazelcast-cluster-role
rules:
- apiGroups:
- ""
resources:
- endpoints
- pods
- nodes
- services
verbs:
- get
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: hazelcast-cluster-role-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: hazelcast-cluster-role
subjects:
- kind: ServiceAccount
name: default
namespace: default

配置Hazelcast - Hazelcast .yaml

hazelcast:
instance-name: my-instance
network:
join:
multicast:
enabled: false
kubernetes:
enabled: true
namespace: dev

应用程序属性
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.url=jdbc:postgresql://host.docker.internal/postgres
spring.datasource.username=postgres
spring.datasource.password=pass
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=com.hazelcast.hibernate.HazelcastCacheRegionFactory
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.show_sql=true
hibernate.cache.hazelcast.instance_name=my-instance

Service with @Cacheable

@Service
public class BookService {
@Autowired
private BookRepo bookRepo;
@Cacheable("books")
public Iterable<Book> getBooks() {
try {
Thread.sleep(15000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
System.out.println("Book service triggered");
return bookRepo.findAll();
}
}

如果我理解正确,要共享的数据不使用@Cacheable,这使得它更简单,下面的解决方案1。

解决方案1 -每个pod/JVM包含2个Hazelcast实例,其中一个是缓存管理器。

  • 第一个用于与其他pod共享数据,并使用Kubernetes发现,正如您已经拥有的。
  • 第二个连接为缓存管理器实现。如果这个第二个实例配置为禁用发现,它将不会找到其他实例来共享@Cacheable数据。
  • 确保第二个实例具有与第一个实例不同的集群名称和端口范围。

解决方案1 -每个pod/JVM包含2个Hazelcast实例,它们都是缓存管理器

  • 配置为解决方案1,第一个集群和第二个独立。
  • 使用@Cacheable(cacheManager = "first" ...)@Cacheable(cacheManager = "second" ...)来选择本地缓存和跨所有pod缓存的内容。

相同JVM中第二个独立实例的示例Hazelcast代码。

@Bean(name = "B")
public HazelcastInstance hazelcastInstanceB() {
Config config = new Config();
config.setClusterName(UUID.randomUUID().toString());
config.getNetworkConfig().setPort(6701);
config.getNetworkConfig().getJoin().getAutoDetectionConfig().setEnabled(false);
config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
return Hazelcast.newHazelcastInstance(config);
}
@Autowired
@Qualifier(value = "B")
private HazelcastInstance hazelcastInstanceB;

最新更新