Courses SSA

networks:
  cassandra:
 
services:
  cassandra1:
    image: cassandra:latest
    container_name: cassandra1
    hostname: cassandra1
    networks:
      - cassandra
    ports:
      - "9042:9042"
      - "7070:7070"   # JMX Exporter
     expose:
      - "7000"
    environment: &environment
        JVM_EXTRA_OPTS: >
          -Dcom.sun.management.jmxremote
          -Dcom.sun.management.jmxremote.local.only=false
          -Dcom.sun.management.jmxremote.authenticate=false
          -Dcom.sun.management.jmxremote.ssl=false
          -Djava.rmi.server.hostname=cassandra1
          -Dcom.sun.management.jmxremote.port=7199
          -Dcom.sun.management.jmxremote.rmi.port=7199
        CASSANDRA_SEEDS: "cassandra1"
        MAX_HEAP_SIZE: 1G
        HEAP_NEWSIZE: 256M

 
  cassandra2:
    image: cassandra:latest
    container_name: cassandra2
    hostname: cassandra2
    networks:
      - cassandra
    ports:
      - "9043:9042"
    environment: *environment   
    depends_on:
      cassandra1:  
        condition: service_started
 
  cassandra3:
    image: cassandra:latest
    container_name: cassandra3
    hostname: cassandra3
    networks:
      - cassandra
    ports:
      - "9044:9042"
    environment: *environment   
    depends_on:
      cassandra2:   
        condition: service_started

  cassandra-exporter:
    image: bitnami/cassandra-exporter:2.3.8
    container_name: cassandra_exporter
    # environment:
    #   Configure how the exporter connects to Cassandra / JMX:
    #   - CASSANDRA_JMX_HOST=cassandra
    #   - CASSANDRA_JMX_PORT=7199
    #   If auth is needed:
    #   - CASSANDRA_JMX_USER=...
    #   - CASSANDRA_JMX_PASSWORD=...
    volumes:
      - ./config.yml:/opt/bitnami/cassandra-exporter/config.yml:ro
    expose:
      - "8080"   # metrics endpoint

  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
    ports:
      - "9090:9090"


  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    depends_on:
      - prometheus
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=admin
nano ./docker-compose.yaml
docker compose up -d
TAG=latest

REAPER_JMX_AUTH_USERNAME=reaperUser
REAPER_JMX_AUTH_PASSWORD=reaperPass

# Authentication credentials (required for security)
REAPER_AUTH_USER=admin
REAPER_AUTH_PASSWORD=your-secure-admin-password

docker run -p 8080:8080 -p 8081:8081 -e "REAPER_JMX_AUTH_USERNAME=${REAPER_JMX_AUTH_USERNAME}" -e "REAPER_JMX_AUTH_PASSWORD=${REAPER_JMX_AUTH_PASSWORD}" -e "REAPER_AUTH_USER=${REAPER_AUTH_USER}" -e "REAPER_AUTH_PASSWORD=${REAPER_AUTH_PASSWORD}" --name reaper -d thelastpickle/cassandra-reaper:${TAG}

http://localhost:8080/webui

docker network list
# (récupérer le nom du réseau)
# commande : docker network connect <nom_réseau> <nom_container>
docker network connect user_cassandra reaper

Ajouter Cluster :

  • cassandra1

prometheus.yml

global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'cassandra_exporter'
    static_configs:
      - targets: ['cassandra-exporter:8080']

config.yml

host: cassandra1:7199
ssl: False
user:
password:
listenAddress: 0.0.0.0
listenPort: 8080
# Regular expression to match environment variable names that will be added
# as labels to all data points. The name of the label will be either
# $1 from the regex below, or the entire environment variable name if no match groups are defined
#
# Example:
# additionalLabelsFromEnvvars: "^ADDL\_(.*)$"
additionalLabelsFromEnvvars:
blacklist:
   # To profile the duration of jmx call you can start the program with the following options
   # > java -Dorg.slf4j.simpleLogger.defaultLogLevel=trace -jar cassandra_exporter.jar config.yml --oneshot
   #
   # To get intuition of what is done by cassandra when something is called you can look in cassandra
   # https://github.com/apache/cassandra/tree/trunk/src/java/org/apache/cassandra/metrics
   # Please avoid to scrape frequently those calls that are iterating over all sstables

   # Unaccessible metrics (not enough privilege)
   - java:lang:memorypool:.*usagethreshold.*

   # Leaf attributes not interesting for us but that are presents in many path
   - .*:999thpercentile
   - .*:95thpercentile
   - .*:fifteenminuterate
   - .*:fiveminuterate
   - .*:durationunit
   - .*:rateunit
   - .*:stddev
   - .*:meanrate
   - .*:mean
   - .*:min

   # Path present in many metrics but uninterresting
   - .*:viewlockacquiretime:.*
   - .*:viewreadtime:.*
   - .*:cas[a-z]+latency:.*
   - .*:colupdatetimedeltahistogram:.*

   # Mostly for RPC, do not scrap them
   - org:apache:cassandra:db:.*

   # columnfamily is an alias for Table metrics
   # https://github.com/apache/cassandra/blob/8b3a60b9a7dbefeecc06bace617279612ec7092d/src/java/org/apache/cassandra/metrics/TableMetrics.java#L162
   - org:apache:cassandra:metrics:columnfamily:.*

   # Should we export metrics for system keyspaces/tables ?
   - org:apache:cassandra:metrics:[^:]+:system[^:]*:.*

   # Logback doesn't have any useful metrics
   - ch:qos:logback:.*

   # Don't scrap us
   - com:criteo:nosql:cassandra:exporter:.*

maxScrapFrequencyInSec:
  50:
    - .*

  # Refresh those metrics only every hour as it is costly for cassandra to retrieve them
  3600:
    - .*:snapshotssize:.*
    - .*:estimated.*
    - .*:totaldiskspaceused:.*

https://hub.docker.com/r/bitnami/cassandra-exporter

sudo dnf install epel-release
sudo dnf update
sudo dnf install python3-pip
sudo pip3 install cassandra-driver
from cassandra.cluster import Cluster
from cassandra.query import SimpleStatement, ConsistencyLevel

# 1. Connect to the Cassandra cluster
cluster = Cluster(['127.0.0.1'])  # Replace with your Cassandra IPs if needed
session = cluster.connect()

# 2. Create a keyspace
keyspace_query = """
CREATE KEYSPACE IF NOT EXISTS test_keyspace
WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '3'}
"""
session.execute(keyspace_query)
print("Keyspace created!")

# 3. Set the keyspace for use
session.set_keyspace('test_keyspace')

# 4. Create a table
table_query = """
CREATE TABLE IF NOT EXISTS users (
    id UUID PRIMARY KEY,
    name text,
    age int
)
"""
session.execute(table_query)
print("Table created!")

# 5. Insert data
from uuid import uuid4

user_id = uuid4()
insert_query = "INSERT INTO users (id, name, age) VALUES (%s, %s, %s)"
session.execute(insert_query, (user_id, 'Alice', 30))
print("Data inserted!")

## Insert with custom consistency level
user_id = uuid4()
insert_query = SimpleStatement(
    "INSERT INTO users (id, name, age) VALUES (%s, %s, %s)",
    consistency_level=ConsistencyLevel.QUORUM  # Change consistency level here
)
session.execute(insert_query, (user_id, 'Alice', 30))


# 6. Select data
select_query = "SELECT id, name, age FROM users"
rows = session.execute(select_query)
print("Current users:")
for row in rows:
    print(f"id: {row.id}, name: {row.name}, age: {row.age}")

# 7. Update data
update_query = "UPDATE users SET age = %s WHERE id = %s"
session.execute(update_query, (31, user_id))
print("Data updated!")

# Verify update
rows = session.execute(select_query)
print("Users after update:")
for row in rows:
    print(f"id: {row.id}, name: {row.name}, age: {row.age}")

# 8. Close connection
cluster.shutdown()
python3 ./main.py
# main = le nom de votre fichier