Introducción

Los sistemas distribuidos son una colección de computadoras independientes que parecen un único sistema coherente para los usuarios. Estos sistemas permiten la distribución de tareas y recursos a través de múltiples nodos, lo que puede mejorar la eficiencia, la escalabilidad y la disponibilidad. En esta sección, exploraremos los conceptos fundamentales de los sistemas distribuidos.

Objetivos de Aprendizaje

Al finalizar esta sección, deberías ser capaz de:

  • Definir qué es un sistema distribuido.
  • Comprender las características clave de los sistemas distribuidos.
  • Identificar los componentes principales de un sistema distribuido.
  • Reconocer ejemplos comunes de sistemas distribuidos en la vida real.

Definición de Sistemas Distribuidos

Un sistema distribuido es un conjunto de computadoras independientes que trabajan juntas para proporcionar un servicio o resolver un problema. Estas computadoras, también conocidas como nodos, se comunican y coordinan sus acciones mediante el intercambio de mensajes.

Características Clave

  1. Transparencia: Los usuarios y las aplicaciones no deben notar la distribución del sistema. Esto incluye:

    • Transparencia de Acceso: Oculta las diferencias en la representación de datos y cómo se accede a ellos.
    • Transparencia de Ubicación: Oculta dónde se encuentran los recursos.
    • Transparencia de Migración: Oculta el hecho de que los recursos pueden moverse de un lugar a otro.
    • Transparencia de Replicación: Oculta el hecho de que los recursos pueden estar replicados.
    • Transparencia de Concurrencia: Oculta el hecho de que los recursos pueden ser compartidos por varios usuarios.
    • Transparencia de Fallos: Oculta los fallos y la recuperación de los mismos.
  2. Escalabilidad: La capacidad del sistema para manejar el crecimiento, ya sea en términos de número de nodos, usuarios o volumen de datos.

  3. Confiabilidad y Disponibilidad: La capacidad del sistema para seguir funcionando correctamente incluso cuando algunos de sus componentes fallan.

  4. Heterogeneidad: La capacidad del sistema para operar en diferentes plataformas y con diferentes tecnologías.

Componentes Principales

  1. Nodos: Las computadoras individuales que forman parte del sistema distribuido.
  2. Red de Comunicación: El medio a través del cual los nodos se comunican entre sí.
  3. Middleware: Software que proporciona servicios y capacidades comunes para las aplicaciones distribuidas, facilitando la comunicación y la gestión de datos.

Ejemplos de Sistemas Distribuidos

  1. World Wide Web (WWW): Una red de servidores web distribuidos que proporcionan acceso a información y servicios.
  2. Sistemas de Archivos Distribuidos: Como NFS (Network File System) y HDFS (Hadoop Distributed File System).
  3. Bases de Datos Distribuidas: Como Google Spanner y Amazon DynamoDB.
  4. Computación en la Nube: Servicios como AWS, Google Cloud y Microsoft Azure que proporcionan recursos de computación distribuidos.

Ejemplo Práctico

Para ilustrar cómo funciona un sistema distribuido, consideremos un sistema de archivos distribuido simple. Supongamos que tenemos tres nodos (A, B y C) que almacenan archivos. Cuando un usuario quiere acceder a un archivo, el sistema debe determinar en qué nodo se encuentra el archivo y luego recuperar el archivo para el usuario.

# Ejemplo de un sistema de archivos distribuido simple
class Nodo:
    def __init__(self, nombre):
        self.nombre = nombre
        self.archivos = {}

    def almacenar_archivo(self, nombre_archivo, contenido):
        self.archivos[nombre_archivo] = contenido

    def obtener_archivo(self, nombre_archivo):
        return self.archivos.get(nombre_archivo, None)

# Crear nodos
nodo_a = Nodo("A")
nodo_b = Nodo("B")
nodo_c = Nodo("C")

# Almacenar archivos en nodos
nodo_a.almacenar_archivo("archivo1.txt", "Contenido del archivo 1")
nodo_b.almacenar_archivo("archivo2.txt", "Contenido del archivo 2")
nodo_c.almacenar_archivo("archivo3.txt", "Contenido del archivo 3")

# Función para obtener un archivo de cualquier nodo
def obtener_archivo_distribuido(nombre_archivo):
    for nodo in [nodo_a, nodo_b, nodo_c]:
        contenido = nodo.obtener_archivo(nombre_archivo)
        if contenido:
            return contenido
    return "Archivo no encontrado"

# Obtener un archivo
print(obtener_archivo_distribuido("archivo2.txt"))

Explicación del Código

  1. Clase Nodo: Representa un nodo en el sistema distribuido. Cada nodo tiene un nombre y un diccionario de archivos.
  2. Métodos almacenar_archivo y obtener_archivo: Permiten almacenar y recuperar archivos en un nodo.
  3. Creación de Nodos: Se crean tres nodos (A, B y C).
  4. Almacenamiento de Archivos: Se almacenan archivos en diferentes nodos.
  5. Función obtener_archivo_distribuido: Busca un archivo en todos los nodos y lo devuelve si lo encuentra.

Ejercicio Práctico

Ejercicio 1

Modifica el ejemplo anterior para que cada nodo registre en un log cada vez que se almacena o se recupera un archivo. El log debe incluir el nombre del archivo y la acción realizada (almacenamiento o recuperación).

Solución

class Nodo:
    def __init__(self, nombre):
        self.nombre = nombre
        self.archivos = {}
        self.log = []

    def almacenar_archivo(self, nombre_archivo, contenido):
        self.archivos[nombre_archivo] = contenido
        self.log.append(f"Almacenado: {nombre_archivo}")

    def obtener_archivo(self, nombre_archivo):
        contenido = self.archivos.get(nombre_archivo, None)
        if contenido:
            self.log.append(f"Recuperado: {nombre_archivo}")
        return contenido

    def mostrar_log(self):
        return self.log

# Crear nodos
nodo_a = Nodo("A")
nodo_b = Nodo("B")
nodo_c = Nodo("C")

# Almacenar archivos en nodos
nodo_a.almacenar_archivo("archivo1.txt", "Contenido del archivo 1")
nodo_b.almacenar_archivo("archivo2.txt", "Contenido del archivo 2")
nodo_c.almacenar_archivo("archivo3.txt", "Contenido del archivo 3")

# Función para obtener un archivo de cualquier nodo
def obtener_archivo_distribuido(nombre_archivo):
    for nodo in [nodo_a, nodo_b, nodo_c]:
        contenido = nodo.obtener_archivo(nombre_archivo)
        if contenido:
            return contenido
    return "Archivo no encontrado"

# Obtener un archivo
print(obtener_archivo_distribuido("archivo2.txt"))

# Mostrar logs
print(nodo_a.mostrar_log())
print(nodo_b.mostrar_log())
print(nodo_c.mostrar_log())

Explicación de la Solución

  1. Atributo log: Se añade un atributo log a la clase Nodo para registrar las acciones.
  2. Métodos almacenar_archivo y obtener_archivo: Se actualizan para añadir entradas al log cada vez que se almacena o se recupera un archivo.
  3. Método mostrar_log: Se añade para mostrar el log de acciones realizadas en el nodo.

Conclusión

En esta sección, hemos cubierto los conceptos básicos de los sistemas distribuidos, incluyendo sus características clave, componentes principales y ejemplos prácticos. Estos fundamentos son esenciales para comprender cómo funcionan los sistemas distribuidos y cómo se pueden utilizar para resolver problemas complejos de manera eficiente y escalable. En la próxima sección, exploraremos los diferentes modelos de sistemas distribuidos.

© Copyright 2024. Todos los derechos reservados