Compações remotas no RocksDB-Cloud

(Hieu Pham) (10 de junho , 2020)

Introdução

RocksDB é um mecanismo de armazenamento LSM cujo crescimento proliferou tremendamente nos últimos anos . RocksDB-Cloud é de código aberto e é totalmente compatível com RocksDB, com o recurso adicional de que todos os dados se tornam duráveis, armazenando-os automaticamente em armazenamento em nuvem (por exemplo, Amazon S3).

Nós, da Rockset, usamos RocksDB-Cloud como um dos blocos de construção do Índice Convergente distribuído da Rockset. O Rockset é projetado com princípios nativos da nuvem e um dos princípios de design primários de um banco de dados nativo da nuvem é separar a computação do armazenamento. Discutiremos como estendemos o RocksDB-Cloud para ter uma separação clara de suas necessidades de armazenamento e de computação.

Um compactador, operado pela US Navy Seabees, realizando compactação do solo

Motor LSM do RocksDB

RocksDB-Cloud armazena dados em SSD ou discos giratórios conectados localmente. O SSD ou o disco giratório fornece o armazenamento necessário para armazenar os dados que serve. Novas gravações em RocksDB-Cloud são gravadas em uma memtable na memória e, quando a memtable está cheia, é liberada para um novo arquivo SST no armazenamento.

Sendo um mecanismo de armazenamento LSM, um conjunto de threads de fundo são usados ​​para compactação, e compactação é um processo de combinação de um conjunto de arquivos SST e geração de novos arquivos SST com chaves sobrescritas e chaves excluídas eliminadas dos arquivos de saída. A compactação precisa de muitos recursos de computação. Quanto mais alta a taxa de gravação no banco de dados, mais recursos de computação são necessários para a compactação, porque o sistema é estável apenas se a compactação for capaz de acompanhar as novas gravações em seu banco de dados.

O problema quando a computação e o armazenamento não são desagregados

Em um típico Sistema baseado em RocksDB, a compactação ocorre em CPUs que são locais no servidor que hospeda o armazenamento também. Nesse caso, computação e armazenamento não são desagregados. E isso significa que, se sua taxa de gravação aumentar, mas o tamanho total do seu banco de dados permanecer o mesmo, você terá que provisionar dinamicamente mais servidores, espalhar seus dados em todos esses servidores e, em seguida, aproveitar a computação adicional nesses servidores para acompanhar o carga de compactação.

Isso tem dois problemas:

  • Espalhar seus dados em mais servidores não é instantâneo porque você precisa copiar muitos dados para fazer isso. Isso significa que você não pode reagir rapidamente a uma carga de trabalho que muda rapidamente.
  • A utilização da capacidade de armazenamento em cada um de seus servidores torna-se muito baixa porque você está distribuindo seus dados para mais servidores. Você perde a relação preço-desempenho por causa de todo o armazenamento não utilizado em seus servidores.

Nossa solução

A principal razão pela qual o RocksDB-Cloud é adequado para separar computação de compactação e armazenamento é porque é um mecanismo de armazenamento LSM. Ao contrário de um banco de dados B-Tree, RocksDB-Cloud nunca atualiza um arquivo SST depois de criado. Isso significa que todos os arquivos SST em todo o sistema são somente leitura, exceto a parte minúscula dos dados em sua tabela de memória ativa. RocksDB-Cloud mantém todos os arquivos SST em um armazenamento de objeto de armazenamento em nuvem como S3, e esses objetos em nuvem são acessíveis com segurança de todos os seus servidores porque são somente leitura.

Então, nossa ideia é que se um RocksDB -O servidor A nuvem pode encapsular um trabalho de compactação com seu conjunto de objetos em nuvem e, em seguida, enviar a solicitação para um servidor sem estado remoto B- e esse servidor B pode buscar os objetos relevantes do armazenamento em nuvem, fazer a compactação, produzir um conjunto de saída Os arquivos SST que são gravados de volta no armazenamento de objeto em nuvem e, em seguida, comunicam essa informação de volta ao servidor A – essencialmente separamos o armazenamento (que reside no servidor A) da computação de compactação (que reside no servidor B). O servidor A tem o armazenamento, enquanto o servidor B não tem armazenamento permanente, mas apenas o cálculo necessário para a compactação. Voila!

API de compactação conectável RocksDB

Estendemos a API base do RocksDB com dois novos métodos que tornam o mecanismo de compactação no RocksDB externamente plugável. Em db.h , apresentamos uma nova API para registrar um serviço de compactação.

Status RegisterPluggableCompactionService(std::unique_ptr);

Esta API registra o plugin que é usado para executar o trabalho de compactação pelo RocksDB. A compactação remota ocorre em duas etapas: Run e InstallFiles. Portanto, o plug-in, PluggableCompactionService , teria 2 APIs:

Status Run(const PluggableCompactionParam& job, PluggableCompactionResult* result) std::vector InstallFiles(
const std::vector& remote_paths,
const std::vector& local_paths,
const EnvOptions& env_options, Env* local_env)

Run é onde ocorre a execução da compactação.Em nossa arquitetura de compactação remota, Run enviaria um RPC para uma camada de compactação remota e receberia um resultado de compactação que tem, entre outras coisas, a lista de arquivos SST compactados recentemente.

InstallFiles é onde o RocksDB instala os arquivos SST recém-compactados da nuvem (remote_paths) em seu banco de dados local (local_paths).

Camada de compactação do Rockset

Agora vamos mostrar como usamos o serviço de compactação plugável descrito acima no serviço de compactação do Rockset. Conforme mencionado acima, a primeira etapa, Run, envia um RPC para uma camada de compactação remota com informações de compactação, como nomes de arquivo SST de entrada e informações de compactação. Chamamos o host que executa este trabalho de compactação de compactor.

O compactador , ao receber a solicitação de compactação, abriria uma instância do RocksDB-Cloud em modo fantasma . O que isso significa é que o RocksDB-Cloud abre o banco de dados local apenas com os metadados necessários, sem buscar todos os arquivos SST do armazenamento em nuvem. Depois de abrir a instância do RocksDB no modo fantasma , ele executaria o trabalho de compactação, incluindo a busca dos arquivos SST necessários, compactá-los e carregar os arquivos SST recém-compactados para um armazenamento temporário na nuvem.

Aqui estão as opções para abrir o RocksDB-Cloud no compactador :

rocksdb::CloudOptions cloud_options; cloud_options.ephemeral_resync_on_open = false; cloud_options.constant_sst_file_size_in_sst_file_manager = 1024; cloud_options.skip_cloud_files_in_getchildren = true;rocksdb::Options rocksdb_options;
rocksdb_options.max_open_files = 0; rocksdb_options.disable_auto_compactions = true; rocksdb_options.skip_stats_update_on_db_open = true; rocksdb_options.paranoid_checks = false; rocksdb_options.compaction_readahead_size = 10 * 1024 * 1024;

Existem vários desafios que enfrentamos durante o desenvolvimento da camada de compactação e nossas soluções:

Melhore a velocidade de abertura do RocksDB-Cloud em fantasma modo

Durante a abertura de instâncias do RocksDB, além de buscar todos os arquivos SST da nuvem (que desativamos com fantasma modo), existem várias outras operações que podem retardar o processo de abertura, principalmente obter a lista de arquivos SST e obter o tamanho de cada arquivo SST. Normalmente, se todos os arquivos SST residirem no armazenamento local, a latência dessas operações get-file-size seria pequena. No entanto, quando o compactador abre o RocksDB-Cloud, cada uma dessas operações resultaria em uma solicitação remota para o armazenamento em nuvem, e a latência combinada total se tornaria proibitivamente cara. Em nossa experiência, para uma instância do RocksDB-Cloud com milhares de arquivos SST, abri-la levaria até um minuto devido a milhares de solicitações get-file-size para S3. Para contornar essa limitação, introduzimos várias opções nas opções do RocksDB-Cloud para desativar esses RPCs durante a abertura. Como resultado, o tempo médio de abertura vai de 7 segundos a 700 milissegundos.

Desativar L0 -> compactação L0

A compactação remota é uma compensação entre a velocidade de uma única compactação e a capacidade de executar mais trabalhos de compactação em paralelo. É porque, naturalmente, cada trabalho de compactação remota seria mais lento do que a mesma compactação executada localmente devido ao custo de transferência de dados na nuvem. Portanto, gostaríamos de minimizar o gargalo do processo de compactação, onde RocksDB-Cloud não pode paralelizar, tanto quanto possível.

Na arquitetura LSM, a compactação L0-> L1 geralmente não é paralelizável porque Os arquivos L0 têm intervalos sobrepostos. Portanto, quando uma compactação L0-> L1 está ocorrendo, o RocksDB-Cloud tem a capacidade de também executar a compactação L0-> L0, com o objetivo de reduzir o número de arquivos L0 e evitar paradas de gravação devido ao RocksDB-Cloud atingir o arquivo L0 limite. No entanto, a desvantagem é que cada arquivo L0 ficaria maior em tamanho após cada compactação L0-> L0.

Em nossa experiência, esta opção causa mais problemas do que os benefícios que traz, porque ter arquivos L0 maiores resulta em uma compactação L0-> L1 muito mais longa, piorando o gargalo do RocksDB-Cloud. Conseqüentemente, desabilitamos a compactação L0-> L0 e vivemos com o raro problema de perda de gravação. De nosso experimento, a compactação do RocksDB-Cloud acompanha as gravações de entrada muito melhor.

Você pode usá-lo agora

O RocksDB-Cloud é um projeto de código aberto, então nosso trabalho pode ser aproveitado por qualquer outro desenvolvedor de RocksDB que deseja obter benefícios separando sua computação de compactação de suas necessidades de armazenamento. Estamos executando o serviço de compactação remota em produção agora. Ele está disponível com a versão 6.7.3 do RocksDB-Cloud. Discutimos tudo sobre o RocksDB-Cloud no canal público do Slack em http://bit.ly/rockset-community-channel .

Autores:

Hieu Pham – Engenheiro de Software, Rockset
Dhruba Borthakur – CTO, Rockset

Originalmente publicado em https: // rockset.com em 4 de junho de 2020.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *