Apache Cassandra es una base de datos NoSQL distribuida de columnas anchas, sin nodo maestro, pensada para cargas con muchas escrituras y alta disponibilidad: cada dato se replica en varios nodos y el clúster sigue funcionando aunque alguno caiga. En este tutorial instalarás Cassandra 5.0 desde el repositorio oficial de Apache en tres servidores Ubuntu 24.04, los unirás en un clúster con autenticación activada, crearás un keyspace y una tabla con CQL y aprenderás a comprobar el estado y hacer copias con nodetool.

Requisitos previos

Para seguir esta guía necesitas:

  • Tres servidores con Ubuntu 24.04 LTS, por ejemplo tres VPS de CubePath, conectados por red privada. En esta guía se usan 10.0.0.21, 10.0.0.22 y 10.0.0.23 (nodo 1, nodo 2 y nodo 3). Sustitúyelas por las tuyas.
  • Un usuario no root con privilegios sudo en cada servidor.
  • Al menos 4 GB de RAM por nodo (8 GB o más en producción) y disco SSD.
  • Si solo quieres probar Cassandra, puedes seguir la guía con un único servidor: omite el paso 4 y usa un factor de replicación de 1.

Los pasos 1 a 3 se ejecutan en los tres nodos.

Paso 1: Instalar Java

Cassandra 5.0 funciona con Java 11 o Java 17. Instala OpenJDK 17 desde los repositorios de Ubuntu:

sudo apt update
sudo apt install -y openjdk-17-jre-headless

Comprueba la versión:

java -version
openjdk version "17.0.16" 2025-07-15
OpenJDK Runtime Environment (build 17.0.16+8-Ubuntu-0ubuntu124.04.1)
OpenJDK 64-Bit Server VM (build 17.0.16+8-Ubuntu-0ubuntu124.04.1, mixed mode, sharing)

Paso 2: Añadir el repositorio de Apache Cassandra

Descarga el archivo de claves del proyecto en /etc/apt/keyrings y añade el repositorio de la serie 5.0 (50x):

sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL -o /etc/apt/keyrings/apache-cassandra.asc https://downloads.apache.org/cassandra/KEYS
echo "deb [signed-by=/etc/apt/keyrings/apache-cassandra.asc] https://debian.cassandra.apache.org 50x main" | sudo tee /etc/apt/sources.list.d/cassandra.list

Instala Cassandra:

sudo apt update
sudo apt install -y cassandra

El paquete arranca Cassandra automáticamente con la configuración por defecto (un clúster de un solo nodo llamado Test Cluster). Como vas a cambiar el nombre del clúster, detén el servicio y borra los datos que se acaban de crear, que guardan ese nombre:

sudo systemctl stop cassandra
sudo rm -rf /var/lib/cassandra/data/* /var/lib/cassandra/commitlog/* /var/lib/cassandra/saved_caches/* /var/lib/cassandra/hints/*

Paso 3: Configurar cassandra.yaml

Cassandra se configura en /etc/cassandra/cassandra.yaml. Ábrelo:

sudo nano /etc/cassandra/cassandra.yaml

Localiza y cambia las siguientes claves (usa Ctrl+W para buscarlas). En listen_address y rpc_address pon la IP privada del nodo que estás configurando:

cluster_name: 'cubepath_cluster'

seed_provider:
  - class_name: org.apache.cassandra.locator.SimpleSeedProvider
    parameters:
      - seeds: "10.0.0.21:7000,10.0.0.22:7000"

listen_address: 10.0.0.21
rpc_address: 10.0.0.21

endpoint_snitch: GossipingPropertyFileSnitch

authenticator: PasswordAuthenticator
authorizer: CassandraAuthorizer

Qué hace cada clave:

  • cluster_name: debe ser idéntico en todos los nodos; un nodo con otro nombre no se une.
  • seeds: nodos de contacto que usan los demás al arrancar para descubrir el clúster. Dos semillas bastan en un clúster pequeño; no pongas todos los nodos.
  • listen_address: IP para la comunicación entre nodos (puerto 7000).
  • rpc_address: IP en la que escucha CQL para los clientes (puerto 9042).
  • endpoint_snitch: GossipingPropertyFileSnitch lee el centro de datos y el rack de cada nodo, necesario para NetworkTopologyStrategy.
  • authenticator y authorizer: exigen usuario y contraseña y activan los permisos por rol.

Define el centro de datos y el rack del nodo:

sudo nano /etc/cassandra/cassandra-rackdc.properties
dc=dc1
rack=rack1

Paso 4: Abrir los puertos y arrancar el clúster

Permite el tráfico entre nodos (7000) y las conexiones CQL (9042) solo desde la red privada. En los tres nodos:

sudo ufw allow from 10.0.0.0/24 to any port 7000 proto tcp
sudo ufw allow from 10.0.0.0/24 to any port 9042 proto tcp

El puerto JMX (7199), que usa nodetool, escucha solo en localhost por defecto y no hace falta abrirlo.

Arranca los nodos de uno en uno, empezando por las semillas, y espera a que cada uno termine de unirse (un par de minutos) antes de arrancar el siguiente:

sudo systemctl enable --now cassandra

Cuando los tres estén arrancados, comprueba el estado del anillo desde cualquier nodo:

nodetool status
Datacenter: dc1
===============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address     Load        Tokens  Owns (effective)  Host ID                               Rack
UN  10.0.0.21   104.2 KiB   16      66.7%             5b1e8a0c-2d4f-4c1b-9d7e-3f0a1b2c3d4e  rack1
UN  10.0.0.22   98.7 KiB    16      66.7%             8c2f9b1d-3e5a-4d2c-8e6f-4a1b2c3d4e5f  rack1
UN  10.0.0.23   101.5 KiB   16      66.7%             9d3a0c2e-4f6b-4e3d-9f7a-5b2c3d4e5f6a  rack1

UN significa Up y Normal: los tres nodos están activos y en el anillo. Si un nodo aparece como UJ (Joining), aún se está uniendo.

Paso 5: Asegurar el usuario administrador

Con PasswordAuthenticator activo, Cassandra crea el superusuario cassandra con contraseña cassandra. Antes de crear otro usuario, aumenta la replicación del keyspace system_auth, que guarda usuarios y permisos. Con el valor por defecto (1 réplica), si cae el nodo que lo contiene nadie podría iniciar sesión.

Conéctate con cqlsh al nodo 1:

cqlsh 10.0.0.21 -u cassandra -p cassandra
ALTER KEYSPACE system_auth
  WITH replication = {'class': 'NetworkTopologyStrategy', 'dc1': 3};

Crea tu propio superusuario, sustituyendo your_strong_password:

CREATE ROLE dbadmin WITH PASSWORD = 'your_strong_password' AND SUPERUSER = true AND LOGIN = true;

Sal con exit y repara system_auth para que los datos lleguen a todas las réplicas. Ejecuta en cada nodo:

nodetool repair --full system_auth

Entra con el nuevo usuario y desactiva el predeterminado:

cqlsh 10.0.0.21 -u dbadmin
ALTER ROLE cassandra WITH PASSWORD = 'otra_password_larga_y_aleatoria' AND SUPERUSER = false AND LOGIN = false;

Si ahora intentas entrar como cassandra, recibirás un error de autenticación.

Paso 6: Crear un keyspace y una tabla

Un keyspace es el equivalente a una base de datos y define cuántas réplicas tiene cada dato. Con NetworkTopologyStrategy indicas el número de réplicas por centro de datos. En la sesión de cqlsh como dbadmin:

CREATE KEYSPACE iot
  WITH replication = {'class': 'NetworkTopologyStrategy', 'dc1': 3};

En Cassandra, las tablas se diseñan a partir de las consultas. Si vas a consultar lecturas por sensor y día, usa (sensor_id, day) como clave de partición, y reading_time como columna de agrupación para que las filas de cada partición se guarden ordenadas:

USE iot;

CREATE TABLE readings (
  sensor_id    text,
  day          date,
  reading_time timestamp,
  temperature  double,
  humidity     double,
  PRIMARY KEY ((sensor_id, day), reading_time)
) WITH CLUSTERING ORDER BY (reading_time DESC);

Incluir el día en la clave de partición evita particiones que crecen sin límite. Inserta unos datos:

INSERT INTO readings (sensor_id, day, reading_time, temperature, humidity)
VALUES ('sensor-01', '2026-09-25', '2026-09-25 10:00:00', 21.4, 48.0);

INSERT INTO readings (sensor_id, day, reading_time, temperature, humidity)
VALUES ('sensor-01', '2026-09-25', '2026-09-25 10:05:00', 21.9, 47.5);

INSERT INTO readings (sensor_id, day, reading_time, temperature, humidity)
VALUES ('sensor-01', '2026-09-25', '2026-09-25 10:10:00', 22.3, 47.1)
USING TTL 2592000;

USING TTL hace que la fila caduque automáticamente (aquí, a los 30 días). Consulta la partición:

SELECT reading_time, temperature, humidity FROM readings
WHERE sensor_id = 'sensor-01' AND day = '2026-09-25' LIMIT 2;
 reading_time                    | temperature | humidity
---------------------------------+-------------+----------
 2026-09-25 10:10:00.000000+0000 |        22.3 |     47.1
 2026-09-25 10:05:00.000000+0000 |        21.9 |     47.5

(2 rows)

Las filas vuelven ordenadas de más reciente a más antigua gracias a CLUSTERING ORDER BY. Las consultas deben filtrar siempre por la clave de partición completa; Cassandra rechaza las que no lo hacen salvo que añadas ALLOW FILTERING, que recorre todo el clúster y no debe usarse en producción.

Paso 7: Elegir el nivel de consistencia

Cada lectura y escritura indica cuántas réplicas deben responder. Con 3 réplicas, QUORUM exige 2: si escribes y lees con QUORUM, siempre lees el dato más reciente y además toleras la caída de un nodo. En cqlsh:

CONSISTENCY QUORUM;
Consistency level set to QUORUM.
NivelRéplicas que responden (RF=3)Uso
ONE1Máxima velocidad, puede leer datos no actualizados
QUORUM2Equilibrio habitual entre consistencia y disponibilidad
LOCAL_QUORUM2 del centro de datos localClústeres con varios centros de datos
ALL3Falla si cualquier réplica está caída

En las aplicaciones, el nivel de consistencia se configura en el driver. Para comprobar la tolerancia a fallos, detén Cassandra en el nodo 3 con sudo systemctl stop cassandra y repite la consulta del paso anterior en el nodo 1 con QUORUM: seguirá funcionando. nodetool status mostrará el nodo 3 como DN (Down). Arráncalo de nuevo antes de continuar.

Paso 8: Mantenimiento con nodetool

nodetool es la herramienta de administración de cada nodo. Estos son los comandos de uso diario.

Ver estadísticas de una tabla (tamaño, latencias, número de SSTables):

nodetool tablestats iot.readings

Ejecutar una reparación completa del keyspace en un nodo. Programa nodetool repair en cada nodo al menos una vez dentro del periodo gc_grace_seconds de tus tablas (10 días por defecto) para que los datos borrados no reaparezcan:

nodetool repair --full iot

Crear una copia instantánea (snapshot). Cassandra crea enlaces duros de los archivos de datos, así que es inmediato y no ocupa espacio extra hasta que los datos cambian:

nodetool snapshot -t backup-2026-09-25 iot
nodetool listsnapshots
Snapshot Details:
Snapshot name     Keyspace name Column family name True size Size on disk Creation time
backup-2026-09-25 iot           readings           0 bytes   5.12 KiB     2026-09-25T10:32:41.118Z

Los archivos quedan en /var/lib/cassandra/data/iot/readings-<id>/snapshots/backup-2026-09-25/. Cópialos fuera del servidor (por ejemplo, con rsync o a un bucket S3) y, una vez copiados, libera el espacio:

nodetool clearsnapshot -t backup-2026-09-25

Para retirar un nodo del clúster de forma ordenada, ejecuta nodetool decommission en ese nodo: transfiere sus datos al resto antes de salir.

Solución de problemas

  • nodetool status solo muestra un nodo: revisa que cluster_name y seeds sean idénticos en todos los nodos, que el puerto 7000 esté abierto y el log /var/log/cassandra/system.log. Si el nodo arrancó con otro nombre de clúster, detenlo, vacía sus directorios de datos (paso 2) y vuelve a arrancarlo.
  • Connection refused en cqlsh: Cassandra tarda en arrancar; espera a ver Starting listening for CQL clients en /var/log/cassandra/system.log. Conéctate a la IP de rpc_address, no a localhost.
  • cqlsh falla con errores de Python: el cqlsh incluido depende de la versión de Python del sistema. Como alternativa, instala el paquete independiente de PyPI con sudo apt install -y pipx y pipx install cqlsh.
  • El nodo se detiene por falta de memoria: Cassandra calcula el heap según la RAM disponible. Asegúrate de tener al menos 4 GB y de no ejecutar otros servicios pesados en el mismo servidor.

Conclusión

Has instalado Apache Cassandra 5.0 en Ubuntu 24.04, has formado un clúster de tres nodos con autenticación, has creado un keyspace replicado y una tabla diseñada para sus consultas, y has visto cómo reparar y hacer snapshots con nodetool.

Como siguientes pasos, puedes:

  • Programar nodetool repair periódicamente en cada nodo con un temporizador de systemd.
  • Activar el cifrado entre nodos y con los clientes (server_encryption_options y client_encryption_options en cassandra.yaml).
  • Conectar tu aplicación con el driver oficial de Cassandra para tu lenguaje, usando LOCAL_QUORUM como consistencia por defecto.