MSEARCH-49 Caching for language configs
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:
</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:
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:
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:
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
Load balancer should allow to pods communicate with each other using port 5071
apiVersion: v1 kind: Service metadata: name: mod-search spec: type: LoadBalancer selector: app: mod-search ports: - name: hazelcast port: 5701 - name: app port: 8081