Capítulo 1. ¿Qué es el Rayo y dónde encaja?

Este trabajo se ha traducido utilizando IA. Agradecemos tus opiniones y comentarios: translation-feedback@oreilly.com

Ray es principalmente una herramienta Python para la computación distribuida rápida y sencilla. Ray fue creado por el RISELab de la Universidad de California, Berkeley. Una iteración anterior de este laboratorio creó el software inicial que acabó convirtiéndose en Apache Spark. Los investigadores del RISELab crearon la empresa Anyscale para seguir desarrollando y ofrecer productos y servicios en torno a Ray.

Nota

También puedes utilizar Ray desde Java. Como muchas aplicaciones Python, bajo el capó Ray utiliza mucho C++ y algo de Fortran. El streaming de Ray también tiene algunos componentes Java.

El objetivo de Ray es resolver una mayor variedad de problemas que sus predecesores, admitiendo diversos modelos de programación escalables que van desde los actores al aprendizaje automático (ML) y al paralelismo de datos. Sus modelos de funciones remotas y actores lo convierten en un verdadero entorno de desarrollo de uso general, en lugar de sólo para big data.

Ray escala automáticamente los recursos informáticos según sea necesario, permitiéndote centrarte en tu código en lugar de gestionar servidores. Además del escalado horizontal tradicional (por ejemplo, añadiendo más máquinas), Ray puede programar tareas para aprovechar diferentes tamaños de máquina y aceleradores como las unidades de procesamiento gráfico (GPU).

Desde la introducción de Amazon Web Services (AWS) Lambda, se ha disparado el interés por la computación sin servidor. En este modelo de computación en la nube, el proveedor de la nube asigna recursos de máquinas bajo demanda, ocupándose de los servidores en nombre de sus clientes. Ray proporciona una gran base para las plataformas sin servidor de propósito general al ofrecer las siguientes características:

  • Oculta los servidores. La autoescalabilidad de Ray gestiona de forma transparente los servidores en función de los requisitos de la aplicación.

  • Al soportar actores, Ray implementa no sólo un modelo de programación sin estado (típico de la mayoría de las implementaciones sin servidor), sino también uno con estado.

  • Te permite especificar los recursos, incluidos los aceleradores de hardware necesarios para la ejecución de tus funciones sin servidor.

  • Admite comunicaciones directas entre tus tareas, por lo que no sólo es compatible con funciones sencillas, sino también con aplicaciones distribuidas complejas.

Ray proporciona una gran cantidad de bibliotecas que simplifican la creación de aplicaciones que pueden aprovechar plenamente las capacidades sin servidor de Ray. Normalmente, necesitarías herramientas diferentes para todo, desde el procesamiento de datos hasta la gestión del flujo de trabajo. Al utilizar una única herramienta para una mayor parte de tu aplicación, simplificas no sólo el desarrollo, sino también la gestión de tus operaciones.

En este capítulo, veremos dónde encaja Ray en el ecosistema y te ayudaremos a decidir si es una buena opción para tu proyecto.

¿Por qué necesitas a Ray?

A menudo necesitamos algo como Ray cuando nuestros problemas son demasiado grandes para manejarlos en un solo proceso. Dependiendo de lo grandes que sean nuestros problemas, esto puede significar escalar desde multinúcleo hasta multicomputador, todo lo cual es compatible con Ray. Si te preguntas cómo puedes gestionar el crecimiento de usuarios, datos o complejidad del mes que viene, esperamos que eches un vistazo a Ray. Ray existe porque escalar software es difícil, y tiende a ser el tipo de problema que se hace más difícil en lugar de más sencillo con el tiempo.

Ray puede escalar no sólo a múltiples ordenadores, sino también sin que tengas que gestionar directamente los servidores. El informático Leslie Lamport ha dicho: "Un sistema distribuido es aquel en el que el fallo de un ordenador que ni siquiera sabías que existía puede inutilizar tu propio ordenador". Aunque este tipo de fallo sigue siendo posible, Ray es capaz de recuperarse automáticamente de muchos tipos de fallos.

Ray se ejecuta limpiamente tanto en tu portátil como a escala con las mismas API. Esto proporciona una opción de inicio sencilla para utilizar Ray que no requiere que vayas a la nube para empezar a experimentar. Una vez que te sientas cómodo con las API y la estructura de la aplicación, puedes simplemente trasladar tu código a la nube para mejorar la escalabilidad sin necesidad de modificar tu código. Esto cubre las necesidades que existen entre un sistema distribuido y una aplicación de un solo hilo. Ray es capaz de gestionar múltiples hilos y GPUs con las mismas abstracciones que utiliza para la computación distribuida.

¿Dónde puedes correr Ray?

Ray puede implementarse en diversos entornos, desde tu ordenador portátil hasta la nube, pasando por gestores de clústeres como Kubernetes o Yarn, o seis Raspberry Pis escondidas bajo tu escritorio.1 En modo local, ponerse en marcha puede ser tan sencillo como un pip install y una llamada a ray.init. Gran parte de Ray moderno inicializará automáticamente un contexto si no hay uno presente, permitiéndote saltarte incluso esta parte.

El comando ray up , que se incluye como parte de Ray, te permite crear clusters y hará lo siguiente:

  • Aprovisiona una nueva instancia/máquina (si se ejecuta en la nube o en el gestor de clústeres) utilizando el kit de desarrollo de software (SDK) del proveedor o accede a las máquinas (si se ejecuta directamente en máquinas físicas)

  • Ejecuta comandos shell para configurar Ray con las opciones deseadas

  • Ejecuta cualquier comando de configuración personalizado y definido por el usuario (por ejemplo, establecer variables de entorno e instalar paquetes).

  • Inicializar el cluster de Rayos

  • Implementa un autoescalador si es necesario

Además de ray up, si se ejecuta en Kubernetes, puedes utilizar el operador Ray Kubernetes. Aunque ray up y el operador Kubernetes son las formas preferidas de crear clústeres Ray, puedes configurar manualmente el clúster Ray si tienes un conjunto de máquinas existentes, ya sean físicas o virtuales (VM).

Dependiendo de la opción de implementación, funcionará el mismo código Ray, con grandes variaciones de velocidad. Esto puede complicarse cuando necesites bibliotecas o hardware específicos para el código, por ejemplo. Veremos más sobre la ejecución de Ray en modo local en el próximo capítulo, y si quieres escalar aún más, cubrimos la implementación en la nube y los gestores de recursos en el Apéndice B.

Ejecutar tu código con Ray

Ray es más que una simple biblioteca que importas; también es una herramienta de gestión de clusters. Además de importar la biblioteca, necesitas conectarte a un clúster Ray. Tienes tres opciones para conectar tu código a un clúster Ray:

Llamar a ray.init sin argumentos

Esto lanza una instancia de Ray incrustada, de un solo nodo, que está inmediatamente disponible para la aplicación.

Utilizar el Cliente Rayo ray.init("ray://<head_node_host>:10001")

Por defecto, cada clúster Ray se inicia con un servidor cliente Ray ejecutándose en el nodo principal que puede recibir conexiones de clientes remotos. Ten en cuenta, sin embargo, que cuando el cliente está ubicado remotamente, algunas operaciones ejecutadas directamente desde el cliente pueden ser más lentas debido a las latencias de la red de área amplia (WAN). Ray no es resistente a los fallos de red entre el nodo principal y el cliente.

Utilizar la API de la línea de comandos de Ray

Puedes utilizar el comando ray submit para ejecutar scripts de Python en clusters. Esto copiará el archivo designado en el clúster del nodo principal y lo ejecutará con los argumentos dados. Si pasas los parámetros, tu código debe utilizar el módulo de Python sys que proporciona acceso a cualquier argumento de la línea de comandos a través de sys.argv. Esto elimina el posible punto de fallo de la red cuando se utiliza el Cliente Rayo.

¿Dónde encaja en el ecosistema?

Ray se encuentra en una intersección única de espacios problemáticos.

El primer problema que resuelve Ray es escalar tu código Python gestionando recursos, ya sean servidores, hilos o GPU. Los componentes básicos de Ray son un planificador, un almacenamiento de datos distribuido y un sistema de actores. El potente planificador que utiliza Ray es lo suficientemente general como para implementar flujos de trabajo sencillos, además de manejar los problemas tradicionales de escala. El sistema de actores de Ray te proporciona una forma sencilla de manejar el estado de ejecución distribuida resistente. Por tanto, Ray es capaz de actuar como un sistema reactivo, en el que sus múltiples componentes pueden reaccionar a su entorno.

Además de los bloques de construcción escalables, Ray tiene bibliotecas de nivel superior como Serve, Datasets, Tune, RLlib, Train y Workflows que existen en el espacio de problemas ML. Están diseñadas para ser utilizadas por personas con más experiencia en ciencia de datos que necesariamente en sistemas distribuidos.

En general, el ecosistema Ray se presenta en la Figura 1-2.

spwr 0102
Figura 1-2. El ecosistema del Rayo

Echemos un vistazo a algunos de estos espacios problemáticos y veamos cómo encaja Ray y cómo se compara con las herramientas existentes. La siguiente lista, adaptada de la documentación "Arquitectura de Ray 1.x" del equipo de Ray, compara Ray con varias categorías de sistemas relacionados:

Orquestadores de clúster

Cluster orquestadores como Kubernetes, Slurm y Yarn programan contenedores. Ray puede aprovecharlos para asignar nodos de clúster.

Marcos de paralelización

Comparado con marcos de paralelización de Python como el multiprocesamiento o Celery, Ray ofrece una API más general y de mayor rendimiento. Además, los objetos distribuidos de Ray permiten compartir datos entre ejecutores paralelos.

Marcos de procesamiento de datos

Las API de bajo nivel de Ray son más flexibles y se adaptan mejor a un marco de "cola distribuida" que los marcos de procesamiento de datos existentes, como Spark, Mars o Dask. Aunque Ray no tiene un conocimiento inherente de los esquemas de datos, las tablas relacionales o el flujo de datos, permite ejecutar muchos de estos marcos de procesamiento de datos, como Modin, Dask en Ray, Mars en Ray y Spark en Ray (RayDP).

Marcos de actuación

A diferencia de los marcos de actores especializados de , como Erlang, Akka y Orleans, Ray integra el marco de actores directamente en los lenguajes de programación. Además, los objetos distribuidos de Ray permiten compartir datos entre actores.

Flujos de trabajo

Cuando la mayoría de la gente habla de flujos de trabajo, se refiere a la interfaz de usuario o al desarrollo de bajo código basado en scripts. Aunque este enfoque puede ser útil para los usuarios no técnicos, a menudo aporta más dolor que valor a los ingenieros de software. Ray utiliza una implementación programática del flujo de trabajo, similar a la de Cadence. Esta implementación combina la flexibilidad de los gráficos de tareas dinámicas de Ray con sólidas garantías de durabilidad. Ray Workflows ofrece una sobrecarga de subsegundos para el lanzamiento de tareas y admite flujos de trabajo con cientos de miles de pasos. También aprovecha el almacén de objetos de Ray para pasar conjuntos de datos distribuidos entre pasos.

Sistemas HPC

A diferencia de Ray, que expone APIs de tareas y actores, la mayoría de los sistemas de computación de alto rendimiento (HPC) exponen APIs de mensajería de nivel inferior, lo que proporciona una mayor flexibilidad de aplicación. Además, muchas de las implementaciones HPC ofrecen primitivas de comunicación colectiva optimizadas. Ray proporciona una biblioteca de comunicación colectiva que implementa muchas de estas funcionalidades de .

Big Data / Marcos de datos escalables

Ray ofrece a algunas API para DataFrames escalables, una piedra angular del ecosistema de los grandes datos. Ray se basa en el proyecto Apache Arrow para proporcionar una API distribuida (limitada) de DataFrame llamada ray.data.Dataset. Está pensada principalmente para las transformaciones más sencillas y la lectura desde la nube o el almacenamiento distribuido. Más allá de eso, Ray también proporciona soporte para una experiencia más parecida a la de Pandas a través de Dask on Ray, que aprovecha la interfaz de Dask sobre Ray.

Trataremos los DataFrames escalables en el capítulo 9.

Advertencia

Además de las bibliotecas señaladas anteriormente, es posible que encuentres referencias a Mars on Ray o al soporte pandas incorporado en Ray (obsoleto). Estas bibliotecas no admiten el modo distribuido, por lo que pueden limitar tu escalabilidad. Se trata de un área en rápida evolución y algo a lo que no debes perder de vista en el futuro.

Aprendizaje automático

Ray tiene múltiples bibliotecas de ML y, en su mayor parte, sirven para delegar gran parte de las partes sofisticadas del ML en herramientas existentes como PyTorch, scikit-learn y TensorFlow, a la vez que utilizan las facilidades de computación distribuida de Ray para escalar. Ray Tune implementa el ajuste de hiperparámetros, utilizando la capacidad de Ray para entrenar muchos modelos locales basados en Python en paralelo a través de un conjunto distribuido de máquinas. Ray Train implementa el entrenamiento distribuido con PyTorch o TensorFlow. La interfaz RLlib de Ray ofrece aprendizaje por refuerzo con algoritmos centrales.

Parte de lo que permite que Ray destaque de los sistemas paralelos de datos puros para ML es su modelo de actor, que permite un seguimiento más fácil del estado (incluidos los parámetros) y la comunicación entre trabajadores. Puedes utilizar este modelo para implementar tus propios algoritmos personalizados que no formen parte de Ray Core.

Trataremos el ML con más detalle en el capítulo 10.

Programación del flujo de trabajo

La programación del flujo de trabajo es una de estas áreas que, a primera vista, puede parecer realmente sencilla. Un flujo de trabajo es "sólo" un gráfico de trabajo que hay que hacer. Sin embargo, todos los programas pueden expresarse como "sólo" un gráfico de trabajo que hay que hacer. Como novedad en la versión 2.0, Ray dispone de una biblioteca de Flujos de Trabajo para simplificar la expresión tanto de los flujos de trabajo tradicionales de lógica empresarial como de los flujos de trabajo a gran escala (por ejemplo, entrenamiento de ML).

Ray es único en la programación de flujos de trabajo porque permite que las tareas programen otras tareas sin tener que volver a llamar a un nodo central. Esto permite una mayor flexibilidad y rendimiento.

Si el motor de flujo de trabajo de Ray te parece demasiado de bajo nivel, puedes utilizar Ray para ejecutar Apache Airflow. Airflow es uno de los motores de programación de flujos de trabajo más populares en el espacio de big data. El proveedor de Apache Airflow para Ray te permite utilizar tu clúster Ray como grupo de trabajadores para Airflow.

Trataremos la programación del flujo de trabajo en el Capítulo 8.

Streaming

Streaming se considera generalmente un procesamiento de datos "en tiempo real", o datos "a medida que llegan". El streaming añade otra capa de complejidad, especialmente cuanto más cerca del tiempo real intentes llegar, ya que no todos tus datos llegarán siempre en orden o a tiempo. Ray ofrece primitivas de streaming estándar y puede utilizar Kafka como fuente y sumidero de datos de streaming. Ray utiliza sus API de modelo de actor para interactuar con los datos de streaming.

El streaming de Ray, como muchos sistemas de streaming atornillados a sistemas por lotes, tiene algunas peculiaridades interesantes. El streaming de Ray, en particular, implementa la mayor parte de su lógica en Java, a diferencia del resto de Ray. Esto puede hacer que depurar aplicaciones de streaming sea más difícil que con otros componentes de Ray.

En el Capítulo 6 veremos cómo crear aplicaciones de streaming con Ray.

Interactivo

No todas las aplicaciones "en tiempo real" son necesariamente aplicaciones de streaming. Un ejemplo común es la exploración interactiva de un conjunto de datos. Del mismo modo, interactuar con las entradas del usuario (por ejemplo, servir modelos) puede considerarse un proceso interactivo y no por lotes, pero se gestiona por separado de las bibliotecas de streaming con Ray Serve.

Lo que Ray no es

Aunque Ray es un sistema distribuido de propósito general, es importante tener en cuenta que hay algunas cosas que Ray no es (al menos, no sin que inviertas un esfuerzo considerable):

  • Lenguaje de consulta estructurado (SQL) o un motor de análisis

  • Un sistema de almacenamiento de datos

  • Apto para el funcionamiento de reactores nucleares

  • Totalmente independiente del idioma

Ray puede usarse para hacer un poco de todo esto, pero probablemente sea mejor que utilices herramientas más especializadas. Por ejemplo, aunque Ray tiene un almacén de claves/valores, no está diseñado para sobrevivir a la pérdida del nodo líder. Esto no significa que si te encuentras trabajando en un problema que necesite un poco de SQL, o algunas bibliotecas que no sean de Python, Ray no pueda satisfacer tus necesidades, simplemente puede que necesites herramientas adicionales.

Conclusión

Ray tiene el potencial de simplificar enormemente tu desarrollo y tu carga operativa para problemas de mediana a gran escala. Lo consigue ofreciendo una API unificada para una variedad de problemas tradicionalmente separados, al tiempo que proporciona escalabilidad sin servidor. Si tienes problemas que abarcan los dominios a los que sirve Ray, o simplemente estás cansado de la sobrecarga operativa de gestionar tus propios clusters, esperamos que te unas a nosotros en la aventura de aprender Ray.

En el próximo capítulo, te mostraremos cómo instalar Ray en modo local en tu máquina. También veremos algunos Hello Worlds de algunos de los ecosistemas que soporta Ray (incluyendo actores y big data).

1 La compatibilidad con ARM, incluida la de las Raspberry PI, requiere por ahora una construcción manual.

Get Escalando Python con Ray now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.