Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

QConSP16 - Apache Cassandra Evoluindo Sistemas Distribuídos

899 views

Published on

Apresentado no QConSP 2016 por Eiti Kimura e Fernando Gonçalves

Muito se tem falado em ingestão e processamento de grandes volumes de dados, mas há ainda muito a se fazer quanto à arquitetura de sistemas distribuídos capazes de realizar esse feito, assim como as ferramentas de apoio.

Desde 2009 a Movile adotou o banco NoSQL Apache Cassandra como uma de suas soluções para dados. E desde então trabalha na evolução de suas plataformas. Com base em 6 anos nas trincheiras do desenvolvimento, vamos compartilhar como sistemas de arquitetura simples tiveram que evoluir para acompanhar o crescimento exponencial da empresa.

Mostraremos os desafios da adoção do Cassandra (e de NoSQL em geral) em sistemas críticos de alto desempenho, processando bilhões de transações por dia. Vamos mostrar também os problemas enfrentados, o que deu certo, o que deu errado e o que aprendemos com isso.

Published in: Software
  • Be the first to comment

QConSP16 - Apache Cassandra Evoluindo Sistemas Distribuídos

  1. 1. EVOLUINDO SISTEMAS DISTRIBUÍDOS 6 ANOS DE NoSQL DAS TRINCHEIRAS Eiti Kimura Fernando Gonçalves MAR 2016
  2. 2. QUEM SOMOS NÓS?
  3. 3. • Arquiteto de software e Coordenador de TI na Movile • Apache Cassandra Developer 1.1 Certified (2013) • Apache Cassandra MVP (2014 e 2015) • Apache Cassandra Contributor (2015) • Cassandra Summit Speaker (2014 e 2015) Eiti Kimura eitikimura
  4. 4. • Desenvolvedor na Movile • Estudante de Ciência da Computação na Unicamp Fernando Gonçalves fhsgoncalves
  5. 5. Sumário ● INTRODUÇÃO ● CASOS DE USO ○ Plataforma de Tarifação e controle de assinaturas ○ Registro de dados de apps e envio de notificações push ● CONCLUSÃO ○ Problemas encontrados, lições aprendidas.
  6. 6. LÍDER EM DESENVOLVIMENTO DE PLATAFORMAS DE COMÉRCIO E CONTEÚDO MÓVEL NA AMÉRICA LATINA
  7. 7. A Movile é a empresa por trás das apps que fazem sua vida mais fácil!
  8. 8. O Melhor conteúdo para Crianças
  9. 9. Líder em delivery de comida no Brasil
  10. 10. A empresa registrou um crescimento anual de 80% nos últimos 6 anos. 80%
  11. 11. INTRODUÇÃO
  12. 12. Apache Cassandra é um banco de dados não relacional (NoSQL) orientado a colunas, distribuído, escalável, de alta disponibilidade, tolerante a falhas. [The Definitive Guide, Eben Hewitt, 2010]
  13. 13. Controle de Assinaturas e Tarifações • Composto de uma API de serviço; • Responsável pelo gerenciamento de assinaturas de usuários; • Cobrança dos usuários nas operadoras; O serviço não pode parar de forma alguma e deve ser muito rápido.
  14. 14. A plataforma em números 105M de assinaturas 76,3M de usuários únicos 145M de transações ao dia
  15. 15. Linha e evolutiva da Plataforma (SBS) 2008 Banco relacional puro 2009 Apache Cassandra (v0.5) 2011 Remodelagem de dados com 4 nós no cluster Cluster da versão 1.0 para 1.2 2013 Cluster upgrade da versão 0.7 para 1.0 Expansão de 4 para 6 nós 2014 Novo indice de dados para assinaturas 2015 Expansão do cluster para 10 nós
  16. 16. ARQUITETURA V1 API DB API APIAPI API Engine Engine Engine
  17. 17. Desvantagens da Arquitetura • Ponto único de falha • Tempos de resposta lentos • Downtimes frequentes • Caro e difícil para escalar Escalar uma plataforma sem escalar as dependências externas resulta em falha.
  18. 18. ARQUITETURA V2 API API Engine Engine DB Regular SQL Queries API API
  19. 19. Benefícios da nova solução ❏ Problemas de desempenho: OK; ❏ Problemas de disponibilidade: OK; ❏ Ponto único de falha: Parcialmente Resolvido; ❏ Aumento significante no throughput de leitura e escrita;
  20. 20. ARQUITETURA V2 Ponto Fraco Engine Engine DB SQL Queries
  21. 21. QUAIS SÃO OS PROBLEMAS?
  22. 22. Problemas na Arquitetura Com o aumento da concorrência ocorre degradação de desempenho nas operações com o banco de dados relacional. Consultas ao banco relacional podem consumir tempo Continua com impacto na escalabilidade
  23. 23. Proposta de Evolução ➔ Extrair dados do Apache Cassandra ao invés do banco relacional; ➔ Sem ponto único de falha; ➔ Melhoria de desempenho, porém mais trabalho filtrando a informação;
  24. 24. BACKEND SERVICE
  25. 25. KIWI - BACKEND SERVICE Foco em smartphones Alta performance Alta disponibilidade Analytics Engajamento de usuário Notificações por Push
  26. 26. 40M Total de instalações de apps 450M Total de notificações push enviadas Análise de dados Alguns dados do Kiwi em 2015 20M Total de configurações de usuários
  27. 27. NOSSO DESAFIO Notificação por push iOS ANDROID
  28. 28. ARQUITETURA V1 SQL
  29. 29. ARQUITETURA V2 Amazon SQS DynamoDB Consumidor SQL
  30. 30. Publicador #1 Publicador #2 Publicador #3 Limite de vazão alcançado APNS GCM SQL ARQUITETURA V2 Push Notification
  31. 31. Problemas na Arquitetura $$ Custos altos Vazão de leitura muito baixa DynamoDB Vazão de leitura atingida SQL
  32. 32. Lentidão no envio de Notificações por Push
  33. 33. ARQUITETURA V3 Push Notification Publicador #1 Publicador #2 Publicador #3 APNS GCM Cassandra v2.1
  34. 34. Mudanças no modelo ➔ Amazon DynamoDB ◆ Objeto serializado com Avro ◆ Poucas colunas ➔ Apache Cassandra ◆ Objeto explodido ◆ Mais de 80 colunas sem serialização
  35. 35. US$ 10.825,00/mês Vazão de leitura = ~ 12.000/s PRÉ MIGRAÇÃO Custo total da solução Resultados DynamoDB + SQL
  36. 36. Resultados US$ 2.580,00/mês Vazão de leitura = ~ 200.000/s PÓS MIGRAÇÃO (8 nós c3.2xlarge) 77% DE ECONOMIA 17x Vazão Custo total da nova solução
  37. 37. Lições Aprendidas O que deu errado
  38. 38. COLLECTIONS
  39. 39. Introdução a collections map<type1, type2> set<type1> list<type1> Problema com tombstones http://bit.ly/cassandra-tombstones
  40. 40. Introdução a atualização de dados no Cassandra sstables tombstones repair
  41. 41. Número de sstables antes do repair # de arquivos sstable Horário
  42. 42. Durante o repair Horário # de arquivos sstable
  43. 43. Alteração do tipo de dados Usando Collections Usando blob cqlsh:test> CREATE TABLE teste_com_mapa( ... id int, ... mapa map<text, text> , ... PRIMARY KEY (id) ); cqlsh:test> CREATE TABLE teste_sem_mapa( ... id int, ... mapa blob, ... PRIMARY KEY (id) );
  44. 44. Repair usando blob ao invés de map Horário # de arquivos sstable
  45. 45. MANUTENÇÃO DO CLUSTER
  46. 46. Sobre adição de nós (Cassandra v2.1) PARA NÃO PERDER DADOS: 1. Não adicionar em paralelo (ESPERAR BALANCEAR) 2. Rodar repair a cada adição 3. Consulte o procedimento no manual.
  47. 47. Quando esquecemos de rodar repair Horário Tempo de resposta para leitura (ms)
  48. 48. Lembre-se sempre... AUTOMATIZAR MONITORAR
  49. 49. HINTED HANDOFF
  50. 50. Hinted Handoff http://bit.ly/cassandra-hinted-handoff
  51. 51. Hinted Handoff ERROR [HintedHandoff:1] 2015-08-31 18:31:55,600 CassandraDaemon.java:182 - Exception in thread Thread [HintedHandoff:1,1,main] java.lang.IndexOutOfBoundsException: null at java.nio.Buffer.checkIndex(Buffer.java:538) ~[na:1.7.0_79] at java.nio.HeapByteBuffer.getLong(HeapByteBuffer.java:410) ~[na:1.7.0_79] at org.apache.cassandra.utils.UUIDGen.getUUID(UUIDGen.java:106) ~[apache-cassandra-2.2.0.jar:2.2.0] at org.apache.cassandra.db.HintedHandOffManager.scheduleAllDeliveries(HintedHandOffManager.java:515) ~[apache-cassandra-2.2.0.jar:2.2.0] at org.apache.cassandra.db.HintedHandOffManager.access$000(HintedHandOffManager.java:88) ~[apache- cassandra-2.2.0.jar:2.2.0] at org.apache.cassandra.db.HintedHandOffManager$1.run(HintedHandOffManager.java:168) ~[apache- cassandra-2.2.0.jar:2.2.0] at org.apache.cassandra.concurrent.DebuggableScheduledThreadPoolExecutor$UncomplainingRunnable.run (DebuggableScheduledThreadPoolExecutor.java:118) ~[apache-cassandra-2.2.0.jar:2.2.0] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [na:1.7.0_79] at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304) [na:1.7.0_79] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThread) CASSANDRA-10233 - IndexOutOfBoundsException in HintedHandOffManager CASSANDRA-10485 - Missing host ID on hinted handoff write
  52. 52. Hinted Handoff cqlsh:system> SELECT target_id,hint_id,message_version FROM hints LIMIT 5; target_id | hint_id | msg_version --------------------------------------+--------------------------------------+------------ | 2f5e0320-62d3-11e5-877e-77558ae77cc8 | 8 72888e32-dae5-41cd-a033-3c5871a3e045 | fad152f0-662a-11e5-89ed-77558ae77cc8 | 8 72888e32-dae5-41cd-a033-3c5871a3e045 | fad152f1-662a-11e5-89ed-77558ae77ac9 | 8 72888e32-dae5-41cd-a033-3c5871a3e045 | fb69e970-662a-11e5-89ed-77558ae77cd5 | 8 52868e32-dae5-41cd-b033-2b5871a3e032 | fb69e971-662a-11e5-89ed-77558ae77zc6 | 8 (5 rows)
  53. 53. Hinted Handoff - POSSÍVEIS CAUSAS - # enable assertions. disabling this in production will give a modest performance benefit (around 5%). JVM_OPTS="$JVM_OPTS -ea" Problemas de bootstrap na adição de novos nós ao cluster
  54. 54. Hinted Handoff Correção de Emergência Executar operação de 'truncate' na tabela de hints Atualizar para versão >= 2.1.11 A versão 3.x não foi afetada pelo problema, pois a nova StorageEngine armazena os hints em arquivos e não mais na estrutura de uma tabela do Cassandra.
  55. 55. ULTRA WIDE ROW (ANTI-PATTERN)
  56. 56. CREATE TABLE idx_config ( conf_id int, ref_id varchar, subs_key varchar, data varchar, last_charge timestamp, expiration timestamp, last_charge_at timestamp, status_id int, origin_id int, msg_balance int, master boolean, enabled boolean, PRIMARY KEY ((conf_id, ref_id), subs_key) ); Estrutura de dados utilizada (CQL) Chave primária Dados da assinatura desnormalizados Chave de partição
  57. 57. Limites Lógicos
  58. 58. Cassandra 1.2 ERROR [CompactionExecutor:6523] 2015-10-09 12:33:23,551 CassandraDaemon.java (line 191) Exception in thread Thread[CompactionExecutor:6523,1,main] java.lang.AssertionError: incorrect row data size3758096384 written to /movile/cassandra-data/SBSPlatform/idx_config/SBSPlatform-idx_config-tmp-ic-715-Data. db; at org.apache.cassandra.io.sstable.SSTableWriter.append(SSTableWriter.java:162) at org.apache.cassandra.db.compaction.CompactionTask.runWith(CompactionTask.java: 162) at org.apache.cassandra.io.util.DiskAwareRunnable.runMayThrow(DiskAwareRunnable. java:48) at org.apache.cassandra.utils.WrappedRunnable.run(WrappedRunnable.java:28) +3GB em 1 linha
  59. 59. Limites Físicos de Partição Cassandra 2.0 ou Anterior ● ~ 100MB ou menos / partição; ● ~ 100k valores (colunas na linha). Cassandra 2.1+ ● Algumas centenas de MB por partição; ● Milhões de valores (colunas por partição).
  60. 60. DS220 Data Modeling Datastax Academy GRATUITO http://bit.ly/cassandra-ds220
  61. 61. CLIENT SIDE JOINS (ANTI-PATTERN)
  62. 62. Modelo v1 Cópia do modelo relacional
  63. 63. Modelo v1 Client Side Joins
  64. 64. Modelo v2 Desnormalização
  65. 65. NÃO COMETA OS MESMOS ERROS
  66. 66. ❏ Evitar Collections do Cassandra; ❏ Adição de nós em paralelo; ❏ Problemas no HintedHandOff; ❏ Client Side Joins (anti-pattern) - Copiar banco relacional; ❏ Ultra wide row (anti-pattern); ❏ Não verificar limites da ferramenta (lógicos e físicos). O que não fazer
  67. 67. E isso é tudo, pessoal!
  68. 68. MUITO OBRIGADO! eitikimura eiti-kimura-movile eiti.kimura@movile.com fhsgoncalves fhsgoncalves fernando.goncalves@movile.com Design by Tiago Cardoso, thanks
  69. 69. Links de Referência: Al Tobey Cassandra 2.1 Tuning Guide https://tobert.github.io/pages/als-cassandra-21-tuning-guide.html Academia Datastax: Modelagem de dados https://academy.datastax.com/courses/ds220-data-modeling Cassandra, lists, and tombstones http://bit.ly/1MwGuGT How to drop and recreate a table in Cassandra versions older than 2.1 http://bit.ly/1R481LO

×