For distributed caching can be used Hazelcast In-memory caching. It is fast, reliable and scalable solution, that can be used for different clusters - AWS, Kubernetes and etc.
Required dependencies for mod-search project:
Code Block |
---|
</properties>
...
<hazelcast.version>4.2</hazelcast.version>
...
</properties>
</dependencies>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-all</artifactId>
<version>${hazelcast.version}</version>
</dependency>
</dependencies> |
Hazelcast cache can be configured using XML, YAML or using Java.
Spring configuration
Configuration class should looks like:
Code Block |
---|
package org.folio.search.configuration;
import com.hazelcast.config.ClasspathYamlConfig;
import com.hazelcast.config.Config;
import com.hazelcast.config.EvictionConfig;
import com.hazelcast.config.EvictionPolicy;
import com.hazelcast.config.InMemoryFormat;
import com.hazelcast.config.MapConfig;
import com.hazelcast.config.MaxSizePolicy;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@RequiredArgsConstructor
public class CacheProperties {
@Bean
public Config hazelcastConfig(@Value("${HAZELCAST_CONFIG_TYPE:multicast}") String configType) {
return new ClasspathYamlConfig(String.format("hazelcast-%s.yaml", configType))
.addMapConfig(new MapConfig("testHazelcastCache")
.setInMemoryFormat(InMemoryFormat.BINARY)
.setEvictionConfig(new EvictionConfig()
.setEvictionPolicy(EvictionPolicy.LRU)
.setMaxSizePolicy(MaxSizePolicy.PER_NODE)
.setSize(1000))
.setTimeToLiveSeconds(600));
}
} |
Common cache settings can be stored in Java configuration, environment specific can be defined using configuration properties in Java or as external YAML configurations in project:
Code Block | ||||
---|---|---|---|---|
| ||||
hazelcast:
instance-name: hazelcast-cache
network:
join:
multicast:
enabled: false
kubernetes:
enabled: true
service-name: mod-search
namespace: falcon |
Which is equal to Java configuration:
Code Block |
---|
config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
config.getNetworkConfig().getJoin().getKubernetesConfig().setEnabled(true)
.setProperty("namespace", "falcon")
.setProperty("service-name", "mod-search"); |
Kubernetes configuration
Using Kubernetes API requires granting certain permissions. To grant them for 'default' service account in 'default' namespace execute the following command.
https://raw.githubusercontent.com/hazelcast/hazelcast-kubernetes/master/rbac.yaml
Code Block | ||||
---|---|---|---|---|
| ||||
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 |
Load balancer should allow to pods communicate with each other using port 5071
Code Block |
---|
apiVersion: v1
kind: Service
metadata:
name: mod-search
spec:
type: LoadBalancer
selector:
app: mod-search
ports:
- name: hazelcast
port: 5701
- name: app
port: 8081 |