No domínio das bases de dados distribuídas, o Apache Cassandra destaca-se como um ator importante. Ele oferece uma combinação de escalabilidade robusta e alta disponibilidade sem comprometer o desempenho. No entanto, o Cassandra também é conhecido por ser difícil de ajustar o desempenho e pelas armadilhas que podem surgir durante esse processo. A flexibilidade expansiva do sistema, embora seja um ponto forte, também significa que o aproveitamento efetivo de todas as suas capacidades envolve muitas vezes a navegação num labirinto complexo de configurações e compromissos de desempenho. Se não for cuidadosamente gerida, esta complexidade pode, por vezes, conduzir a comportamentos inesperados ou a um desempenho abaixo do ideal.
Nesta publicação do blogue, percorremos a jornada de otimização do Cassandra da DoorDash. Compartilharei o que aprendemos ao tornar nossa frota muito mais eficiente e econômica. Ao analisar nossos casos de uso, esperamos compartilhar lições universais que possam ser úteis. Antes de mergulharmos nesses detalhes, vamos falar brevemente sobre os conceitos básicos do Cassandra e seus prós e contras como um banco de dados NoSQL distribuído.
O que é o Apache Cassandra?
O Apache Cassandra é um sistema de gestão de bases de dados NoSQL distribuído e de código aberto, concebido para tratar grandes quantidades de dados numa vasta gama de servidores de base. Oferece alta disponibilidade sem um único ponto de falha. Fortemente inspirado no DynamoDB de 2007 da Amazon, o Facebook desenvolveu o Cassandra para alimentar a sua funcionalidade de pesquisa na caixa de entrada e, mais tarde, abriu o seu código fonte. Desde então, tornou-se um dos armazenamentos de valores-chave distribuídos preferidos.
Cassandra pros
- Escalabilidade: Uma das características mais atraentes do Cassandra é a sua excecional escalabilidade. É excelente na escalabilidade horizontal e vertical, o que lhe permite gerir grandes volumes de dados sem esforço.
- Tolerância a falhas: O Cassandra oferece uma excelente tolerância a falhas através da sua arquitetura distribuída. Os dados são replicados em vários nós, garantindo que não haja um único ponto de falha.
- Alta disponibilidade: Com a sua estratégia de replicação e natureza descentralizada, o Cassandra garante uma elevada disponibilidade, tornando-o uma escolha fiável para aplicações críticas.
- Flexibilidade: O Cassandra suporta um design de esquema flexível, o que é uma vantagem para as aplicações com estruturas de dados em evolução.
- Eficiência de escrita: O Cassandra está optimizado para um elevado rendimento de escrita, lidando com grandes volumes de escrita sem problemas.
Cassandra contras
- Desempenho de leitura: Embora o Cassandra seja excelente em termos de eficiência de escrita, o seu desempenho de leitura pode ser menos impressionante, especialmente em cenários que envolvem grandes conjuntos de dados com leituras frequentes com elevadas restrições de consistência.
- Modificação de dados dispendiosa: Uma vez que o Cassandra é uma árvore de fusão estruturada em registo em que os dados escritos são imutáveis, a eliminação e as actualizações são dispendiosas. Especialmente no caso das eliminações, pode gerar "pedras tumulares" que afectam o desempenho. Se a sua carga de trabalho for muito pesada em termos de eliminação e atualização, uma arquitetura apenas Cassandra poderá não ser a melhor escolha.
- Complexidade na afinação: Ajustar o Cassandra para obter um desempenho ótimo requer um conhecimento profundo dos seus mecanismos internos, o que pode ser complexo e demorado.
- Compromisso de consistência: De acordo com o teorema CAP, o Cassandra troca frequentemente a consistência pela disponibilidade e tolerância de partição, o que pode não se adequar a todos os casos de utilização.
As nuances de Cassandra
As nuances em torno da aplicação do Cassandra tornam-se evidentes quando se ponderam os seus benefícios em relação aos requisitos de casos de utilização específicos. Embora a sua escalabilidade e fiabilidade sejam incomparáveis para aplicações de escrita intensiva, é necessário considerar a natureza dos dados do projeto e os padrões de acesso. Por exemplo, se a sua aplicação requer capacidades de consulta complexas, sistemas como o MongoDB podem ser mais adequados. Por outro lado, se a consistência forte for um requisito crítico, o CockroachDB pode ser mais adequado.
Em nossa jornada na DoorDash, navegamos por essas áreas cinzentas avaliando cuidadosamente nossas necessidades e alinhando-as com os recursos do Cassandra. Reconhecemos que, embora nenhum sistema seja uma solução única para todos, com um ajuste meticuloso e a compreensão do potencial do Cassandra, ele poderia ser maximizado para atender e até mesmo superar nossas expectativas. As secções seguintes analisam a forma como abordámos a afinação do Cassandra - atenuando os seus contras e tirando partido dos seus prós - para o adaptar eficazmente aos nossos casos de utilização intensiva de dados.
Mantenha-se informado com as actualizações semanais
Subscreva o nosso blogue de Engenharia para receber actualizações regulares sobre todos os projectos mais interessantes em que a nossa equipa está a trabalhar
Please enter a valid email address.
Obrigado por subscrever!
Atrever-se a melhorar
Devido ao rápido crescimento da DoorDash, a nossa utilização do Cassandra expandiu-se rapidamente. Apesar de aumentar a nossa velocidade de desenvolvimento, este rápido crescimento deixou um rasto de oportunidades perdidas para afinar o desempenho do Cassandra. Numa tentativa de aproveitar algumas dessas oportunidades, a equipa de Armazenamento de Infra-estruturas trabalhou em estreita colaboração com as equipas de produto num esforço de afinação que durou meses. O projeto produziu alguns resultados surpreendentes, incluindo:
- ~35% de redução de custos para toda a frota Cassandra
- Por cada 1 dólar que gastamos, conseguimos processar 59 KB de dados por segundo contra 23 KB, o que representa uma melhoria de 154% na economia da unidade
Na secção seguinte, exploraremos exemplos específicos da nossa frota que podem ser aplicáveis a outros casos de utilização.
Conceba o seu esquema de forma sensata desde o início
O passo fundamental para garantir um cluster Cassandra optimizado é ter um esquema bem concebido. As escolhas de design efectuadas ao nível do esquema têm implicações de longo alcance no desempenho, escalabilidade e manutenção. Um esquema mal concebido no Cassandra pode levar a problemas como consultas ineficientes, pontos de acesso na distribuição de dados e dificuldades de escalonamento. Eis algumas considerações fundamentais para a conceção de um esquema Cassandra eficaz:
- Compreender os padrões de acesso aos dados: Antes de conceber o seu esquema, é crucial ter uma compreensão clara dos padrões de acesso aos dados da sua aplicação. O Cassandra está optimizado para gravações rápidas e leituras eficientes, mas apenas se o modelo de dados estiver alinhado com a forma como os dados serão acedidos. Conceba as suas tabelas em função das suas consultas, e não o contrário.
- Utilização eficaz de chaves primárias: A chave primária no Cassandra é composta por chaves de partição e colunas de clustering. A chave de partição determina a distribuição dos dados pelo cluster, pelo que é essencial escolher uma chave de partição que garanta uma distribuição uniforme dos dados e, ao mesmo tempo, suporte os seus padrões de acesso primário. As colunas de agrupamento determinam a ordem de classificação numa partição e podem ser utilizadas para suportar consultas de intervalo eficientes.
- Evite partições grandes: As partições extremamente grandes podem ser prejudiciais para o desempenho do Cassandra. Podem levar a problemas como longas pausas na recolha de lixo, aumento das latências de leitura e desafios na compactação. Conceba o seu esquema para evitar pontos de acesso e garantir uma distribuição mais uniforme dos dados.
- Normalização vs. desnormalização: Ao contrário dos sistemas tradicionais de gestão de bases de dados relacionais, ou RDBMS, o Cassandra não é excelente a juntar tabelas. Como resultado, a desnormalização é frequentemente necessária. No entanto, é um equilíbrio; embora a desnormalização possa simplificar as consultas e melhorar o desempenho, ela também pode levar à redundância de dados e a maiores requisitos de armazenamento. Considere cuidadosamente seu caso de uso ao decidir o quanto desnormalizar.
- Considerar as implicações dos índices secundários: Os índices secundários no Cassandra podem ser úteis, mas têm desvantagens. Eles podem adicionar sobrecarga e podem nem sempre ser eficientes, especialmente se as colunas indexadas tiverem alta cardinalidade ou se os padrões de consulta não aproveitarem os pontos fortes dos índices secundários.
- TTL e gestão de tombstones: O Time-to-live, ou TTL, é um recurso poderoso do Cassandra para gerenciar a expiração de dados. No entanto, é importante compreender como o TTL e os tombstones resultantes afectam o desempenho. O manuseamento incorreto das pedras tumulares pode levar à degradação do desempenho ao longo do tempo. Se possível, evite exclusões.
- Estratégias de atualização: Compreender como funcionam as actualizações no Cassandra. Como as actualizações são essencialmente operações de escrita, podem levar à criação de várias versões de uma linha que precisam de ser resolvidas em tempo de leitura, o que afecta o desempenho. Projete seus padrões de atualização para minimizar esses impactos. Se possível, evite actualizações.
Escolha criteriosamente o seu nível de consistência
A capacidade do Cassandra de configurar níveis de consistência para operações de leitura e escrita oferece uma ferramenta poderosa para equilibrar a precisão dos dados e o desempenho. No entanto, como acontece com qualquer recurso poderoso, ele vem com uma ressalva: responsabilidade. O nível de consistência escolhido pode afetar significativamente o desempenho, a disponibilidade e a tolerância a falhas do seu cluster Cassandra, incluindo as seguintes áreas:
- Compreender os níveis de consistência: No Cassandra, os níveis de consistência variam de UM (em que a operação requer confirmação de um único nó) a TODOS (em que a operação requer confirmação de todas as réplicas no cluster). Existem também níveis como QUORUM (que requer a maioria dos nós) e LOCAL_QUORUM (uma maioria dentro do centro de dados local). Cada um desses níveis tem suas próprias implicações no desempenho e na precisão dos dados. Pode saber mais sobre esses níveis nas configurações aqui.
- Compromisso entre desempenho e exatidão: Os níveis de consistência mais baixos, como o ONE, podem oferecer um desempenho mais elevado porque requerem menos nós para responder. No entanto, eles também apresentam um risco maior de inconsistência de dados. Os níveis mais elevados, como TODOS, garantem uma consistência forte, mas podem afetar significativamente o desempenho e a disponibilidade, especialmente numa configuração de vários centros de dados.
- Impacto na disponibilidade e tolerância a falhas: Níveis de consistência mais elevados também podem afetar a disponibilidade da sua aplicação. Por exemplo, se utilizar um nível de consistência de TODOS, e mesmo uma réplica estiver em baixo, a operação falhará. Portanto, é importante equilibrar a necessidade de consistência com o potencial de falhas de nós e problemas de rede.
- Ajuste dinâmico com base no caso de utilização: Uma estratégia consiste em ajustar dinamicamente os níveis de consistência com base na criticidade da operação ou no estado atual do cluster. Esta abordagem requer uma lógica de aplicação mais sofisticada, mas pode otimizar o desempenho e a precisão dos dados.
Afine a sua estratégia de compactação (e o filtro bloom)
A compactação é um processo de manutenção no Cassandra que funde várias SSTables, ou tabelas de cadeias ordenadas, numa única. A compactação é executada para recuperar espaço, melhorar o desempenho de leitura, limpar lápides e otimizar a E/S do disco.
Os utilizadores devem escolher entre três estratégias principais para desencadear a compactação nos utilizadores do Cassandra com base nos seus casos de utilização. Cada estratégia é optimizada para coisas diferentes:
- Estratégia de compactação por níveis de dimensão, ou STCS
- Mecanismo de gatilho:
- A estratégia monitoriza o tamanho dos SSTables. Quando um determinado número atinge aproximadamente o mesmo tamanho, o processo de compactação é acionado para esses SSTables. Por exemplo, se o sistema tiver um limiar definido para quatro, quando quatro SSTables atingirem um tamanho semelhante, serão fundidos num só durante o processo de compactação.
- Quando utilizar:
- Cargas de trabalho com uso intensivo de escrita
- Tamanhos consistentes de SSTable
- Prós:
- Amplificação de escrita reduzida
- Bom desempenho na escrita
- Contras:
- Potencial queda no desempenho de leitura devido ao aumento de varreduras de SSTable
- Combina dados mais antigos e mais recentes ao longo do tempo
- É necessário deixar um disco sobresselente muito maior para executar eficazmente esta estratégia de compactação
- Mecanismo de gatilho:
- Estratégia de compactação nivelada, ou LCS
- Mecanismo de gatilho:
- Os dados são organizados em níveis. O nível 0 (L0) é especial e contém os SSTables recentemente descarregados ou compactados. Quando o número de SSTables em L0 ultrapassa um limite específico (por exemplo, 10 SSTables), estes SSTables são compactados com os SSTables no Nível 1 (L1). Quando L1 ultrapassa o seu limite de tamanho, é compactado com L2, e assim por diante.
- Quando utilizar:
- Cargas de trabalho de leitura intensiva
- Necessidade de um desempenho de leitura consistente
- A gestão do espaço em disco é vital
- Prós:
- Desempenho de leitura previsível devido a menos SSTables
- Utilização eficiente do espaço em disco
- Contras:
- Amplificação de escrita aumentada
- Mecanismo de gatilho:
- Estratégia de compactação TimeWindow, ou TWCS
- Mecanismo de gatilho:
- As SSTables são agrupadas com base no carimbo de data/hora dos dados, criando janelas de tempo distintas, como diariamente ou de hora a hora. Quando uma janela de tempo expira - o que significa que passamos para a janela seguinte - os SSTables dentro dessa janela expirada tornam-se candidatos à compactação. Somente os SSTables dentro da mesma janela são compactados juntos, garantindo a localidade temporal dos dados.
- Quando utilizar:
- Dados de séries cronológicas ou dados de ciclos de vida previsíveis
- Expirações baseadas em TTL
- Prós:
- Tratamento eficiente de dados de séries cronológicas
- Amplificação de leitura reduzida para consultas com registo de data e hora
- SSTables mais antigos imutáveis
- Contras:
- Não é adequado para cargas de trabalho não temporais
- Potenciais problemas de espaço se os dados dentro de uma janela temporal forem vastos e variarem significativamente entre janelas
- Mecanismo de gatilho:
Na nossa experiência, a menos que esteja a armazenar estritamente dados de séries temporais com TTL predefinido, o LCS deve ser a sua escolha padrão. Mesmo quando a sua aplicação faz uso intensivo de escrita, o espaço extra em disco exigido por SSTables progressivamente grandes no STCS torna esta estratégia pouco apelativa. O LCS é uma escolha óbvia em casos de uso intensivo de leitura. A Figura 2 abaixo mostra a quantidade de queda no uso do disco após a troca da estratégia de compactação e das limpezas.
É fácil esquecer que cada estratégia de compactação deve ter um tamanho de cache de filtro de floração diferente. Quando alternar entre estratégias de compactação, não se esqueça de ajustar este tamanho de cache em conformidade.
- Configuração padrão do filtro de florescimento do STCS: A configuração padrão do STCS geralmente visa um equilíbrio entre o uso da memória e o desempenho da leitura. Como o STCS pode levar a SSTables maiores, o filtro bloom pode ser configurado como um pouco maior do que o que seria usado no LCS para reduzir a chance de leituras de disco desnecessárias. No entanto, o tamanho exato dependerá da configuração do Cassandra e da carga de trabalho específica.
- Configuração padrão do filtro de florescimento do LCS: Os bloom filters do LCS geralmente são menores porque os SSTables são gerenciados em níveis e cada nível contém dados não sobrepostos. Essa organização reduz a necessidade de filtros de florescimento maiores, pois é menos provável que sejam feitas leituras de disco desnecessárias
- Definição predefinida do filtro bloom do TWCS: Utilizado principalmente para dados de séries temporais, o TWCS envolve normalmente SSTables de vida mais curta devido à natureza da expiração de dados com base no tempo. O tamanho predefinido do filtro bloom para o TWCS pode ser ajustado para refletir a natureza temporal dos dados; é potencialmente mais pequeno devido ao envelhecimento previsível das SSTables.
Como um exemplo específico, mudámos um dos nossos clusters Cassandra em execução na versão 3.11 de STCS para LCS, conforme mostrado na Figura 3 abaixo. No entanto, não aumentámos o tamanho da cache do filtro de floração em conformidade. Como resultado, os nós nesse cluster estavam constantemente a ficar sem memória, ou OOM, devido ao aumento da taxa de falsos positivos para leituras. Depois de aumentar bloom_filter_fp_chance de 0,01 para 0,1, muito mais memória do SO é poupada, eliminando o problema de OOM.
Agrupar ou não agrupar? É uma pergunta difícil
Nas bases de dados relacionais tradicionais, as operações em lote são uma técnica comum para melhorar o desempenho, uma vez que podem reduzir as viagens de ida e volta à rede e simplificar a gestão de transacções. No entanto, quando se trabalha com uma base de dados distribuída como o Cassandra, a abordagem de batching, seja para leituras ou escritas, requer uma consideração cuidadosa devido à sua arquitetura única e aos métodos de distribuição de dados.
Escritas em lote: Os compromissos
O Cassandra, optimizado para uma elevada taxa de transferência de escrita, trata as operações de escrita individuais de forma eficiente nos seus nós distribuídos. Mas as gravações em lote, em vez de melhorarem o desempenho, podem introduzir vários desafios, tais como:
- Aumento da carga nos nós coordenadores: Os grandes lotes podem criar estrangulamentos no nó coordenador, que é responsável pela gestão da distribuição destas operações de escrita.
- Amplificação de escrita: O agrupamento pode levar a que sejam gravados mais dados no disco do que o necessário, sobrecarregando o subsistema de E/S.
- Potencial de latência e falhas: As operações de grandes lotes podem exceder os limites de tempo limite, levando a escritas parciais ou à necessidade de novas tentativas.
Tendo em conta estes factores, consideramos frequentemente mais eficazes os lotes mais pequenos e frequentes ou as gravações individuais, garantindo uma distribuição de carga mais equilibrada e um desempenho consistente.
Leituras em bloco: Uma perspetiva diferente
As leituras em lote no Cassandra, ou operações multi-get, envolvem a obtenção de dados de várias linhas ou partições. Embora pareça eficiente, essa abordagem vem com seu próprio conjunto de complicações:
- Sobrecarga do coordenador e da rede: O nó coordenador tem de efetuar consultas em vários nós, aumentando potencialmente os tempos de resposta.
- Impacto em partições grandes: Grandes leituras em lote podem levar a problemas de desempenho, especialmente a partir de grandes partições.
- Localidade e distribuição de dados: O agrupamento pode perturbar a localidade dos dados, um fator-chave no desempenho do Cassandra, conduzindo a operações mais lentas.
- Risco de hotspots: As leituras em lote distribuídas de forma desigual podem criar hotspots, afectando o equilíbrio da carga em todo o cluster.
Para atenuar estes problemas, pode ser mais benéfico trabalhar com operações de leitura direccionadas que se alinham com os pontos fortes do Cassandra no tratamento de dados distribuídos.
Em nossa jornada no DoorDash, aprendemos que a criação de lotes no Cassandra não segue a sabedoria convencional dos sistemas RDBMS tradicionais. Quer seja para leituras ou gravações, cada operação em lote deve ser cuidadosamente avaliada no contexto da natureza distribuída do Cassandra e das características de tratamento de dados. Ao fazê-lo, conseguimos otimizar a nossa utilização do Cassandra, alcançando um equilíbrio entre desempenho, fiabilidade e eficiência de recursos.
O DataCenter não é para isolamento de consultas
O Cassandra utiliza centros de dados, ou DCs, para suportar a disponibilidade multi-região, um recurso que é crítico para garantir alta disponibilidade e recuperação de desastres. No entanto, há um equívoco comum em relação ao uso de DCs no Cassandra, especialmente entre aqueles que estão fazendo a transição de sistemas RDBMS tradicionais. Pode parecer intuitivo tratar um DC como uma réplica de leitura, semelhante à forma como as réplicas de leitura são usadas no RDBMS para balanceamento de carga e descarregamento de consultas. Mas no Cassandra, esta abordagem precisa de ser cuidadosamente considerada.
Cada DC no Cassandra pode participar na replicação de dados; esta replicação é vital para a resiliência geral do sistema. Embora seja possível designar um DC para cargas de trabalho de leitura pesada - como fizemos na DoorDash com nosso DC somente leitura - essa decisão não é isenta de compensações.
Um aspeto crítico a compreender é o conceito de contrapressão. Na nossa configuração, o DC só de leitura é utilizado apenas para operações de leitura. No entanto, isso não isola completamente o DC principal da carga. Quando o DC somente leitura tem uma carga alta ou outros problemas, ele pode criar uma contrapressão que afeta o DC principal. Isto acontece porque num cluster Cassandra todos os DCs estão interligados e participam no processo geral de integridade do cluster e de replicação de dados.
Por exemplo, se o DC só de leitura for sobrecarregado por consultas pesadas ou más, pode abrandar, levando a um aumento das latências. Estes atrasos podem repercutir-se no DC principal, uma vez que este espera por confirmações ou tenta gerir a consistência da replicação entre DCs. Esses cenários podem levar a uma redução da taxa de transferência e a um aumento da latência em todo o cluster, e não apenas no DC somente leitura.
Num dos nossos clusters Cassandra, utilizámos o seu DC só de leitura para alojar consultas analíticas dispendiosas que, efetivamente, tiram um instantâneo diário das tabelas. Como tratámos o RO DC como complicado e isolado, à medida que o número de tabelas aumentava, as consultas tornavam-se cada vez mais dispendiosas. Eventualmente, o trabalho de análise fez com que o RO DC atingisse 100% todas as noites. Isto também começou a afetar o CD principal. Trabalhando com a equipa de produto, optimizámos drasticamente esses trabalhos em lote e criámos uma melhor forma de tirar o instantâneo. Sem entrar em muitos detalhes, utilizamos o toke range para percorrer aleatoriamente o anel e distribuir a carga entre os clusters. A Figura 4 abaixo mostra a arquitetura aproximada.
O resultado final foi fantástico. O pico de CPU foi eliminado, o que nos permitiu desativar completamente o RO DC. O desempenho do CD principal também beneficiou visivelmente com isto.
Afinação do GC: Por vezes vale a pena
No Cassandra, o GC tuning, ou ajuste da recolha de lixo, é uma tarefa desafiante. Exige uma compreensão profunda dos mecanismos de recolha de lixo dentro da Máquina Virtual Java, ou JVM, bem como a forma como o Cassandra interage com estes sistemas. Apesar de sua complexidade, o ajuste fino do processo de coleta de lixo pode gerar melhorias significativas no desempenho, especialmente em ambientes de alto rendimento como o nosso na DoorDash. Aqui estão algumas considerações comuns:
- Prefira coletas mais frequentes da geração jovem: Na recolha de lixo JVM, os objectos são primeiro alocados na geração jovem, que é normalmente mais pequena e recolhida com mais frequência. Ajustar o Cassandra para favorecer colecções de geração jovem mais frequentes pode ajudar a limpar rapidamente objectos de curta duração, reduzindo o espaço total de memória. Essa abordagem geralmente envolve o ajuste do tamanho da geração jovem e a frequência das coletas para atingir um equilíbrio entre recuperar a memória imediatamente e não sobrecarregar o sistema com muitas pausas de GC.
- Evitar colecções da velha geração: Os objectos que sobrevivem a várias colecções da geração jovem são promovidos para a geração antiga, que é recolhida com menos frequência. As colecções na geração antiga consomem mais recursos e podem levar a tempos de pausa mais longos. Numa base de dados como o Cassandra, onde o desempenho consistente é fundamental, é crucial minimizar as colecções da geração antiga. Isso pode envolver não apenas o ajuste dos tamanhos da geração jovem/antiga, mas também a otimização do uso da memória e das estruturas de dados do Cassandra para reduzir a quantidade de lixo produzido.
- Ajustar o algoritmo do coletor de lixo: Diferentes coletores de lixo têm características diferentes e são adequados a diferentes tipos de cargas de trabalho. Por exemplo, o coletor de lixo G1 é frequentemente uma boa escolha para o Cassandra, uma vez que pode gerir eficientemente grandes heaps com tempos de pausa mínimos. No entanto, a escolha e o ajuste do coletor de lixo devem ser baseados em padrões de carga de trabalho específicos e no comportamento observado no seu ambiente.
- Monitorizar e ajustar com base em métricas: O ajuste eficaz do GC requer monitoramento e ajustes contínuos. As principais métricas a monitorizar incluem tempos de pausa, frequência de recolhas e a taxa de atribuição e promoção de objectos. Ferramentas como o JMX, ferramentas de monitorização da JVM e as próprias métricas do Cassandra podem fornecer informações valiosas sobre o comportamento do GC e o seu impacto no desempenho geral.
- Compreender o impacto na taxa de transferência e na latência: Qualquer ajuste de GC deve considerar seu impacto na taxa de transferência e na latência. Embora um GC mais agressivo possa reduzir o consumo de memória, ele também pode introduzir pausas mais frequentes, afetando a latência. O objetivo é encontrar uma configuração que ofereça um equilíbrio ideal para sua carga de trabalho específica.
Em nossa experiência na DoorDash, descobrimos que o ajuste de GC direcionado, embora complexo, pode ser altamente benéfico. Analisando cuidadosamente nossas cargas de trabalho e ajustando iterativamente nossas configurações de GC, conseguimos reduzir os tempos de pausa e aumentar a taxa de transferência e a confiabilidade geral do sistema. No entanto, vale a pena notar que o ajuste do GC não é uma tarefa única, mas um processo contínuo de observação, ajuste e otimização. A Figura 6 abaixo mostra um exemplo de quando ajustámos o nosso GC para obter um melhor desempenho do P99.
Trabalhos futuros e aplicações
À medida que olhamos para o futuro na DoorDash, a nossa jornada com o Apache Cassandra está a aprofundar-se e a evoluir. Uma das nossas missões contínuas é refinar as optimizações de consulta. Estamos a mergulhar nas nuances dos tamanhos dos lotes e a evitar os antipadrões que prejudicam a eficiência.
Outro desafio remanescente é o desempenho da captura de dados de alteração, ou CDC. A nossa configuração atual com o Debezium, emparelhado com o Cassandra 3, sofre de limitações em termos de latência, fiabilidade e escalabilidade. Estamos a pensar numa transição para o Cassandra 4 e clientes raw, que oferecem melhores capacidades de CDC. Esta mudança não é apenas uma atualização técnica; é um movimento estratégico para desbloquear novos domínios de processamento e integração de dados em tempo real.
A observabilidade no Cassandra é outra fronteira que estamos ansiosos por conquistar. O cenário atual torna difícil discernir os meandros do desempenho das consultas. Para trazer estes aspectos ocultos para a luz, estamos a embarcar numa iniciativa para integrar a nossa própria camada de proxy. Esta adição, embora introduza um salto extra no nosso fluxo de dados, promete uma riqueza de conhecimentos sobre a dinâmica das consultas. É um compromisso calculado, que acreditamos que irá enriquecer a nossa compreensão e controlo sobre as nossas operações de dados.
Agradecimentos
Esta iniciativa não seria um sucesso sem a ajuda dos nossos parceiros, as DRIs dos vários clusters que foram sintonizados, incluindo:
- Equipa de anúncios: Chao Chu, Deepak Shivaram, Michael Kniffen, Erik Zhang e Taige Zhang
- Equipa de encomendas: Cesare Celozzi, Maggie Fang e Abhishek Sharma
- Equipa do público: Edwin Zhang
- Equipa de Menu e Dados: Yibing Shi, Jonathan Brito, Xilu Wang e Santosh Vanga
Agradecemos também a Levon Stepanian por ajudar a rastrear a economia de custos nas taxas de gerenciamento do AWS Infra e da Instaclustr. Por fim, obrigado pelo apoio da equipa de armazenamento mais alargada e dos nossos parceiros Instaclustr.