Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NoHostAvailableError: All host(s) tried for query failed

I've installed Cassandra on one EC2 instance that contains one keyspace with SimpleStrategy and replcation factor 1.

I've also made port 9042 accessible from anywhere in the security group.

I have a Node.js application that contains the following code:

const cassandra = require('cassandra-driver');
const client = new cassandra.Client({ contactPoints: ['12.34.567.890:9042',], keyspace: 'ks1' });

const query = 'CREATE TABLE table.name ( field1 text, field2 text, field3 counter, PRIMARY KEY (field1, field2));';

client.execute(query)
    .then(result => console.log(result));

which produces the following error:

NoHostAvailableError: All host(s) tried for query failed. First host tried, 12.34.567.890:9042: DriverError: Connection timeout. See innerErrors.

I use cassandra-driver.

I've made sure Cassandra is running.

Edit:

As Aaron suggested, I have installed cqlsh on the client machine. When I go cqlsh 12.34.567.890 9042, it returns:

Connection error: ('Unable to connect to any servers', {'12.34.567.890': error(10061, "Tried connecting to [('12.34.567.890', 9042)]. Last error: No connection could be made because the target machine actively refused it")})

As Aaron suggeted, I have edited Cassandra.yaml on the server and replaced localhost with 12.34.567.890. I'm still getting the same error though.

like image 510
Alon Avatar asked Mar 05 '23 15:03

Alon


1 Answers

First of all, you don't need to specify the port. Try this:

const client = new cassandra.Client({ contactPoints: ['12.34.567.890'], keyspace: 'ks1' });

Secondly, where is your NodeJS app running from? Install and run cqlsh from there, just to make sure connection is possible. You can also use telnet to make sure you can connect to your node on 9042.

Also, you're going to want to enable authentication and authorization, and never use SimpleStrategy again. Enabling auth and building your keyspaces with NetworkTopologyStrategy are good habits to get into.

I just noticed that you said this:

instance that contains one keystore

Did you mean "keyspace" or are you using client-to-node SSL? If so, you're going to need to adjust your connection code to present a SSL certificate which matches the one in your node's keystore.

If you're still having problems, the next thing to do, would be to go about ensuring that you are connecting to the correct IP address. Grep your cassandra.yaml to see that:

$ grep "_address:" conf/cassandra.yaml
listen_address: 192.168.0.2
broadcast_address: 10.1.1.4
# listen_on_broadcast_address: false
rpc_address: 192.168.0.2
broadcast_rpc_address: 10.1.1.4

If they're configured, you'll want to use the "broadcast" address. These different addresses are typically useful for deployments where you have both an internal and external IP address.

$ grep "_address:" conf/cassandra.yaml
listen_address: localhost
# broadcast_address: 1.2.3.4
# listen_on_broadcast_address: false
rpc_address: localhost
# broadcast_rpc_address: 1.2.3.4

If you see output that looks like this, it means that Cassandra is listening on your local IP of 127.0.0.1. In which case, you wouldn't even need to specify it.

grep "_address:" cassandra.yaml returns exactly what you wrote in the second quote (with the localhost). Is it good or I need to change it?

You will need to change this. Otherwise, it will only accept connections on 127.0.0.1, which will not allow anything outside that node to connect to it.

Then what should I write there? I guess Cassandra is not supposed to be aware to the IP address of the machine that hosting it.

Actually, the main problem is that Cassandra is very aware of which IP it is on. Since you're trying to connect on 12.34.567.890 (which I know isn't a real IP), you should definitely use that.

You only need to specify broadcast addresses if each of your instances has both internal and external IP addresses. Typically the internal address gets specified as both rpc and listen, while the external becomes the broadcast addresses. But if your instance only has one IP, then you can leave the broadcast addresses commented-out.

like image 73
Aaron Avatar answered Mar 10 '23 21:03

Aaron