Résoudre les problèmes de restauration de Cassandra

Vous consultez la documentation d'Apigee et d'Apigee hybrid.
Il n'existe pas de documentation Apigee Edge équivalente pour ce sujet.

Symptôme

Lors de la restauration Cassandra dans Apigee hybrid, vous pouvez rencontrer des erreurs dans les journaux de restauration.

Message d'erreur

L'un des éléments suivants s'affiche dans les journaux :

java.net.ConnectException: Connection timed out (Connection timed out)
/tmp/tmp/schema.cql:662:OperationTimedOut: errors={'10.0.0.1': 'Client request timeout. See Session.execute[_async](timeout)'}, last_host=10.0.0.1
/tmp/tmp/schema.cql:6409:AlreadyExists: Table 'kvm_myorg.kvm_map_keys_descriptor' already exists

Causes possibles

Cause Description Instructions de dépannage applicables
Connexion expirée Il s'agit d'une erreur de connectivité entre les pods apigee-cassandra-restore et apigee-cassandra-default-*. Apigee hybrid
Opération arrivée à expiration Cette erreur se produit si la restauration expire après 15 minutes. Apigee hybrid
Existe déjà Ce message d'erreur n'est pas lié à la cause du problème et résulte d'une nouvelle tentative d'un job de restauration. Apigee hybrid

Cause : connexion expirée

Il s'agit d'une erreur de connectivité entre les pods apigee-cassandra-restore et les pods apigee-cassandra-default-* :

java.net.ConnectException: Connection timed out (Connection timed out)

Diagnostic

  1. Si votre réseau hôte n'est pas accessible à partir du réseau du pod, assurez-vous que hostNetwork est défini sur false sous cassandra dans overrides.yaml, comme indiqué dans Restaurer une région à partir d'une sauvegarde.
  2. Pour tester la connectivité, connectez-vous au pod apigee-mart ou apigee-runtime, qui se trouve sur le même réseau que le job apigee-cassandra-restore. Vous pouvez également utiliser n'importe quel autre pod dans le réseau du pod.
    1. Obtenez le nom du pod apigee-mart :
      kubectl -n apigee get po --selector=app=apigee-mart --no-headers -o custom-columns=":metadata.name"
    2. Exécutez une session bash dans le pod mart :
      kubectl exec -it MART_POD_NAME -n apigee -- bash

      Remplacez MART_POD_NAME par le nom du pod MART. Par exemple, apigee-mart-myorg--9a8228a-191-t0xh1-qz5fl.

    3. Exécutez des tests de connectivité sur les ports Cassandra :
      curl -v -m 5 telnet://apigee-cassandra-default-0.apigee-cassandra-default.apigee.svc.cluster.local:9042
      curl -v -m 5 telnet://apigee-cassandra-default-0.apigee-cassandra-default.apigee.svc.cluster.local:7001

    Si vous obtenez une erreur Connection timed out, cela signifie que vous rencontrez des problèmes de connectivité. Toutefois, si un message Connected to s'affiche, la connexion a bien été établie. Vous devez alors appuyer sur Ctrl+C pour fermer la connexion et continuer.

Solution

Assurez-vous que le paramètre HostNetwork est défini sur false dans le fichier overrides.yaml utilisé pour la restauration, puis répétez le processus de restauration. Si le paramètre est déjà défini sur false, mais que vous rencontrez des erreurs de connectivité, assurez-vous que les pods Cassandra sont opérationnels à l'aide de la commande suivante :

kubectl get pods -n apigee -l app=apigee-cassandra

La sortie doit se présenter sous la forme suivante :

NAME                         READY   STATUS    RESTARTS   AGE
apigee-cassandra-default-0   1/1     Running   0          14m
apigee-cassandra-default-1   1/1     Running   0          13m
apigee-cassandra-default-2   1/1     Running   0          11m
exampleuser@example hybrid-files %

Cause : l'opération a expiré

L'erreur suivante se produit si la restauration expire après 15 minutes. L'erreur indique des problèmes d'E/S, par exemple lorsque le stockage et le réseau ne permettent pas de transmettre à temps le contenu non compressé de la sauvegarde.

/tmp/tmp/schema.cql:662:OperationTimedOut: errors={'10.0.0.1': 'Client
request timeout. See Session.execute[_async](timeout)'}, last_host=10.0.0.1

Diagnostic

  1. Consultez les journaux apigee-cassandra-default-0 pour noter l'horodatage du début de la restauration :

    kubectl logs apigee-cassandra-default-0 -n apigee | grep 'MigrationManager.java' | head -n 1
  2. Comparez l'horodatage avec la dernière de création de table dans les journaux :

    kubectl logs apigee-cassandra-default-0 -n apigee | grep 'Create new table' | tail -n 1

    Les résultats de cette comparaison doivent indiquer que le pod Cassandra était toujours en train de créer des tables après le dépassement du délai avant expiration.

  3. Testez la bande passante de stockage à l'aide des commandes suivantes :

    kubectl -n apigee exec -it apigee-cassandra-default-0 -- bash -c 'dd if=/dev/zero of=/opt/apigee/data/test.img bs=200M count=1 ; rm /opt/apigee/data/test.img'
    kubectl -n apigee exec -it apigee-cassandra-default-1 -- bash -c 'dd if=/dev/zero of=/opt/apigee/data/test.img bs=200M count=1 ; rm /opt/apigee/data/test.img'
    kubectl -n apigee exec -it apigee-cassandra-default-2 -- bash -c 'dd if=/dev/zero of=/opt/apigee/data/test.img bs=200M count=1 ; rm /opt/apigee/data/test.img'

    Si la vitesse d'écriture est inférieure à 100 M/s, cela peut signifier l'absence de ressource StorageClass appropriée (SSD).

  4. Testez la bande passante réseau :

    1. Exécutez netcat sur le pod Cassandra pour écouter sur le port :

      kubectl -n apigee exec -it apigee-cassandra-default-0 -- bash -c 'nc -l -p 3456 > /dev/null'
    2. Dans une session shell distincte, obtenez le nom du pod apigee-mart :

      kubectl -n apigee get po --selector=app=apigee-mart --no-headers -o custom-columns=":metadata.name"
    3. Exécutez une session bash dans le pod apigee-mart. Vous pouvez également utiliser n'importe quel autre pod dans le réseau du pod :

      kubectl exec -it MART_POD_NAME -n apigee -- bash

      Remplacez MART_POD_NAME par le nom du pod MART. Par exemple, apigee-mart-myorg--9a8228a-191-t0xh1-qz5fl.

    4. Exécutez un test de bande passante réseau sur le pod Cassandra qui exécute toujours netcat :

      dd if=/dev/zero bs=50M count=1 | nc apigee-cassandra-default-0.apigee-cassandra-default.apigee.svc.cluster.local 3456

    Vous pouvez répéter cette procédure pour d'autres pods Cassandra. Si la vitesse obtenue est inférieure à 10 M/s, la bande passante réseau est probablement la cause du problème.

Solution

Une fois que vous avez confirmé la vitesse d'E/S lente à l'aide des étapes ci-dessus, assurez-vous que votre cluster satisfait les besoins minimum en termes de réseau et de stockage. Testez à nouveau la bande passante.

Cause : existe déjà

Diagnostic

Une erreur semblable à celle-ci s'affiche :

/tmp/tmp/schema.cql:6409:AlreadyExists: Table 'kvm_myorg.kvm_map_keys_descriptor' already exists

Solution

Ce message d'erreur n'est pas lié à la cause du problème et résulte d'une nouvelle tentative d'un job de restauration. Le message d'erreur réel devrait apparaître dans les journaux du premier pod qui a échoué.

Obtenez les journaux de l'échec initial afin de diagnostiquer le problème.

Si le problème persiste, consultez la page Vous devez collecter des informations de diagnostic.

Solution de contournement pour le problème connu 391861216

Diagnostic

Le pod Cassandra le plus élevé est dans un état CrashLoopBackoff après la restauration. Cela peut être dû au problème connu 391861216. Une erreur semblable à la suivante s'affiche dans le journal du pod Cassandra:

Cannot change the number of tokens from 512 to 256

Solution

Suivez les étapes ci-dessous pour résoudre le problème sous-jacent. Cela permettra à Cassandra de démarrer normalement tout en préservant les données.

  1. Démarrez la suppression de la PVC pour le pod Cassandra bloqué à l'état CrashLoopBackoff. Définissez POD_NAME sur le nom du pod dans l'état CrashLoopBackoff. Définissez APIGEE_NAMESPACE sur l'espace de noms du cluster dans lequel Apigee est installé.

    kubectl delete pvc cassandra-data-POD_NAME -n APIGEE_NAMESPACE --wait=false
  2. Supprimez le pod dans l'état CrashLoopBackoff.

    kubectl delete pod POD_NAME -n APIGEE_NAMESPACE
  3. Remplacez manuellement l'hôte source de Cassandra par le pod le plus élevé. Par exemple, si vous disposez de trois réplicas, SEED_POD_NAME doit être apigee-cassandra-default-2. Cette étape n'est nécessaire qu'une seule fois et peut être ignorée pour les pods suivants.

    kubectl patch apigeeds/default -n APIGEE_NAMESPACE --type='merge' -p '{"spec": {"components": {"cassandra": {"properties": {"externalSeedHost":"SEED_POD_NAME.apigee-cassandra-default.APIGEE_NAMESPACE.svc.cluster.local"}}}}}'
  4. Supprimez le nœud avec 512 jetons de l'anneau Cassandra.

    kubectl exec -n APIGEE_NAMESPACE -t sts/apigee-cassandra-default -c apigee-cassandra -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD status' | awk '/^DN .*\?.* 512 / {print $6; exit}; /^DN .* [KMG]iB.* 512 / {print $7; exit}' | xargs -I {} kubectl exec -n APIGEE_NAMESPACE -t sts/apigee-cassandra-default -c apigee-cassandra -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD removenode {}'
  5. Attendez que le pod Cassandra se rétablisse, redémarre éventuellement plusieurs fois et atteigne un état Ready de 2/2. Le pod suivant passe alors à l'état CrashLoopBackoff.

    kubectl get pods -n APIGEE_NAMESPACE -l app=apigee-cassandra -w
  6. Mettez à jour POD_NAME et répétez les étapes précédentes pour les autres pods, un par un, lorsqu'ils passent à l'état CrashLoopBackoff jusqu'à ce que tous les pods soient dans un état Ready de 2/2 et aient un état Running.

  7. Vérifiez que tous les pods ont bien rejoint l'anneau Cassandra.

    kubectl exec -n APIGEE_NAMESPACE -t sts/apigee-cassandra-default -c apigee-cassandra -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD status'

    Tous les nœuds Cassandra doivent être à l'état UN et disposer de 256 jetons.

  8. Annulez la modification apportée à l'hôte source pour Cassandra.

    kubectl patch apigeeds/default -n APIGEE_NAMESPACE --type='merge' -p '{"spec": {"components": {"cassandra": {"properties": {"externalSeedHost":""}}}}}'

    Le contrôleur Apigee Datastore redémarre à nouveau les pods Cassandra, car il rétablit le changement d'hôte de référence.

Vous devez collecter des informations de diagnostic

Si le problème persiste, même après avoir suivi les instructions ci-dessus, rassemblez les informations de diagnostic suivantes, puis contactez Google Cloud Customer Care :

  1. Outre les données habituelles que vous pouvez être invité à fournir, collectez les données de diagnostic de tous les pods Cassandra à l'aide de la commande suivante :

    for p in $(kubectl -n apigee get pods -l app=apigee-cassandra --no-headers -o custom-columns=":metadata.name") ; do \
            for com in info describecluster failuredetector version status ring info gossipinfo compactionstats tpstats netstats cfstats proxyhistograms gcstats ; do kubectl \
            -n apigee exec ${p} -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD '"$com"' 2>&1 '\
            | tee /tmp/k_cassandra_nodetool_${com}_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt | head -n 40 ; echo '...' ; done; done
          
  2. Compressez-les et incluez-les dans la demande d'assistance :

    tar -cvzf /tmp/cassandra_data_$(date +%Y.%m.%d_%H.%M.%S).tar.gz /tmp/k_cassandra_nodetool*
  3. Collectez et incluez les journaux du pod de restauration. Notez que les journaux ne restent disponibles que peut de temps. Ils doivent donc être collectés juste après l'échec.
  4. Si vous avez suivi les étapes de diagnostic ci-dessus, collectez tous les résultats de la console, copiez-les dans un fichier et incluez le fichier dans la demande d'assistance.