H2 é um banco de dados único com uma boa reputação em relação ao desempenho. Outros bancos de dados são multiencadeados.
Minha pergunta é: quando um banco de dados multithread se torna mais interessante que um banco de dados single thread? Quantos usuários? Quantos processos? Qual é o gatilho? Alguém tem experiência para compartilhar?
Sumário
- O gargalo usual é o acesso ao disco
- Os SSDs são rápidos, mas frágeis (o procedimento de falha é obrigatório)
- Uma consulta longa em um sistema de thread único bloqueará todas as outras
- Configurar o sistema multi-threading pode ser complicado
- Bancos de dados multithread são benéficos mesmo em sistemas de núcleo único
performance
database-recommendation
Jérôme Verstrynge
fonte
fonte
Respostas:
Aqui está a minha opinião:
Geralmente, o gargalo (ou a parte mais lenta) de um sistema de banco de dados é o disco. A CPU apenas dispara durante operações aritméticas, processamento ou qualquer outra tarefa que a CPU realiza. Com arquitetura adequada, o multithreading pode ajudar a compensar a carga de uma consulta na CPU, em vez de fazer leituras / gravações lentas no disco. Há casos em que é mais rápido calcular um valor usando os ciclos da CPU do que criar uma coluna computada (que foi salva anteriormente no disco) e ler essa coluna do disco.
Em alguns RDBMS, há um banco de dados temporário (tempdb) usado por todos os bancos de dados nessa instância para classificação, hash, variáveis temporárias, etc ... A multithreading e a divisão desses arquivos tempdb podem ser usadas para melhorar a taxa de transferência do tempdb , melhorando assim o desempenho geral do servidor.
Usando multithreading (paralelismo), o conjunto de resultados de uma consulta pode ser dividido para ser processado nos diferentes núcleos do servidor, em vez de usar apenas um núcleo. Esse recurso nem sempre melhora o desempenho, mas há casos em que o faz e, portanto, o recurso está disponível.
Os threads disponíveis para o banco de dados são usados para vários propósitos: leitura / gravação em disco, conexões do usuário, trabalhos em segundo plano, bloqueio / trava, E / S de rede, etc ... Dependendo da arquitetura do sistema operacional, os threads são alimentados preventivamente na CPU e são gerenciado usando esperas e filas. Se a CPU puder processar esses threads rapidamente, os tempos de espera serão baixos. Um banco de dados multiencadeado será mais rápido que um banco de dados único, pois em um banco de dados único haverá a sobrecarga de reciclar apenas um segmento, em vez de ter outros passos disponíveis.
A escalabilidade também se torna um problema, pois mais threads serão necessários para gerenciar e executar o sistema de banco de dados em escala.
fonte
multithreaded
nesse contexto significa algo diferente , ou seja, que todas as transações são serializadas como Lucas menciona em sua resposta.Se há algo que posso dizer sobre o MySQL é que o InnoDB, seu mecanismo de armazenamento transacional (compatível com ACID), é de fato multithread. No entanto, é tão multithread quanto VOCÊ CONFIGURA !!! Mesmo "pronto para uso", o InnoDB tem um ótimo desempenho em um único ambiente de CPU, devido às configurações padrão. Para tirar proveito dos recursos de multithreading do InnoDB, lembre-se de ativar várias opções.
innodb_thread_concurrency define o limite superior do número de threads simultâneos que o InnoDB pode manter aberto. O melhor número de rodada definido para isso é (2 X Número de CPUs) + Número de Discos. ATUALIZAÇÃO : Como aprendi em primeira mão com a conferência Percona NYC, você deve definir isso como 0 para alertar o InnoDB Storage Engine para encontrar o melhor número de threads para o ambiente em que está executando.
innodb_concurrency_tickets define o número de encadeamentos que podem ignorar a verificação de simultaneidade com impunidade. Depois que esse limite é atingido, a verificação de simultaneidade de encadeamento se torna a norma novamente.
innodb_commit_concurrency define o número de transações simultâneas que podem ser confirmadas. Como o padrão é 0, não definir isso permite que qualquer número de transações seja confirmado simultaneamente.
innodb_thread_sleep_delay define o número de milissegundos que um encadeamento do InnoDB pode estar inativo antes de entrar novamente na fila do InnoDB. O padrão é 10000 (10 s).
innodb_read_io_threads e innodb_write_io_threads (ambos desde o MySQL 5.1.38) alocam o número especificado de threads para leituras e gravações. O padrão é 4 e o máximo é 64.
innodb_replication_delay impõe o atraso do encadeamento em um escravo quando innodb_thread_concurrency for atingido.
innodb_read_ahead_threshold permite leituras lineares do número definido de extensões (64 páginas [página = 16K]) antes de mudar para leitura assíncrona.
O tempo me escaparia se eu nomeasse mais opções. Você pode ler sobre eles na documentação do MySQL .
A maioria das pessoas desconhece esses recursos e está bastante satisfeita com o InnoDB apenas realizando transações compatíveis com ACID. Se você ajustar alguma dessas opções, fá-lo por sua própria conta e risco.
Eu joguei com várias instâncias de buffer pool do MySQL 5.5 (162 GB em 9 instâncias de buffer pools) e tentei particionar os dados automaticamente na memória dessa maneira. Alguns especialistas dizem que isso deve oferecer 50% de melhoria no desempenho. O que consegui foi uma tonelada de bloqueio de threads que realmente fez o InnoDB rastrear. Eu mudei para 1 buffer (162GB) e tudo estava bem novamente no mundo. Acho que você precisa de especialistas da Percona à sua disposição para definir isso. Estarei na Conferência MySQL da Percona em Nova York amanhã e perguntarei sobre isso se a oportunidade se oferecer.
Em conclusão, o InnoDB se comporta bem agora em um servidor com várias CPUs, considerando suas configurações padrão para operações multithread. Ajustá-los exige muito cuidado, muita paciência, ótima documentação e ótimo café (ou Red Bull, Jolt, etc.).
Bom dia, boa noite e boa noite !!!
ATUALIZAÇÃO 27-05-2011 20:11
Voltei da conferência Percona MySQL em Nova York na quinta-feira. Que conferência. Aprendi bastante, mas recebi uma resposta sobre o InnoDB. Fui informado por Ronald Bradford que definir innodb_thread_concurrency como 0 permitirá ao InnoDB decidir o melhor curso de ação internamente com simultaneidade de thread. Vou experimentar isso ainda mais no MySQL 5.5.
UPDATE 2011-06-01 11:20
No que diz respeito a uma longa consulta, o InnoDB é compatível com ACID e funciona muito bem usando o MultiVersion Concurrency Control . As transações devem ser capazes de transportar níveis de isolamento (leituras repetíveis por padrão) que impedem que outras pessoas acessem dados.
Quanto aos sistemas com vários núcleos, o InnoDB percorreu um longo caminho. No passado, o InnoDB não apresentava bom desempenho em um ambiente multicore. Lembro-me de ter que executar várias instâncias mysql em um único servidor para obter os múltiplos núcleos para distribuir os vários processos mysqld pelas CPUs. Isso não é mais necessário, graças à Percona e, mais tarde, ao MySQL (eh, Oracle, dizendo que isso ainda me deixa louco), pois eles desenvolveram o InnoDB em um mecanismo de armazenamento mais maduro que pode acessar os núcleos com simplicidade sem muito ajuste. A instância atual do InnoDB hoje pode operar bem em um único servidor núcleo.
fonte
Assim que você tiver vários usuários ou processos simultâneos, ou mesmo um único processo com acesso a banco de dados multiencadeado, ter um banco de dados que suporte o encadeamento se tornará potencialmente interessante.
O H2 é seguro para threads, mas serializa todas as solicitações no banco de dados, o que pode se tornar um possível problema de desempenho em um cenário de carga pesada. Se esse é realmente o caso de um projeto específico, depende de uma combinação de seus requisitos de desempenho, do número de threads / usuários / processos que acessam o banco de dados, da frequência de consultas executadas por esses threads e do desempenho médio e do pior caso possível. consultas.
Por exemplo, se seus requisitos de desempenho tiverem uma resposta em um segundo, você não terá mais de 10 usuários simultâneos executando uma única consulta que leva 0,05 segundos para executar, um banco de dados de thread único ainda permitirá que você atinja esses objetivos (embora com vários threads) provavelmente já daria um aumento notável no desempenho). Dado o mesmo cenário com uma única consulta em potencial e com o pior desempenho de meio segundo, serializar o acesso ao banco de dados não permitirá mais que você atinja suas metas de desempenho.
Se você estiver usando H2 no seu projeto, recomendamos que você execute um criador de perfil na sua base de código em um cenário de carregamento (apenas inicie um número x de threads que atingem seu código simultaneamente usando algumas casos de uso típicos). Isso fornecerá métricas reais sobre o desempenho e gargalos na sua base de código, em vez de apenas teorizar. Se isso mostra suas solicitações gastando uma grande porcentagem de seu tempo apenas aguardando para acessar o banco de dados, é hora de mudar para um banco de dados encadeado.
fonte
Pelo que posso dizer, "single-threaded" é um pouco impróprio para H2. O ponto é que ela serializa todas as transações (isto é, faz uma de cada vez).
A questão crucial sobre se isso é "ok" ou não para o seu aplicativo não é "Quantos usuários?" ou até "Quantos processos?", mas "Quanto tempo minhas transações levarão?"
Se todas as suas transações forem de menos de um segundo, isso pode ser bom, se algumas levarem várias horas para serem concluídas, isso pode não ser bom, pois todas as outras transações pendentes aguardam a conclusão. A decisão sobre se isso é "bom" ou não dependerá de seus próprios requisitos de desempenho - ou seja, quanto tempo é uma espera aceitável para que meus usuários acessem o banco de dados com transações.
--EDITAR
Parece que o H2 realmente não serializa transações - apenas DML. Em outras palavras, muitas atualizações curtas em uma única transação longa não bloquearão outras atualizações . No entanto, a menos que você esteja usando o recurso MVCC experimental , o bloqueio de tabela significa que isso tem um efeito semelhante na prática. Há também um recurso experimental "multi_threaded", mas não pode ser usado ao mesmo tempo que o MVCC
fonte
Citando partes do site do PostgreSQL ... Observe que não tenho absolutamente nenhuma idéia dos méritos desses argumentos - eles simplesmente não se encaixam em um comentário.
Nas Perguntas frequentes do desenvolvedor ("Por que os threads não são usados ..."):
http://wiki.postgresql.org/wiki/Developer_FAQ#Why_don.27t_you_use_threads.2C_raw_devices.2C_async-I.2FO.2C_.3Cinsert_your_favorite_wizz-bang_feature_here.3E.3F
Na lista Todo ("Recursos que não queremos"):
http://wiki.postgresql.org/wiki/Todo#Features_We_Do_Not_Want
Então, novamente ... eu não tenho absolutamente nenhuma idéia dos méritos acima. Foi apenas muito tempo para caber em um comentário.
fonte
Um banco de dados multithread só beneficiará você quando você tiver mais de uma consulta paralela no banco de dados. Depende do número de usuários que você possui. Se você tiver mais de dez usuários trabalhando no aplicativo ao mesmo tempo, provavelmente eles produzirão mais de uma consulta no banco de dados ao mesmo tempo.
Além disso, um banco de dados multithread só pode se beneficiar quando houver vários núcleos na CPU. Se houver um núcleo único, o banco de dados multiencadeado precisará enfileirar o trabalho e executá-los sequencialmente no núcleo único. Quando há vários núcleos, cada núcleo pode executar um thread em paralelo. Assim, melhor desempenho.
Isso responde à sua consulta?
fonte