[ray_client]: first draft of documentation (#13216)

This commit is contained in:
Barak Michener
2021-01-08 15:38:36 -08:00
committed by GitHub
parent f916549602
commit eb6f403b97
7 changed files with 128 additions and 9 deletions
+1
View File
@@ -304,6 +304,7 @@ Papers
xgboost-ray.rst
dask-on-ray.rst
mars-on-ray.rst
ray-client.rst
.. toctree::
:hidden:
+69
View File
@@ -0,0 +1,69 @@
**********
Ray Client
**********
.. note::
This feature is still in beta and subject to changes.
===========
Basic usage
===========
While in beta, the server is available as an executable module. To start the server, run
``python -m ray.util.client.server [--host host_ip] [--port port] [--redis-address address] [--redis-password password]``
This runs ``ray.init()`` with default options and exposes the client gRPC port at ``host_ip:port`` (by default, ``0.0.0.0:50051``). Providing ``redis-address`` and ``redis-password`` will be passed into ``ray.init()`` when the server starts, allowing connection to an existing Ray cluster, as per the `cluster setup <cluster/index.html>`_ instructions.
From here, another Ray script can access that server from a networked machine with ``ray.util.connect()``
.. code-block:: python
import ray
import ray.util
ray.util.connect("0.0.0.0:50051") # replace with the appropriate host and port
# Normal Ray code follows
@ray.remote
def f(x):
return x ** x
do_work.remote(2)
#....
When the client disconnects, any object or actor references held by the server on behalf of the client are dropped, as if directly disconnecting from the cluster
===================
``RAY_CLIENT_MODE``
===================
Because Ray client mode affects the behavior of the Ray API, larger scripts or libraries imported before ``ray.util.connect()`` may not realize they're in client mode. This feature is being tracked with `issue #13272 <https://github.com/ray-project/ray/issues/13272>`_ but the workaround here is provided for beta users.
One option is to defer the imports from a ``main`` script that calls ``ray.util.connect()`` first. However, some older scripts or libraries might not support that.
Therefore, an environment variable is also available to force a Ray program into client mode: ``RAY_CLIENT_MODE`` An example usage:
.. code-block:: bash
RAY_CLIENT_MODE=1 python my_ray_program.py
===================================
Programatically creating the server
===================================
For larger use-cases, it may be desirable to connect remote Ray clients to an existing Ray environment. The server can be started separately via
.. code-block:: python
from ray.util.client.server import serve
server = serve("0.0.0.0:50051")
# Server does some work
# ...
# Time to clean up
server.stop(0)
+2
View File
@@ -18,6 +18,8 @@ There are three ways of starting the Ray runtime:
* Explicitly via CLI (:ref:`start-ray-cli`)
* Explicitly via the cluster launcher (:ref:`start-ray-up`)
You can also connect to an existing Ray runtime using the `Ray Client <ray-client.html>`
.. _start-ray-init:
Starting Ray on a single machine
+15 -3
View File
@@ -7,8 +7,20 @@ from ray.util.placement_group import (placement_group, placement_group_table,
remove_placement_group)
from ray.util import rpdb as pdb
from ray.util.client_connect import connect, disconnect
__all__ = [
"ActorPool", "disable_log_once_globally", "enable_periodic_logging",
"iter", "log_once", "pdb", "placement_group", "placement_group_table",
"remove_placement_group", "inspect_serializability", "collective"
"ActorPool",
"disable_log_once_globally",
"enable_periodic_logging",
"iter",
"log_once",
"pdb",
"placement_group",
"placement_group_table",
"remove_placement_group",
"inspect_serializability",
"collective",
"connect",
"disconnect",
]
+1 -1
View File
@@ -75,7 +75,7 @@ class RayAPIStub:
return getattr(self.api, key)
def is_connected(self) -> bool:
return self.api is not None
return self.client_worker is not None
def init(self, *args, **kwargs):
if self._server is not None:
+9 -5
View File
@@ -427,7 +427,7 @@ def main():
"-p", "--port", type=int, default=50051, help="Port to bind to")
parser.add_argument(
"--redis-address",
required=True,
required=False,
type=str,
help="Address to use to connect to Ray")
parser.add_argument(
@@ -437,11 +437,15 @@ def main():
help="Password for connecting to Redis")
args = parser.parse_args()
logging.basicConfig(level="INFO")
if args.redis_password:
ray.init(
address=args.redis_address, _redis_password=args.redis_password)
if args.redis_address:
if args.redis_password:
ray.init(
address=args.redis_address,
_redis_password=args.redis_password)
else:
ray.init(address=args.redis_address)
else:
ray.init(address=args.redis_address)
ray.init()
hostport = "%s:%d" % (args.host, args.port)
logger.info(f"Starting Ray Client server on {hostport}")
server = serve(hostport)
+31
View File
@@ -0,0 +1,31 @@
from ray.util.client import ray
from ray._private.client_mode_hook import _enable_client_hook
from ray._private.client_mode_hook import _explicitly_enable_client_mode
from typing import List
from typing import Tuple
def connect(conn_str: str,
secure: bool = False,
metadata: List[Tuple[str, str]] = None) -> None:
if ray.is_connected():
raise RuntimeError("Ray Client is already connected. "
"Maybe you called ray.util.connect twice by "
"accident?")
# Enable the same hooks that RAY_CLIENT_MODE does, as
# calling ray.util.connect() is specifically for using client mode.
_enable_client_hook(True)
_explicitly_enable_client_mode()
# TODO(barakmich): https://github.com/ray-project/ray/issues/13274
# for supporting things like cert_path, ca_path, etc and creating
# the correct metadata
return ray.connect(conn_str, secure=secure, metadata=metadata)
def disconnect():
if not ray.is_connected():
raise RuntimeError("Ray Client is currently disconnected.")
return ray.disconnect()