Solução de problemas na restauração do Cassandra

Esta é a documentação da Apigee e da Apigee híbrida.
Não há documentação equivalente do Apigee Edge para esse tópico.

Sintoma

Durante a restauração do Cassandra na Apigee híbrida, é possível encontrar erros nos registros de restauração.

Mensagem de erro

Você verá uma das seguintes opções nos registros:

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

Causas possíveis

Causa Descrição Instruções de solução de problemas aplicáveis para
Tempo limite de conexão expirado Esse erro é de conectividade entre pods apigee-cassandra-restore e apigee-cassandra-default-*. Apigee híbrido
O tempo limite da operação expirou Esse erro ocorre quando a restauração expira após 15 minutos. Apigee híbrido
Já existe Essa mensagem de erro não está relacionada à causa do problema e é resultado de uma operação de repetição de um job de restauração. Apigee híbrido

Causa: tempo limite de conexão esgotado

O seguinte é um erro de conectividade entre pods apigee-cassandra-restore e apigee-cassandra-default-*:

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

Diagnóstico

  1. Se a rede do host não estiver acessível pela rede do pod, verifique se hostNetwork está definido como false em cassandra em overrides.yaml, conforme mostrado em Como restaurar uma região a partir de um backup.
  2. Para testar a conectividade, faça login no pod apigee-mart ou apigee-runtime, que está na mesma rede que o job apigee-cassandra-restore. Também é possível usar qualquer outro pod na rede de pods.
    1. Consiga o nome do pod apigee-mart:
      kubectl -n apigee get po --selector=app=apigee-mart --no-headers -o custom-columns=":metadata.name"
    2. Execute uma sessão bash dentro do pod mart:
      kubectl exec -it MART_POD_NAME -n apigee -- bash

      Substitua MART_POD_NAME pelo nome do pod MART. Por exemplo, apigee-mart-myorg--9a8228a-191-t0xh1-qz5fl.

    3. Execute testes de conectividade nas portas do 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

    Se você receber um erro Connection timed out na saída, isso significa que há problemas de conectividade. No entanto, se você receber uma mensagem Connected to, indicando que a conexão foi bem-sucedida, pressione Ctrl + C para fechar a conexão e continuar.

Resolução

Verifique se a configuração HostNetwork está definida como false no arquivo overrides.yaml usado para restauração e repita o processo de restauração. Se a configuração já estiver definida como false, mas você encontrar erros de conectividade, verifique se os pods do Cassandra estão funcionando com o seguinte comando:

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

As saídas terão a aparência do exemplo a seguir:

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 %

Causa: tempo limite da operação esgotado

O erro a seguir ocorrerá se a restauração expirar após mais de 15 minutos. O erro indica problemas de E/S, como armazenamento e rede que não conseguem transmitir o conteúdo descompactado do backup a tempo.

/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

Diagnóstico

  1. Verifique os registros apigee-cassandra-default-0 para observar o carimbo de data/hora do início da restauração:

    kubectl logs apigee-cassandra-default-0 -n apigee | grep 'MigrationManager.java' | head -n 1
  2. Compare o carimbo de data/hora com o registro mais recente da criação da tabela:

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

    Os resultados dessa comparação mostram que o pod do Cassandra ainda estava no processo de criação de tabelas após o tempo limite ter sido excedido.

  3. Teste a largura de banda de armazenamento com os seguintes comandos:

    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'

    Se a velocidade de gravação for inferior a 100 M/s, isso pode indicar a falta de um StorageClass apropriado (SSD) usado.

  4. Teste a largura de banda da rede:

    1. Execute netcat no pod do Cassandra para ouvir na porta:

      kubectl -n apigee exec -it apigee-cassandra-default-0 -- bash -c 'nc -l -p 3456 > /dev/null'
    2. Em uma sessão de shell separada, consiga o nome do pod apigee-mart:

      kubectl -n apigee get po --selector=app=apigee-mart --no-headers -o custom-columns=":metadata.name"
    3. Execute uma sessão bash dentro do pod apigee-mart. Também é possível usar qualquer outro pod na rede de pods:

      kubectl exec -it MART_POD_NAME -n apigee -- bash

      Substitua MART_POD_NAME pelo nome do pod MART. Por exemplo, apigee-mart-myorg--9a8228a-191-t0xh1-qz5fl.

    4. Execute um teste de largura de banda da rede no pod do Cassandra que ainda está executando o netcat:

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

    Repita o processo para outros pods do Cassandra. Se a velocidade resultante for inferior a 10 M/s, a largura de banda da rede provavelmente será a causa do problema.

Resolução

Depois que a velocidade de E/S lenta for confirmada com as etapas acima, verifique se o cluster está em conformidade com os requisitos mínimos de rede e armazenamento. Em seguida, teste a largura de banda novamente.

Causa: já existe

Diagnóstico

Você vai encontrar um erro semelhante ao seguinte:

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

Resolução

Essa mensagem de erro não está relacionada à causa do problema e é resultado de uma operação de repetição de um job de restauração. A mensagem de erro real será exibida nos registros do primeiro pod que falhou.

Consiga os registros da falha inicial para diagnosticar o problema.

Se o problema persistir, acesse Precisa de informações de diagnóstico.

Solução alternativa para o problema conhecido 391861216

Diagnóstico

O pod do Cassandra com o número mais alto está no estado CrashLoopBackoff após a restauração. Isso pode ocorrer devido ao problema conhecido 391861216. Você encontra um erro no registro do pod do Cassandra semelhante a este:

Cannot change the number of tokens from 512 to 256

Resolução

Siga as etapas abaixo para resolver o problema. Isso permite que o Cassandra seja iniciado normalmente, preservando os dados.

  1. Inicie a exclusão do PVC do pod do Cassandra que está preso no estado CrashLoopBackoff. Defina POD_NAME como o nome do pod no estado CrashLoopBackoff. Defina APIGEE_NAMESPACE como o namespace do cluster em que a Apigee está instalada.

    kubectl delete pvc cassandra-data-POD_NAME -n APIGEE_NAMESPACE --wait=false
  2. Exclua o pod no estado CrashLoopBackoff.

    kubectl delete pod POD_NAME -n APIGEE_NAMESPACE
  3. Mude manualmente o host de propagação do Cassandra para o pod com o número mais alto. Por exemplo, se você tiver três réplicas, SEED_POD_NAME será apigee-cassandra-default-2. Isso é necessário apenas uma vez e pode ser pulado para pods subsequentes.

    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. Remova o nó com 512 tokens do anel do 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. Aguarde até que o pod do Cassandra se recupere, reinicie, possivelmente mais de uma vez, e alcance um estado Ready de 2/2. O próximo pod mais alto vai entrar no estado CrashLoopBackoff.

    kubectl get pods -n APIGEE_NAMESPACE -l app=apigee-cassandra -w
  6. Atualize POD_NAME e repita as etapas anteriores para os pods restantes, um de cada vez, conforme eles entram no estado CrashLoopBackoff até que todos os pods estejam em um Ready estado de 2/2 e tenham um status Running.

  7. Verifique se todos os pods entraram no anel do 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'

    Todos os nós do Cassandra precisam ter o status UN e 256 tokens.

  8. Reverta a mudança no host de propagação do Cassandra.

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

    O controlador do Apigee Datastore vai reiniciar os pods do Cassandra novamente, revertendo a mudança do host de semente.

É necessário coletar informações de diagnóstico

Se o problema persistir mesmo depois de seguir as instruções acima, colete as seguintes informações de diagnóstico e entre em contato com o Cloud Customer Care:

  1. Além dos dados usuais que podem ser solicitados, colete os dados de diagnóstico de todos os pods do Cassandra com o seguinte comando:

    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. Compacte-o e informe-o no caso de suporte:

    tar -cvzf /tmp/cassandra_data_$(date +%Y.%m.%d_%H.%M.%S).tar.gz /tmp/k_cassandra_nodetool*
  3. Colete e forneça os registros do pod de restauração. Os registros são de curta duração, portanto, precisam ser coletados logo após a falha.
  4. Se você seguiu as etapas de diagnóstico acima, colete todas as saídas do console, copie-as em um arquivo e anexe-o ao caso de suporte.