AWS Redis Cluster MOVED Error using redis node library - node.js

I have created a Redis MemoryDB cluster with 2 nodes in AWS:
I connect to it using redis node library v4.0.0 like this:
import { createCluster } from 'redis';
(async () => {
const REDIS_USERNAME = 'test-username';
const REDIS_PASSWORD = 'test-pass';
const cluster = createCluster({
rootNodes: [
{
url: `rediss://node1.amazonaws.com:6379`,
},
{
url: `rediss://node2.amazonaws.com:6379`,
},
],
defaults: {
url: `rediss://cluster.amazonaws.com:6379`,
username: REDIS_USERNAME,
password: REDIS_PASSWORD,
}
});
cluster.on('error', (err) => console.log('Redis Cluster Error', err));
await cluster.connect();
console.log('connected to cluster...');
await cluster.set('key', 'value');
const value = await cluster.get('key');
console.log('Value', value);
await cluster.disconnect();
})();
But sometimes I get the error ReplyError: MOVED 12539 rediss://node2.amazonaws.com:6379 and I cannot get the value from the key.
Do you have any idea if there is something wrong with the configuration of the cluster or with the code using redis node library?
Edit:
I tried it with ioredis library and it works, so it's something wrong with the redis library.
Node.js Version: 16
Redis Server Version: 6

I had created an issue to redis library, so it's going to be solved soon with this PR.

Related

Elasticsearch error "The client noticed that the server is not Elasticsearch and we do not support this unknown product"

I set up an elastic search instance in my local server using the OpenSearch docker image.
$ docker run -p 9200:9200 -p 9600:9600 -e "discovery.type=single-node" opensearchproject/opensearch:1.3.1
I can see the instance is up and running https://localhost:9200/
When trying to execute a simple search I am getting the following error.
ProductNotSupportedError: The client noticed that the server is not Elasticsearch and we do not support this unknown product.
I also tried the latest elastic search client but it's giving me a connection error.
error ConnectionError: unable to verify the first certificate
Code sample:
//const { Client } = require('#elastic/elasticsearch') // Got connection error when using latest version
const {Client: Client} = require('es7')
var connectionString = 'https://admin:admin#localhost:9200'
const client = new Client({
node: connectionString,
ssl: {
rejectUnauthorized: false
}
})
client.info()
.then(async response => {
console.log('success', response.statusCode);
const result = await client.search({
index: 'r7',
query: {
match: {
subtype: 'a'
}
}
})
console.log('result', result)
console.log('count', result.hits.hits)
})
.catch(error => {
console.error('error', error)
})
Your help is much appreciated.
Thank you.
You have an Elasticsearch client version that is more recent than 7.10.2, the version at which Opensearch was forked.
You should either downgrade the client library to match 7.10.2, or use the Opensearch Javascript client instead.

Redis connection in broken state: connection timeout exceeded. It might have been processed Nodejs + Async-redis

Am trying to connect to AWS redis elastic cache, but i keep getting this error all the time. I am not sure what i am doing wrong here, any help is greatly appreciated. Here's my code
async function testRedis(){
try{
const asyncRedis = require("async-redis");
const client = asyncRedis.createClient({
port: 6379,
host: 'myHost',
auth_pass: redisPassword,
connect_timeout: 900,
enable_offline_queue: false
})
const response = await client.set("test", "response");
const redisResp = await client.get("test");
const connStatus = client.quit()
console.log('connection status::', connStatus)
} catch (err) {
console.log(err)
}
}
I had the same issue. My host didn't an provide IP address for host option so I fixed it by using a connection string: [redis[s]:]//[[user][:password#]][host][:port][/db-number][?db=db-number[&password=bar[&option=value]]]
Should look something like:
const connectionString = 'rediss://username:password#url-to-your.redis.db.server.com:2500'
const client = asyncRedis.createClient(connectionString);
Async redis is a wrapper over Node Redis: https://www.npmjs.com/package/redis
Check out the docs for more info.

Failed to connect ElastiCache from NodeJS server on Elastic Beanstalk

We have a nodeJS server with express on AWS Elastic Beanstalk and we are trying to connect it with the Elasticache(Redis clustered) from the NodeJS but getting this error Redis Client Connection Error ClusterAllFailedError: Failed to refresh slots cache.. The error seems very common as a lot of people are facing the same bug. In order to connect to ElastiCache, we are using an npm module named ioredis.
A lot of people recommend using the same VPC and security group for both ElastiCache and Elastic Beanstalk. We are already using the same VPC and on Elastic Beanstalk we are using two security groups one of them matches the security group of ElastiCache. For the default VPC, we have enabled All Traffic for the inbound and outbound rules, but still, we are facing the same bug.
In order to connect to ElastiCache from NodeJS server I am using the following code:
const Redis = require("ioredis");
exports.connect = () => {
const client = new Redis.Cluster(
["xxxxx.xxxxx.clustercfg.use1.cache.amazonaws.com:6379"],
{
slotsRefreshTimeout: 10000,
dnsLookup: (address, callback) => callback(null, address),
redisOptions: {
showFriendlyErrorStack: true,
tls: {
checkServerIdentity: (/*host, cert*/) => {
// skip certificate hostname validation
return undefined;
},
},
},
}
);
client.on("ready", () => {
console.log("Redis Client Ready");
});
client.on("connect", () => {
console.log("Redis Client Connected");
});
client.on("error", (error) => {
console.log("Redis Client Connection Error", error);
});
client.on("reconnecting", () => {
console.log("Redis Client Reconnecting");
});
client.on("end", () => {
console.log("Redis Client Connection ended");
});
return client;
};
ElastiCache Configuration
Default VPC Security Group with Inbound and Outbound rules
Elastic Beanstalk security group(Same as default)
Error information from Elastic Beanstalk
Versions:
Node.js running on 64bit Amazon Linux with platform version 4.15.1
NodeJS version: 12.18.3
ioredis version: 4.17.3
npm version: 6.14.6
express version: 4.17.1
UPDATE: I am able to access the ElastiCache from ElasticBeanstalk if I do ssh and use redis-cli, but unable to access it using ioredis on NodeJS which is running on ElasticBeanstalk.
I have a similar setup and eventually got it working, a few key points:
Elasticbeanstalk and Elasticache have to be in the same VPC
Elasticache's security group should have an inbound rule to allow traffic from Elasticbeanstalk
Here's a code to connect:
import { RedisPubSub } from 'graphql-redis-subscriptions';
import Redis from 'ioredis';
import config from '../../config/env';
const options = {
// AWS host will look like this: somecache-dev-ro.k6sjdj.ng.0001.use1.cache.amazonaws.com
host: config.redis.host || 'localhost',
port: config.redis.port || 6379,
retryStrategy: (times: number): number => {
// reconnect after
return Math.min(times * 50, 2000);
},
};
export const pubsub = new RedisPubSub({
publisher: new Redis(options),
subscriber: new Redis(options),
});
I was debugging a similar issue. To access redis, I had to add tls: {} to the ioredis options:
{
host: process.env.REDIS_HOST,
port: process.env.REDIS_PORT,
password: process.env.REDIS_PASSWORD,
tls: {}
}
you can simply create connection
const Redis = require("ioredis");
const client = new Redis(
6379,
"Configiration Endpoint (xxx.xxxx.xxxcache.amazonaws.com)"
);
client.on("ready", () => {
console.log("Redis Client Ready");
client.send(
});
client.on("connect", () => {
console.log("Redis Client Connected");
});
client.on("error", (error) => {
console.log("Redis Client Connection Error", error);
});

Connection to postgresql db from node js

I'm tyring to make a connection from my nodejs script to my db connection, but seems like there is a suspicius issue i'm not able to figure out.
At the moment, this is my code:
const { Pool } = require('pg');
const pool = new Pool({
user: 'user',
host: '192.168.1.xxx',
database: 'database',
password: 'password',
port: 5432,
});
pool.on('error', (err, client) => {
console.error('Error:', err);
});
const query = `SELECT * FROM users`;
pool.connect()
.then((client) => {
client.query(query)
.then(res => {
for (let row of res.rows) {
console.log(row);
}
})
.catch(err => {
console.error(err);
});
})
.catch(err => {
console.error(err);
});
The issue seems to be in pool.connect(), but i can't understand what i'm missing because i got no errors in the log. I've installed pg module in the directory of my project with npm install --prefix pg and i know modules are loaded correctly.
I edited postgresql.conf:
# - Connection Settings -
listen_addresses = '*'
and pg_hba.conf
host database user 192.168.1.0/24 md5
to make the database reachable via lan and seems liek it works, because i'm able to connect successfully with apps like DBeaver...but i can't with NodeJS.
It's possible there is some kind of configuration i've to active?

Connection pooling in elasticsearch

How can we configure connection pooling for elasticsearch in node js? For handling instance failures and detecting dead nodes.
How can I customize Transport, ConnectionPool, Connections classes of elasticsearch in nodejs.
This feature is supported with the new RC1 client
Here an example:
'use strict'
// docker run -p 9200:9200 -p 9300:9300 --rm -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:6.7.0
const { Client } = require('#elastic/elasticsearch')
const client = new Client({
nodes: ['http://127.0.0.1:9200/'],
requestTimeout: 2000,
sniffInterval: 500,
sniffOnStart: true,
sniffOnConnectionFault: true
})
client.on('sniff', (err, req) => {
console.log('snif', err ? err.message : '', `${JSON.stringify(req.meta.sniff)}`)
})
setInterval(async () => {
try {
const info = await client.info()
console.log(info.body.name)
} catch (err) {
console.log(err.message);
}
}, 1500)
Note install the v6:
"#elastic/elasticsearch": "6.7.0-rc.1",

Resources