Dynamic Topology refresh in Jedis - spring

I have a multi-master redis cluster configuration hosted in Kubernetes cluster. We connect to the redis via hostname of load balancer using Jedis Library. hostname is prod-redis-cluster.xyz.com. T When there is a patching to redis nodes, IP address of the load balancer does not change whereas the IP address of the actual Redis nodes behind the load balancer changes. However, application loses connectivity to the cluster and it re-establishes only when we restart the application.
We use JEDIS Client library. The sample code is present here.
Spring - Redis Cluster Configuration for Redis Hosted in K8s environment
Lettuce client of Jedis provides an option to refresh the topology dynamically at specific intervals. Please refer the below link.
https://lettuce.io/core/release/api/io/lettuce/core/cluster/ClusterTopologyRefreshOptions.html
redis:
cluster:
nodes:
lettuce:
cluster:
refresh:
adaptive: true
period: 5m
timeout: 150
and
`RefreshOptions R = ClusterTopologyRefreshOptions.builder()
.dynamicRefreshSources(false).enablePeriodicRefresh(true).build()
The above mentioned code helps in resolving the issue in Lettuce. How to achieve the same in Jedis?

Related

Questions about springboot redis (lettuce) health check

When using the Lettuce to connect redis cluster, if a slave node is unavailable, springboot health check will fails, but actually the read and write of the application are normal. Is this the design or a bug?
springboot: 2.3.12.RELEASE

Access to Redis Cluster via Single Endpoint

I have a application using Redis. This system implemented with java spring used jedis package for connection to the redis with the configuration as follow
jedis.pool.host=redisServer-IP
so the application connect to redis server on the redisServer-IP and works fine but, for the lack of memory on a single server and and HA capability I need to use a redis cluster I used docker compose to create a redis cluster using the here.
Also redis cluster working fine with three masters and three replicas.
I just need to understand, the Redis Cluster can work with the single endpoint, because I can only set single endpoint in the above jedis.pool.host configuration, or I need to have a proxy to deal with the redis cluster ?
NOTE: I can not make any changes in my application

Redis cache config setting from Springboot application

Currently we are exploring Redis as distributed in-mem cache which would be hosted on AWS via Amazon elasticache.
For Redis cluster connection from application, we are using Jedis client.
What are the cache property settings supported from client side?
org.springframework.data.redis.cache.RedisCacheConfiguration does not give much options other than TTL(time-to-live). IS there any other way to set more cache properties from client-side like enabling ssl, memory size etc.?

Google Kubernetes Engine Spring Boot App Cant Connect To Database Within Same Network

I have a spring boot app deployed to GKE in the us-central1 region. There is a postgres database that runs on a compute engine VM instance. Both are a part of the 'default' VPC network. I can ping this database by its hostname from within one of the GKE pods. However when the spring boot app launches and attempts connection to the database using the same hostname like so in the properties file, I get a connection timeout error and the app fails to startup:
spring.datasource.url=jdbc:postgresql://database01:5432/primary
We have similar connections to this database from other VM instances that work fine. There is aalso a similar setup with Kafka and the app is also unable to resolve the broker hostnames. What am I missing?
If your database is installed as external database on GKE, then you need to create "ExternalName" service
apiVersion: v1
kind: Service
metadata:
name: postgresql
spec:
type: ExternalName
externalName: usermgmtdb.csw6ylddqss8.us-east-1.rds.amazonaws.com
In this case, you need to know the "externalName" of your external PostgreSQL service, which is external dns name.
Otherwise, if you deploy PostgreSQL to your Kubernetes Cluster, you need to create PersistentVolumeClaim, StorageClass, PostgreSQL Deployment and PostgreSQL ClusterIP service.
See the manifest examples here: https://github.com/stacksimplify/aws-eks-kubernetes-masterclass/tree/master/04-EKS-Storage-with-EBS-ElasticBlockStore/04-03-UserManagement-MicroService-with-MySQLDB/kube-manifests

Spring boot application registers same instance, multipe times in consul cluster

I am trying to register a spring boot app to a consul cluster.
I have 3 node consul cluster 1 master 2 agents.
I have a load-balancer in front of 2 consul agents, so that it is HA.
In my application.yml. I ask the services to join via load-balancer
spring
cloud:
consul:
enabled: true
port: loadbalancer_port
host: http://loadbalancer
discovery:
instance-id: ${info.app.environment}:${spring.application.name}
tags:
- ${spring.profiles.active}
Now, when my service restarts it is creating a duplicate entry in consul.
I figured that, because it is being registered in 2 different agents.
Does this mean, I cant have HA consul with loadbalancer ? or should I ask the services to register to particular agents with out load-balancer?
Please help!!
Consul is designed to have a Consul client agent deployed on each server in your data center (see Consul Reference Architecture). Instead of registering services centrally, services running on a machine are registered with the local/co-located Consul agent. The agents then submit the list of services registered against them to the Consul servers, which then aggregates this info from each agent to form the service catalog. The catalog maintains the high-level view of the cluster, including which services are available, which nodes run those services, health information, etc.
TLDR; Remove the load balancer and register the services directly with the agents in order to avoid this issue where service registrations are duplicated across hosts.

Resources