Skip to content

Commit

Permalink
[Java] Simplify Java worker configuration (ray-project#2938)
Browse files Browse the repository at this point in the history
## What do these changes do?
Previously, Java worker configuration is complicated, because it requires setting environment variables as well as command-line arguments.

This PR aims to simplify Java worker's configuration. 
1) Configuration management is now migrated to [lightbend config](https://github.com/lightbend/config), thus doesn't require setting environment variables.
2) Many unused config items are removed.
3) Provide a simple `example.conf` file, so users can get started quickly.
4) All possible options and their default values are declared and documented in `ray.default.conf` file.

This PR also simplifies and refines the following code:
1) The process of `Ray.init()`.
2) `RunManager`.
3) `WorkerContext`. 

### How to use this configuration?
1. Copy `example.conf` into your classpath and rename it to `ray.conf`.
2. Modify/add your configuration items. The all items are declared in `ray.default.conf`.
3. You can also set the items in java system prosperities.

Note: configuration is read in this priority:
System properties > `ray.conf` > `ray.default.conf`

## Related issue number
N/A
  • Loading branch information
jovany-wang authored and raulchen committed Sep 26, 2018
1 parent 0e552fb commit 8e8e123
Show file tree
Hide file tree
Showing 45 changed files with 845 additions and 1,872 deletions.
21 changes: 9 additions & 12 deletions java/README.rst
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
This directory contains the java worker, with the following components.

- java/api: Ray API definition
- java/common: utilities
- java/runtime-common: common implementation of the runtime in worker
- java/runtime-dev: a pure-java mock implementation of the runtime for
fast development
- java/runtime-native: a native implementation of the runtime
- java/test: various tests
- src/local\_scheduler/lib/java: JNI client library for local scheduler
- src/plasma/lib/java: JNI client library for plasma storage

Quick start
===========

Configuration
-------------
Ray will read your configurations in the following order:

* Java system properties: e.g., ``-Dray.home=/path/to/ray``.
* A ``ray.conf`` file in the classpath: `example <https://github.com/ray-project/ray/java/example.conf>`_.

For all available config items and default values, see `this file <https://github.com/ray-project/ray/java/runtime/src/main/resources/ray.default.conf>`_.

Starting Ray
------------

Expand Down
7 changes: 7 additions & 0 deletions java/api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,11 @@
<description>java api for ray</description>

<packaging>jar</packaging>

<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
</dependencies>
</project>
10 changes: 8 additions & 2 deletions java/api/src/main/java/org/ray/api/Ray.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import java.util.List;
import org.ray.api.id.UniqueId;
import org.ray.api.runtime.DefaultRayRuntimeFactory;
import org.ray.api.runtime.RayRuntime;
import org.ray.api.runtime.RayRuntimeFactory;

Expand All @@ -17,7 +16,14 @@ public final class Ray extends RayCall {
* Initialize Ray runtime with the default runtime implementation.
*/
public static void init() {
init(new DefaultRayRuntimeFactory());
try {
Class clz = Class.forName("org.ray.runtime.DefaultRayRuntimeFactory");
RayRuntimeFactory factory = (RayRuntimeFactory) clz.newInstance();
init(factory);
} catch (Exception e) {
throw new RuntimeException("Failed to initialize Ray runtime.", e);
}

}

/**
Expand Down

This file was deleted.

6 changes: 0 additions & 6 deletions java/cli/src/main/java/org/ray/cli/CommandStart.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,4 @@ public class CommandStart {
@Parameter(names = "--head", description = "start the head node")
public boolean head;

@Parameter(names = "--config", description = "the config file of ray")
public String config = "";

@Parameter(names = "--overwrite", description = "the overwrite items of config")
public String overwrite = "";

}
27 changes: 0 additions & 27 deletions java/cli/src/main/java/org/ray/cli/CommandSubmit.java

This file was deleted.

188 changes: 30 additions & 158 deletions java/cli/src/main/java/org/ray/cli/RayCli.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,200 +2,80 @@

import com.beust.jcommander.JCommander;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.ray.api.id.UniqueId;
import org.ray.runtime.config.PathConfig;
import org.ray.runtime.config.RayParameters;
import org.ray.runtime.config.RunMode;
import org.ray.runtime.gcs.KeyValueStoreLink;
import org.ray.runtime.gcs.RedisClient;
import org.ray.runtime.gcs.StateStoreProxy;
import org.ray.runtime.gcs.StateStoreProxyImpl;
import org.ray.runtime.config.RayConfig;
import org.ray.runtime.runner.RunManager;
import org.ray.runtime.runner.worker.DefaultDriver;
import org.ray.runtime.util.config.ConfigReader;
import org.ray.runtime.util.logger.RayLog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
* Ray command line interface.
*/
public class RayCli {

private static RayCliArgs rayArgs = new RayCliArgs();
private static final Logger LOGGER = LoggerFactory.getLogger(RayCli.class);

private static RunManager startRayHead(RayParameters params, PathConfig paths,
ConfigReader configReader) {
RunManager manager = new RunManager(params, paths, configReader);
private static RayCliArgs rayArgs = new RayCliArgs();

private static RunManager startRayHead() {
RayConfig rayConfig = RayConfig.create();
RunManager manager = new RunManager(rayConfig);
try {
manager.startRayHead();
manager.startRayProcesses(true);
} catch (Exception e) {
e.printStackTrace();
RayLog.core.error("error at RayCli startRayHead", e);
throw new RuntimeException("Ray head node start failed", e);
LOGGER.error("Failed to start head node.", e);
throw new RuntimeException("Failed to start Ray head node.", e);
}

RayLog.core.info("Started Ray head node. Redis address: {}", manager.info().redisAddress);
LOGGER.info("Ray head node started. Redis address is {}", rayConfig.getRedisAddress());
return manager;
}

private static RunManager startRayNode(RayParameters params, PathConfig paths,
ConfigReader configReader) {
RunManager manager = new RunManager(params, paths, configReader);

private static RunManager startRayNode() {
RayConfig rayConfig = RayConfig.create();
RunManager manager = new RunManager(rayConfig);
try {
manager.startRayNode();
manager.startRayProcesses(false);
} catch (Exception e) {
e.printStackTrace();
RayLog.core.error("error at RayCli startRayNode", e);
throw new RuntimeException("Ray work node start failed, err = " + e.getMessage());
LOGGER.error("Failed to start work node.", e);
throw new RuntimeException("Failed to start work node.", e);
}

RayLog.core.info("Started Ray work node.");
LOGGER.info("Ray work node started.");
return manager;
}

private static RunManager startProcess(CommandStart cmdStart, ConfigReader config) {
PathConfig paths = new PathConfig(config);
RayParameters params = new RayParameters(config);

// Init RayLog before using it.
RayLog.init(params.log_dir);

RayLog.core.info("Using IP address {} for this node.", params.node_ip_address);
private static RunManager startProcess(CommandStart cmdStart) {
RunManager manager;
if (cmdStart.head) {
manager = startRayHead(params, paths, config);
manager = startRayHead();
} else {
manager = startRayNode(params, paths, config);
manager = startRayNode();
}
return manager;
}

private static void start(CommandStart cmdStart, ConfigReader reader) {
startProcess(cmdStart, reader);
private static void start(CommandStart cmdStart) {
startProcess(cmdStart);
}

private static void stop(CommandStop cmdStop) {
String[] cmd = {"/bin/sh", "-c", ""};

cmd[2] = "killall global_scheduler local_scheduler plasma_store plasma_manager";
try {
Runtime.getRuntime().exec(cmd);
} catch (IOException e) {
RayLog.core.warn("exception in killing ray processes");
}

cmd[2] = "kill $(ps aux | grep redis-server | grep -v grep | "
cmd[2] = "kill $(ps aux | grep ray | grep -v grep | "
+ "awk \'{ print $2 }\') 2> /dev/null";
try {
Runtime.getRuntime().exec(cmd);
} catch (IOException e) {
RayLog.core.warn("exception in killing ray processes");
}

cmd[2] = "kill -9 $(ps aux | grep DefaultWorker | grep -v grep | "
+ "awk \'{ print $2 }\') 2> /dev/null";
try {
Runtime.getRuntime().exec(cmd);
} catch (IOException e) {
RayLog.core.warn("exception in killing ray processes");
}
}

private static String[] buildRayRuntimeArgs(CommandSubmit cmdSubmit) {

if (cmdSubmit.redisAddress == null) {
throw new RuntimeException(
"--redis-address must be specified to submit a job");
}

List<String> argList = new ArrayList<String>();
String section = "ray.java.start.";
String overwrite = "--overwrite="
+ section + "redis_address=" + cmdSubmit.redisAddress + ";"
+ section + "run_mode=" + "CLUSTER";

argList.add(overwrite);

if (cmdSubmit.config != null) {
String config = "--config=" + cmdSubmit.config;
argList.add(config);
LOGGER.error("Exception in killing ray processes.", e);
}

String[] args = new String[argList.size()];
argList.toArray(args);

return args;
}

private static void submit(CommandSubmit cmdSubmit, String configPath) throws Exception {
ConfigReader config = new ConfigReader(configPath, "ray.java.start.deploy=true");
PathConfig paths = new PathConfig(config);
RayParameters params = new RayParameters(config);
params.redis_address = cmdSubmit.redisAddress;
params.run_mode = RunMode.CLUSTER;

KeyValueStoreLink kvStore = new RedisClient();
kvStore.setAddr(cmdSubmit.redisAddress);
StateStoreProxy stateStoreProxy = new StateStoreProxyImpl(kvStore);
stateStoreProxy.initializeGlobalState();

// Init RayLog before using it.
RayLog.init(params.log_dir);
UniqueId appId = params.driver_id;
String appDir = "/tmp/" + cmdSubmit.className;

// Start driver process.
RunManager runManager = new RunManager(params, paths, config);
Process proc = runManager.startDriver(
DefaultDriver.class.getName(),
cmdSubmit.redisAddress,
appId,
appDir,
params.node_ip_address,
cmdSubmit.className,
cmdSubmit.classArgs,
"",
null);

if (null == proc) {
RayLog.rapp.error("Failed to start driver.");
return;
}

RayLog.rapp.info("Driver started.");
}

private static String getConfigPath(String config) {
String configPath;

if (config != null && !config.equals("")) {
configPath = config;
} else {
configPath = System.getenv("RAY_CONFIG");
if (configPath == null) {
configPath = System.getProperty("ray.config");
}
if (configPath == null) {
throw new RuntimeException(
"Please set config file path in env RAY_CONFIG or property ray.config");
}
}
return configPath;
}

public static void main(String[] args) throws Exception {
public static void main(String[] args) {

CommandStart cmdStart = new CommandStart();
CommandStop cmdStop = new CommandStop();
CommandSubmit cmdSubmit = new CommandSubmit();
JCommander rayCommander = JCommander.newBuilder().addObject(rayArgs)
.addCommand("start", cmdStart)
.addCommand("stop", cmdStop)
.addCommand("submit", cmdSubmit)
.build();
rayCommander.parse(args);

Expand All @@ -210,21 +90,13 @@ public static void main(String[] args) throws Exception {
System.exit(0);
}

String configPath;
switch (cmd) {
case "start": {
configPath = getConfigPath(cmdStart.config);
ConfigReader config = new ConfigReader(configPath, cmdStart.overwrite);
start(cmdStart, config);
}
break;
case "start":
start(cmdStart);
break;
case "stop":
stop(cmdStop);
break;
case "submit":
configPath = getConfigPath(cmdSubmit.config);
submit(cmdSubmit, configPath);
break;
default:
rayCommander.usage();
}
Expand Down
1 change: 0 additions & 1 deletion java/doc/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,4 @@ Run tests
::

# in `ray/java` directory
export RAY_CONFIG=ray.config.ini
mvn test
Loading

0 comments on commit 8e8e123

Please sign in to comment.