Desempenho em HDFS para ficheiros pequenos
eu escrevi um pequeno projecto C++ para ler os ficheiros directamente do disco rígido (não de HDFS) para construir a linha de base de desempenho. O programa irá criar 4 threads de leitura para cada disco. O resultado de desempenho é ter cerca de 14MB / s por disco. O débito Total é de cerca de 14MB / s * 5 * 5 = 350MB /s (14MB/s * 5 discos * 5 máquinas ).
no entanto, quando este programa (ainda usando c++, ligado dinamicamente a libhdfs.so, criando 4*5*5 = 100 threads) lê arquivos de HDFS cluster, o débito é apenas 55MB / s.
Se esta programação for despoletado no mapreduce( streamming hadoop, 5 tarefas, cada uma tem 20 threads, o número total de threads ainda é de 100), o rendimento desce para cerca de 45MB/s. (Acho que é mais lento por algum processo de contabilidade).
Pergunto-me qual é o desempenho razoável que os HDFS podem ter. Como você pode ver, comparando com o código nativo, a transferência de dados é apenas sobre 1/7. É o problema da minha confusão? Ou limitação HDFS? Ou limitação Java? Qual é a melhor maneira para o meu cenário? Poder ajuda de sequência de Ficheiros (muito)? Qual é o rendimento razoável comparado com a leitura IO nativo que podemos esperar? Aqui está um pouco da minha configuração.NameNode heap size 32G.
Job/Task node heap size 8G.
Número De Manipuladores De Códigos: 128
Número De Manipuladores De Dados: 8
DataNode Número máximo de tópicos de transferência: 4096
1GBps ethernet.
Obrigado.3 answers
b) sobrecarga de HDFS. Esta sobrecarga está principalmente na latência, não em transferência. HDFS pode ser sintonizado para servir um monte de arquivos em parralel. O HBase está a fazê-lo e podemos tirar definições dos guias de ajuste da HBase. A questão aqui é, na verdade, de quanto Datanodes você precisa
c) a sua LAN. Você move os dados da rede para que você possa atingir o limite de rendimento ethernet 1Gb. (eu acho que é o que você tem.
Eu também tenho que concordar com o Joe - que HDFS não é construído para o cenário e você deve usar outra tecnologia (como HBase, se você gosta de Hadoop stack) ou comprimir arquivos juntos - por exemplo, em arquivos de sequência.
Em relação à leitura de ficheiros maiores do HDFS-run DFSIO benchmark e será o seu número.
Ao mesmo tempo-SSD em um único host perfeitamente pode ser uma solução também.
HDFS realmente não é projetado para muitos arquivos pequenos.
Para cada novo ficheiro que ler, o cliente tem de falar com o namenode, o que lhe dá a(S) localização(ões) do (s) Bloco (s) do ficheiro, e depois o cliente envia os dados do datanode.
Agora, na melhor das hipóteses, o cliente faz isto uma vez, e depois descobre que ele é a máquina com os dados nela, e pode lê-lo directamente do disco. Isto será rápido: comparável a leitura de disco direto. Se não for a máquina que tem os dados nela, então ela deve passar os dados através da rede. Então você está preso por velocidades de E/S de rede, o que não deve ser terrível, mas ainda um pouco mais lento do que Leitura de disco direto. No entanto, está a ter um caso ainda pior, em que a sobrecarga de falar com o namenode se torna significativa. Com apenas arquivos 1KB, você está chegando ao ponto em que você está trocando tanto metadados quanto dados reais. O cliente tem que fazer duas trocas de rede separadas para obter os dados de cada arquivo. Adicione a isto que o namenode está provavelmente ficando martelado por todos esses diferentes threads e assim ele pode se tornar um gargalo. Então, para responder à sua pergunta, sim, se você usar HDFS para algo que não foi projetado para ser usado, vai ser lento. Fundir seus arquivos pequenos, e usar MapReduce para obter localização de dados, e você terá um desempenho muito melhor. Na verdade, porque você vai ser capaz de tirar melhor vantagem de leitura de disco sequencial, eu não ficaria surpreso se a leitura de um arquivo HDFS grande foi mesmo mais rápido do que a leitura de muitos arquivos locais pequenos.Só para adicionar ao que Joe disse, outra diferença entre HDFS e outros sistemas de arquivos é que ele mantém o disco I/o o o menos possível, armazenando dados em blocos maiores (normalmente 64M ou 128M), em comparação com FS tradicionais onde o tamanho do bloco FS está na ordem de KBs. por essa razão, eles sempre dizem que HDFS é bom no processamento de poucos arquivos grandes em vez de grande nenhum de arquivos pequenos. a razão por trás disso é o fato de que, embora tenham havido avanços significativos em componentes como cpu, ram etc em tempos recentes, o disco I/o é uma área onde ainda não estamos muito adiantados. esta era a intenção por trás de ter tão grandes blocos (ao contrário do FS tradicional) e manter o uso do disco o menos possível.
Além disso, se o tamanho do bloco for muito pequeno, teremos um maior número de blocos. o que significa mais metadados. isso pode novamente degradar o desempenho, como mais quantidade de informação precisa ser carregada na memória. para cada bloco, que é considerado um object in HDFS has about 200B of metadata associated with it. se você tiver muitos blocos pequenos, ele só vai aumentar os metadados e você pode acabar com problemas de RAM. Há um post muito bom na seção de Blogues de Cloudera que fala sobre o mesmo assunto. Você pode visitar este aqui .