mirror of
https://github.com/wassname/ray.git
synced 2026-08-05 13:21:03 +08:00
[ray_client]: first draft of documentation (#13216)
This commit is contained in:
@@ -304,6 +304,7 @@ Papers
|
||||
xgboost-ray.rst
|
||||
dask-on-ray.rst
|
||||
mars-on-ray.rst
|
||||
ray-client.rst
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
]
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
Reference in New Issue
Block a user