Connection issue with AWS Redis cluster from Spring Boot App - amazon-elasticache

I am trying to integrate AWS elasticache redis with spring boot application using spring-data-redis. Getting below exception when using a service.
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:191)
... 84 more
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused
at redis.clients.jedis.Connection.connect(Connection.java:164)
Using below code
#Bean
public RedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig) {
JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory(jedisPoolConfig);
redisConnectionFactory.setHostName("AWS primary replication group endpoint");
redisConnectionFactory.setPort(6379);
redisConnectionFactory.setUsePool(true);
redisConnectionFactory.setTimeout(3600);
return redisConnectionFactory;
}
I am able to connect to AWS Redis from my EC2 instance where the service is deployed. Any sample code or steps would be really helpful.

Might be late to this party but it was my experience that declaring spring.redis.host in application.yml, application.properties or at the command-line as a -D argument were not respected by RedisProperties within RedisAutoConfiguration.
What ultimately worked for me was exporting an environment variable, like so
export SPRING_REDIS_HOST=...
before starting up a service that attempts to connect to ElastiCache.

Related

Using AWS Elasticache Redis to manage sessions in Sails.js

I'm currently using connect-redis in my Sails.js project to leverage a locally-installed redis instance. In the future, I'd like to use a common redis instance for multiple server instances (behind a load balancer), so I've been looking at AWS Elasticache. I'm having trouble with the configuration, though.
sails-project\config\session.js:
adapter: 'connect-redis',
host: 'primary-endpoint.xxxxxx.ng.0001.apse1.cache.amazonaws.com',
port: 6379,
ttl: <redis session TTL in seconds>,
db: 0,
pass: <redis auth password>,
prefix: 'sess:',
What should the TTL value be? Should the pass attribute point to IAM somehow?
I tried creating a user in IAM with AmazonElastiCacheFullAccess permissions and putting its access key ID in the pass attribute, but I got this error in my server console (testing on my Windows box):
C:\repos\sails-project\node_modules\connect-redis\lib\connect-redis.js:83
throw err;
^
AbortError: Redis connection lost and command aborted. It might have been processed.
at RedisClient.flush_and_error (C:\repos\sails-project\node_modules\redis\index.js:362:23)
...
Any ideas on what to change?
I'm going to assume your "windows box" is outside of AWS.
For Elasticache you can't access it from outside AWS. See the Security Section here : https://aws.amazon.com/elasticache/faqs/#Can_I_access_Amazon_ElastiCache_from_outside_AWS
The most common use case is to have EC2 instances within a VPC access and consume the Elasticache service. Along with this the Elasticache Redis service doesn't employ authentication and only allows lock down via security groups.
If you need something that differentiates from this configuration then you should look at putting Redis on EC2 so that you have full control.

Stack Exchange Connecting to Redis Cluster Connection error

I am trying to connect our asp.net application through Stack exchange client to Redis Cluster, but I am getting an connection error shown below :
No connection is available to service this operation:
I am using the connection string :
< add key="SearchCacheRedisConnectionString" value="IP:6379,IP:6379,connectTimeout=1000,abortConnect=false,ConnectRetry=3,syncTimeout=500,keepAlive=180" />
I have used the same connection string to connect to a standalone redis instance and everything works perfectly.
Its only when i try to connect to a cluster ( 3 master 3 slave ) architecture that i am getting a connection error.
Is there a different connection string i am supposed to use to connect to a Redis Cluster or is there any specific changes i am supposed to make in my code to connect to a Cluster.
Any help will be much appreciated. Thank you
Could your connectTimeout be too low? The StackExchange.Redis default is 5000

Connect to Redis (AWS) from Elastic Beanstalk instance

What is the method to connect to Redis node in an Elasticache from an Elastic BeanStalk instance?
Would just the host-name (redis node endpoint) and port enough?
Or is there any other authentication I have to complete? I get this error when I try to connect to the node.
org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
For our rails application we have in our configuration environment variables:
REDIS_URL=redis://ourname.use1.cache.amazonaws.com:6379
REDIS_PROVIDER=REDIS_URL
and it works fine. Not sure specifically for your application, but this should resolve that.
Also, make sure that your redis node has the appropriate security group permissions. For example, if it is in sg-a and your Beanstalk nodes are in sg-b, make sure that sg-a has a tcp rule for 6379 for sg-b

How to configure ElastiCache Redis for Spring Data Access

I am trying to setup ElastiCache to use with a Java Application. I have based my setup based on this documentation:
https://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/BestPractices.html
The EC2 instance where the Java (8) App runs is in a VPC.
I have tried an ElastiCache instance both in VPC and no VPC. However, I always got,
redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused
If I install Redis myself on an EC2 instance and connect to it, the app is able to connect to the Redis Cache!
I have setup proper authorization with Security-group from EC2 to Cache-Security but no luck. I just can't make the 'connection'. Any sample connection snippet would be really helpful.
Redis is setup this way in the APP Config:
#Bean
public JedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory();
redisConnectionFactory.setHostName(<cache-node>);
redisConnectionFactory.setPort(6397);
redisConnectionFactory.setUsePool(true);
redisConnectionFactory.setTimeout(3600);
return redisConnectionFactory;
}
The various versions:
Jedis- 2.6.2, Spring- 4.1.6, Spring-data-> 1.5.0
telnet redis-ip 6397
Determine if redis can be connected
redisConnectionFactory.setPort(6397);
should probably be
redisConnectionFactory.setPort(6379); //default redis port

Can I let spring-session used a standalone redis?

I have built up a redis server, I want to know whether I can make spring-session use the existed redis server instead of embed its redis-server?
Yes Spring Session can and should use an existing Redis Server. This is the primary way to deploy to production. I have provided a few examples below:
Spring Boot
Taking the Spring Boot Sample and converting it to use an external Redis Server can be done by:
Removing the #EmbeddedRedisServer annotation
Configuring the Redis Server Location For example, you might provide the following properties in your application.properties:
spring.redis.host=example.com
spring.redis.password=secret
spring.redis.port=6379
Other Samples
The other samples are quite similar to use an external Redis instance. For example, to change the httpsession sample to use an external Redis:
Remove #EnableEmbeddedRedis
Update your RedisConnectionFactory Bean definition to point to your Redis server
For example:
#Bean
public JedisConnectionFactory connectionFactory() {
JedisConnectionFactory connection = new JedisConnectionFactory();
connection.setPort(6379);
connection.setHostName("example.com");
connection.setPassword("secret");
return connection;
}