简体   繁体   中英

Can I restart an iPython cluster from a notebook?

I'm just wondering if there is some python code or magics I can execute that will restart the ipython cluster. It seems like every time I change my code, it needs to be restarted.

A simple idea, seems too "hacky" for production:

Setup the Client and define a simple function for testing.

import ipyparallel as ipp
c = ipp.Client()
dv = c[:]

# simple function
@dv.remote(block=True)
def getpid():
    import os
    return os.getpid()

getpid()
[1994, 1995, 1998, 2001]

Define a function to restart the cluster. shutdown with targets='all' and hub=True should kill the entire cluster. Then start a new cluster with ! or %sx magic command.

import time
def restart_ipcluster(client):
    client.shutdown(targets='all', hub=True)
    time.sleep(5) # give the cluster a few seconds to shutdown

    # include other args as necessary
    !ipcluster start -n4 --daemonize
    time.sleep(60) # give cluster ~min to start

    return ipp.Client() # with keyword args as necessary

One drawback to this approach is that the DirectView needs to be re-assigned and any function decorated with dv.remote or dv.parallel needs to be re-executed.

c = restart_ipcluster(c)    
dv = c[:]

@dv.remote(block=True)
def getpid():
    import os
    return os.getpid()

getpid()
[3620, 3621, 3624, 3627]

Reading the source for ipyparallel Client , the shutdown method mentioned above has a keyword argument, restart=False , but it's currently not implemented. Maybe the devs are working on a reliable method.

One can start/stop an IPython cluster using the class Cluster .

Class representing an IPP cluster.
ie one controller and one or more groups of engines.
Can start/stop/monitor/poll cluster resources.
All async methods can be called synchronously with a _sync suffix, eg cluster.start_cluster_sync()

Here's a demo:

Start the cluster and check if it's running

import ipyparallel as ipp
cluster = ipp.Cluster(n=4)
# start cluster asyncronously (or cluster.start_cluster_sync() without await)
await cluster.start_cluster()

# Using existing profile dir: '/Users/X/.ipython/profile_default'
# Starting 4 engines with <class 'ipyparallel.cluster.launcher.LocalEngineSetLauncher'>

# <Cluster(cluster_id='1648978529-rzr8', profile='default', controller=<running>, engine_sets=['1648978530'])>

rc = ipp.Client(cluster_id='1648978529-rzr8')

cluster._is_running()
# True

This can be also seen in the Clusters tab of the Jupyter notebook: 一个集群运行 - Jupyter notebook - ipyparallel

Stop the cluster

# stop cluster syncronously
cluster.stop_cluster_sync()

cluster._is_running()
# False

Restart the cluster

# start cluster syncronously
cluster.start_cluster_sync()

cluster._is_running()
# True

Use cluster as a context manager

A cluster can be also used as a context manager using a with-statement ( https://ipyparallel.readthedocs.io/en/latest/examples/Cluster%20API.html#Cluster-as-a-context-manager ):

import os
with ipp.Cluster(n=4) as rc:
    engine_pids = rc[:].apply_async(os.getpid).get_dict()
engine_pids

This way the cluster will only exist for the duration of the computation.

See also my other answer .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM