How to run a http server on EMR master node of a Spark application - apache-spark

I have a Spark streaming application (Spark 2.4.4) running on AWS EMR 5.28.0. In the driver application on master node, besides setting up the spark streaming job, I am also running a http server (Akka-http 10.1.6) which can query the driver application for data, I bind to port 6161 like the following:
val bindingFuture: Future[ServerBinding] = Http().bindAndHandle(myapiroutes, "127.0.0.1", 6161)
try {
bindingFuture.map { serverBinding =>
log.info(s"AlertRestApi bound to ${serverBinding.localAddress}")
}
} catch {
case ex: Exception => {
log.error(s"Failed to bind to 127.0.0:6161")
system.terminate()
}
}
then I start spark streaming:
ssc.start()
When I test this on local spark, I am able to access http://localhost:6161/myapp/v1/data and get data from spark streaming, everything is good so far.
However, when I run this application in AWS EMR, I could not access port 6161. I ssh into the driver node and try to curl my url, it gives me error message:
[hadoop#ip-xxx-xx-xx-x ~]$ curl http://xxx.xx.xx.x:6161/myapp/v1/data
curl: (7) Failed to connect to xxx.xx.xx.x port 6161: Connection refused
when I look into the log in the driver node, I do see the port is bound (why the host shows 0:0:0:0:0:0:0:0? I don't know, that is the way in my dev testing, and it works, I see the same log and able to access the url):
20/04/13 16:53:26 INFO MyApp: MyRestApi bound to /0:0:0:0:0:0:0:0:6161
So my question is, what should I do so that I can access the api at port 6161 on the driver node? I realize Yarn resource manager may be involved but I know nothing about Yarn resource manager to point myself where to investigate.
Please help. Thanks

You are mentioning 127.0.0.1 as the host name or 0.0.0.0??
127.0.0.1 will work in your local system but not in AWS as it is loopback address. In such case you need to use 0.0.0.0 as the host name
Also make sure that ports are open and access is provided from your IP. To do that, go to Inbound rules for your instance and add 6161 under custom TCP rule if not done already.
Let me know if this makes any difference

Related

Spring Boot app can't connect to Cassandra cluster, driver returning "AllNodesFailedException: Could not reach any contact point"

i've updated my spring-boot to v3.0.0 and spring-data-cassandra to v4.0.0 which resulted in unable to connect to cassandra cluster which is deployed in stg env and runs on IPv6 address having different datacenter rather DC1
i've added a config file which accepts localDC programatically
`#Bean(destroyMethod = "close")
public CqlSession session() {
CqlSession session = CqlSession.builder()
.addContactPoint(InetSocketAddress.createUnresolved("[240b:c0e0:1xx:xxx8:xxxx:x:x:x]", port))
.withConfigLoader(
DriverConfigLoader.programmaticBuilder()
.withString(DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER, localDatacenter)
.withString(DefaultDriverOption.AUTH_PROVIDER_PASSWORD,password)
.withString(DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT,"10s")
.withString(DefaultDriverOption.CONNECTION_CONNECT_TIMEOUT, "20s")
.withString(DefaultDriverOption.REQUEST_TIMEOUT, "20s")
.withString(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT, "20s")
.withString(DefaultDriverOption.SESSION_KEYSPACE,keyspace)
.build())
//.addContactPoint(InetSocketAddress.createUnresolved(InetAddress.getByName(contactPoints).getHostName(), port))
.build();
}
return session;`
and this is my application.yml file
spring:
data:
cassandra:
keyspace-name: xxx
contact-points: [xxxx:xxxx:xxxx:xxx:xxx:xxx]
port: xxx
local-datacenter: xxxx
use-dc-aware: true
username: xxxxx
password: xxxxx
ssl: true
SchemaAction: CREATE_IF_NOT_EXISTS
So locally I was able to connect to cassandra (by default it is pointing to localhost) , but in stg env my appplication is not able to connect to that cluster
logs in my stg env
caused by: com.datastax.oss.driver.api.core.AllNodesFailedException: Could not reach any contact point, make sure you've provided valid addresses (showing first 1 nodes, use getAllErrors() for more): Node (endPoint=/[240b:cOe0:102:xxxx:xxxx:x:x:x]:3xxx,hostId-null,hashCode=4e9ba6a8):[com.datastax.oss.driver.api.core.connection.ConnectionInitException:[s0|controllid:0x984419ed,L:/[240b:cOe0:102:5dd7: xxxx:x:x:xxx]:4xxx - R:/[240b:c0e0:102:xxxx:xxxx:x:x:x]:3xxx] Protocol initialization request, step 1 (OPTIONS: unexpected tarlure com.datastax.oss.driver.apt.core.connection.closedconnectiontxception: Lost connection to remote peer)]
Network
You appear to have a networking issue. The driver can't connect to any of the nodes because they are unreachable from a network perspective as it states in the error message:
... AllNodesFailedException: Could not reach any contact point ...
You need to check that:
you have configured the correct IP addresses,
you have configured the correct CQL port, and
there is network connectivity between your app and the cluster.
Security
I also noted that you configured the driver to use SSL:
ssl: true
but I don't see anywhere where you've configured the certificate credentials and this could explain why the driver can't initiate connections.
Check that the cluster has client-to-node encryption enabled. If it does then you need to prepare the client certificates and configure SSL on the driver.
Driver build
This post appears to be a duplicate of another question you posted but is now closed due to lack of clarity and details.
In that question it appears you are running a version of the Java driver not produced by DataStax as pointed out by #absurdface:
Specifically I note that java-driver-core-4.11.4-yb-1-RC1.jar isn't a Java driver artifact released by DataStax (there isn't even a 4.11.4 Java driver release). This could be relevant for reasons we'll get into ...
We are not aware of where this build came from and without knowing much about it, it could be the reason you are not able to connect to the cluster.
We recommend that you switch to one of the supported builds of the Java driver. Cheers!
A hearty +1 to everything #erick-ramirez mentioned above. I would also expand on his answers with an observation or two.
Normally spring-data-cassandra is used to automatically configure a CqlSession and make it available for injection (or for use in CqlTemplate etc.). That's what you'd normally be configuring with your application.yml file. But you're apparently creating the CqlSession directly in code, which means that spring-data-cassandra isn't involved... and therefore what's in your application.yml likely isn't being used.
This analysis strongly suggests that your CqlSession is not being configured to use SSL. My understanding is that your testing sequence went as follows:
Tested app locally on a local server, everything worked
Tested app against test environment, observed the errors above
If this sequence is correct and you have SSL enabled in you test environment but not on your local Cassandra instance that could very easily explain the behaviour you're describing.
This explanation could also explain the specific error you cite in the error message. "Lost connection to remote peer" indicates that something is unexpectedly killing your socket connection before any protocol messages are explained... and an SSL issue would cause almost exactly that behaviour.
I would recommend checking the SSL configuration for both servers involved in your testing. I would also suggest consulting the SSL-related documentation referenced by Erick above and confirm that you have all the relevant materials when building your CqlSession.
added the certificate in my spring application
public CqlSession session() throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
Resource resource = new ClassPathResource("root.crt");
InputStream inputStream = resource.getInputStream();
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate cert = cf.generateCertificate(inputStream);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
keyStore.setCertificateEntry("ca", cert);
trustManagerFactory.init(keyStore);
SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
return CqlSession.builder()
.withSslContext(sslContext)
.addContactPoint(new InetSocketAddress(contactPoints,port))
.withAuthCredentials(username, password)
.withLocalDatacenter(localDatacenter)
.withKeyspace(keyspace)
.build();
}
so added the cert file in the configuration file of the cqlsession builder and this helped me in connecting to the remote cassandra cluster

How to connect to Cassandra Database using Python code

I had followed the steps given in https://docs.datastax.com/en/developer/python-driver/3.25/getting_started/ to connect to cassandra database using python code, but still after running the code snippet I am getting
NoHostAvailable: ('Unable to connect to any servers', {'hosts"port': OperationTimedOut('errors=None, last_host=None'),
Python version 2.7 and 3 (classpath is set for both the python versions)
Java 1.8 (class path has been set)
Apache cassandra 3.11.6 (apache home classpath has been set)
I tend to use a very simple app to test connectivity to a Cassandra cluster:
from cassandra.cluster import Cluster
cluster = Cluster(['10.1.2.3'], port=45678)
session = cluster.connect()
row = session.execute("SELECT release_version FROM system.local").one()
if row:
print(row[0])
Then run it:
$ python HelloCassandra.py
4.0.6
In your comment you mentioned that you're getting OperationTimedOut which indicates that the driver never got a response back from the node within the client timeout period. This usually means (a) you're connecting to the wrong IP, (b) you're connecting to the wrong CQL port, or (c) there's a network connectivity issue between your app and the cluster.
Make sure that you're using the IP address that you've set in rpc_address of cassandra.yaml. Also make sure that the node is listening for CQL clients on the right port. You can easily verify this by checking the output of either of these Linux utilities like netstat or lsof, for example:
$ sudo lsof -nPi -sTCP:LISTEN
Cheers!
So that error message suggests that the host/port combination either does not have Cassandra running on it or is under heavy load and unable to respond.
Can you edit your question to include the Cassandra connection portion of your code, as well as maybe how you're calling it? I have a test script which I use (and you're welcome to check it out), and here is the connection portion:
protocol=4
hostname=sys.argv[1]
username=sys.argv[2]
password=sys.argv[3]
nodes = []
nodes.append(hostname)
auth_provider = PlainTextAuthProvider(username=username, password=password)
cluster = Cluster(nodes,auth_provider=auth_provider, protocol_version=protocol)
session = cluster.connect()
I call it like this:
$ python3 testCassandra.py 127.0.0.1 aaron notReallyMyPassword
local
One thing you might try too, would be to run a nodetool status on the cluster just to make sure it's running ok.
Edit
local variable 'session' referenced before assignment
So this sounds to me like you're attempting a session.execute before session = cluster.connect(). Have a look at my Git repo (linked above) to see the correct order for instantiating session.
I am not using default port
In that case, make sure the port is being set in the cluster definition. Ex:
port = 19099
cluster = Cluster(nodes,auth_provider=auth_provider, port=port)

Force selenium-webdriver to bind to localhost

When using selenium-webdriver, something attempts to bind to a port, listening for connections from the unspecified IPv6/IPv4 host (:: / 0.0.0.0). This triggers a firewall message.
I'd like to avoid this firewall message by forcing whatever this is to bind only to localhost, but I can't find any clues about what this server is or how to configure it.
Example code which replicates the issue:
const webdriver = require('selenium-webdriver');
const driver = new webdriver.Builder().forBrowser('chrome').build();
setTimeout(() => {
driver.quit();
}, 10000);
On macOS, this shows the prompt:
Do you want the application “node” to accept incoming network connections?
Obviously choosing "deny" still allows the tests to run (since everything is local anyway), and after selecting this option the OS remembers the choice until Node is updated, but I'd like to lock-down the test so that this isn't an issue.
What is causing this? How can I configure it?
You can use Selenium Standalone Server and bind it to a specific IP address. Additionally you can disable IPv6 addresses lookup.
Launch Selenium Standalone Server like:
java -Djava.net.preferIPv4Stack=true -jar selenium-server-standalone-x.xx.x.jar -host 10.20.30.40
Amend your webdriver initialization code to explicitly set the Selenium Server address like:
const driver = new webdriver.Builder().forBrowser('chrome').usingServer('http://10.20.30.40:4444/wd/hub').build();
replace this 10.20.30.40 with the IP address of your choice (the IP address or alias must exist on the system where you run the test)
References:
Selenium with JavaScript - The Standalone Selenium Server
Connecting Selenium Hubs to Cloud Server

'The requested address is not valid in its context' while trying to connect to ArangoDB server on LAN

I have two machines on LAN, I'd like to connect to AranoDB serve on one of them from another one.
The first one has an address 192.168.0.105, arangod.conf
[server]
endpoint = tcp://0.0.0.0:8529
storage-engine = auto
another one has an address 192.168.0.100 and arangod.conf
[server]
endpoint = tcp://192.168.0.105:8529
storage-engine = auto
ArangoDB on the first machine is working. When I try to start ArangoDB on the second machine, I see the following error:
2018-08-21T09:46:15Z [2724] INFO {authentication} Jwt secret not specified, generating...
2018-08-21T09:46:15Z [2724] INFO ArangoDB 3.3.12 [win64] 64bit, using build tags/v3.3.12-0-g225095d762, VPack 0.1.30, RocksDB 5.6.0, ICU 58.1, V8 5.7.492.77, OpenSSL 1.0.2a 19 Mar 2015
2018-08-21T09:46:15Z [2724] INFO using storage engine mmfiles
2018-08-21T09:46:15Z [2724] INFO {cluster} Starting up with role SINGLE
2018-08-21T09:46:15Z [2724] INFO {authentication} Authentication is turned on (system only)
2018-08-21T09:46:18Z [2724] INFO using endpoint 'http+tcp://192.168.0.105:8529' for non-encrypted requests
2018-08-21T09:46:18Z [2724] ERROR {communication} unable to bind to endpoint 'http+tcp://192.168.0.105:8529': The requested address is not valid in its context
2018-08-21T09:46:18Z [2724] WARNING {communication} failed to open endpoint 'http+tcp://192.168.0.105:8529' with error: The requested address is not valid in its context
2018-08-21T09:46:18Z [2724] FATAL failed to bind to endpoint 'http+tcp://192.168.0.105:8529'. Please check whether another instance is already running using this endpoint and review your endpoints configuration.
I've already created rules in the windows firewall and in the router.
Test-NetConnection results are:
PS C:\Users\> Test-NetConnection -ComputerName 192.168.0.105 -Port 8529
ComputerName : 192.168.0.105
RemoteAddress : 192.168.0.105
RemotePort : 8529
SourceAddress : 192.168.0.100
TcpTestSucceeded : True
What else should I do?
Not sure what you try here... connect with one server to another server? This is bound to fail. Don't you want to run a server on one machine and connect to it from another computer on the local network using arangosh? Or simply use the web interface?
The endpoint must be an address used by a network interface of your local computer. It can't be the address of another machine.
Setups like clusters require a lot more configuration (if done bare-metal).
For an overview of deployment modes including multi-machine setups you may want to check the work-in-progress documentation: https://docs.arangodb.com/devel/Manual/Deployment/

prestodb| worker not found & v1/collector/general is not returning any values

Hi I have configured prestodb with one coordinator and one worker.
when I run the worker I do get the message like
Discovery server connect succeeded for refresh (presto/general)
Discovery server connect succeeded for refresh (collector/general)
io.airlift.discovery.client.Announcer Discovery server connect succeeded for announce
however when I run a query it says worker not available.
also when I try to see if the below urls works
http://<master>/v1/service/presto/general - works ( i can see both nodes)
However when i use
http://<master>//v1/service/collector/general - doesn't work below is the result
{"environment":"dev","services":[]}
Server config.properties
coordinator=true
node-scheduler.include-coordinator=false
http-server.http.port=8000
query.max-memory=50GB
query.max-memory-per-node=3GB
discovery-server.enabled=true
discovery.uri=http://gdcrtdev01.[domain]:8000
Worker config.properties
coordinator=false
http-server.http.port=8000
query.max-memory=50GB
query.max-memory-per-node=1GB
discovery.uri=http://gdcrtdev01.[domain]:8000

Resources