# Cassandra für Timeseries
## Keyspace erstellen
Beginnend mit der Erstellung des Keyspaces mit dem Namen `time_series`, welches die Zeitreihendaten beinhaltet werden.
```cql=
CREATE KEYSPACE time_series
WITH replication = {
'class': 'NetworkTopologyStrategy',
<data_center>: 3
};
```
`NetworkTopologyStrategy` ist die empfohlene Replikationsstrategie für Cassandra-Deployment in der Produktion. Außerdem ist der Name der Rechenzentren und deren Replikationsfaktor anzugeben.
## Datenmodellierung
Die folgende Tabellen dienen zur Speicherung von Zeitreihendaten und statistischen Metadaten, die der statistischen Berechnung von Zeitreihendaten nach einem bestimmten Zeitraum entnommen werden. Jede von dieser Tabelle weist das Attribut `date` auf, dessen Einsatz soll die Gruppierung der Daten in Bucket (pro Tag) ermöglichen. Dieses Attribut bildet mit der Attribute `tsm` und `metric` die Primärschlüssel. Diese Attribute sollen verhindern, dass die Partition in Cassandra nicht zu groß wird.
```cql=
USE time_series; /* name des Keyspaces */
CREATE TABLE IF NOT EXISTS measurements (
tsm TEXT,
metric TEXT,
date DATE,
timestamp TIMESTAMP,
value DECIMAL,
meta MAP<TEXT,TEXT>,
PRIMARY KEY ((tsm, metric, date), timestamp)
) WITH CLUSTERING ORDER BY (timestamp DESC);
/* Nur für numerische Daten */
CREATE TABLE IF NOT EXISTS measurements_stats (
tsm TEXT,
metric TEXT,
date DATE,
min DECIMAL,
max DECIMAL,
median DECIMAL,
mean DECIMAL,
stdev DECIMAL,
PRIMARY KEY ((tsm, metric), date)
) WITH CLUSTERING ORDER BY (date DESC);
```
Betrachte die obige Tabelle werden die Daten wie folgt in der `measurements`-Datenbank gespeichert.
| tsm | metric | date| timestamp | value |
| -------- | -------- | -------- | ------- |---------- |
| 6019370670cdf100087e9679 | temperature | 2021-03-11 | 1615452179000 | 234
| 6019370670cdf100087e9679 | rotation | 2021-03-11 | 1615452179000 | 23
Was die Ordinaldaten betreffen, werden sie innerhalb der `meta`-Eigenschaft gespeichert. Analog zur `measurements`-Tabelle werden die Ordinaldaten wie folgt gespiechert.
| tsm | metric | date| timestamp | value | meta |
| -------- | -------- | -------- | ------- |---------- | ---------- |
| 6019370670cdf100087e9679 | color | 2021-03-11 | 1615452179000 | null | {color: red}
## Deployment Cassandra in K8s
### Erstellung vom Secret für den Lese- / Schreibzugriff auf einen S3-Bucket
Vor der Installation des `k8ssandra`-Clusters müssen Anmeldeinformationen angegeben werden, damit Medusa Lese- / Schreibzugriff auf einen AWS S3-Bucket hat, in dem die Sicherung gespeichert wird. Medusa unterstützt lokale, Amazon S3-, Google Cloud Storage- (GCS) und Azure-Buckets. Derzeit stellt K8ssandra Konfigurationen für Amazon S3 und GCS zur Verfügung.
> Hinweis
Weitere Informationen zum Konfigurieren von Amazon S3 sind unter [AWS S3-Setup](https://github.com/thelastpickle/cassandra-medusa/blob/master/docs/aws_s3_setup.md) im Medusa-Wiki zu finden.
Beginnend mit der Erstellung des Secrets für Medusa, das für Backup und Wiederherstellung verwendet wird. Dafür wird eine Datei `medusa-bucket-key.yaml` mit folgendem Inhalt erstellt:
```yaml=
apiVersion: v1
kind: Secret
metadata:
name: medusa-bucket-key # 1
namespace: cassandra # change the name of namespace if you want it in another namespace
type: Opaque
stringData:
# Note that this currently has to be set to medusa_s3_credentials!
medusa_s3_credentials: |-
[default]
aws_access_key_id = <my_access_key>
aws_secret_access_key = <my_secret_key>
```
Der Name des Secrets in `#1` muss in `k8ssandra`-Konfigurationsdatei eingegeben. Ersetze die Werte `<my_access_key>` und `<my_secret_key>` durch die S3-Access-Credentials.
### Konfiguration
Das Deployment von Cassandra in Kubernetes-Cluster lässt sich leicht mit dem Operator `k8ssandra` einstellen. Erstelle eine Datei `values.yaml` mit folgendem Inhalt:
```yaml=
cassandra:
version: "3.11.10"
auth:
superuser:
username: cassandra # the secret will be automatically generated
cassandraLibDirVolume:
storageClass: longhorn # or local-path
size: 5Gi
allowMultipleNodesPerWorker: true
heap:
size: 1G
newGenSize: 1G
resources:
requests:
cpu: 1000m
memory: 2Gi
limits:
cpu: 1000m
memory: 2Gi
datacenters:
- name: dc1
size: 1
racks:
- name: default
kube-prometheus-stack: #2
# enabled: false # disabled this if you don't need the prometheus stack
grafana:
adminUser: admin
adminPassword: admin123
stargate: # access to cassandra through CQL, RESTAPI, GRAPHQL
enabled: true
replicas: 1
heapMB: 256
cpuReqMillicores: 200
cpuLimMillicores: 1000
medusa: # backup and restore
enabled: true
cassandraUser:
username: cassandra
storage: s3 # use s3_compatible if you want to use MinIO
storage_properties:
region: eu-central-1
# host: 192.168.29.1 # for s3_compatible
bucketName: backups.cassandra
# secure: false # set it if you s3_compatible storage is not secure
storageSecret: medusa-bucket-key
```
Diese Konfigurationsdatei erstellt einen K8ssandra-Cluster mit einem Rechenzentrum `dc1`, das einen einzelnen Cassandra-Knoten `size: 1` enthält, mit den folgenden Spezifikationen:
* Cassandra Version 3.11.10
* 1 GB für heap
* 2 GB für RAM for the container
* 1 CPU core
* 5 GB für storage
* 1 Stargate-Node mit
* 1 CPU core
* 256 MB für heap
Für einen Produktion-Ansatz müssen die obige Konfigurationsdatei angepasst und mindestens 3 Cassandra-Knoten `size: 3` deployt werden.
### Deployment
Für das Deployment wird das HELM-Chart des Operators verwendet.
```bash=
$ helm repo add k8ssandra https://helm.k8ssandra.io/stable
$ helm repo update
```
Erstelle das Medusa-Secret
```bash=
$ kubectl apply -f medusa-bucket-key.yaml
```
Nun stelle der `K8ssandra`-Cluster bereit.
```bash=
$ helm install -f ./values.yaml -n cassandra k8ssandra k8ssandra/k8ssandra
```
Nachdem der Cluster bereitgestellt wurde, überprüfe ob der Operator bereit ist.
```bash=
$ kubectl describe CassandraDataCenter dc1 | grep "Cassandra Operator Progress:"
```
_Output_:
```
Cassandra Operator Progress: Ready
```
### Port Forwarding
```bash=
$ kubectl port-forward svc/k8ssandra-dc1-stargate-service 8080 8081 8082 9042
```