Stockage HDFS et Hive – comparaison entre les formats de fichiers et les méthodes de compression

Il y a quelques jours, nous avons conduit un test dans le but de comparer différent format de fichiers et méthodes de compression disponible dans Hive. Parmi ces formats, certains sont natifs à HDFS et s’appliquent à tous les utilisateurs d’Hadoop. La suite de tests est composée de requête Hive toutes similaires qui créent une table, éventuellement définissent une méthode de compression et chargent un jeu de données dans cette table nouvellement crée. Parmi les requêtes écrites sont testés les formats “sequence file”, “text file” et “RCFILE” ainsi que les codecs de compression “default”, “bz”, “gz”, “LZO” et “Snappy”.

N.B., cet article est la traduction d’un article précédent publié en anglais en mars dernier. Sa traduction est justifiée par la popularité de celui-ci.

Mise à jour, le 4 avril 2012: réponse au commentaire de Huchev relatif au codec LZ4.

Mise en place

L’environnement sur lequel ont été lancés ces tests est un cluster de 20 noeuds comprenant 120 To de stockage et fonctionnant sous Cloudera CDH3U3. Le jeu de données original est un répertoire de 1.33 Go composé de 80 fichiers non divisible compressés en “bz2”. Les données à l’intérieur sont structurées au format CSV pour un total de 125.000.000 lignes.

Ci-dessous, voici un exemple de requête Hive qui importe les données en utilisant le format “RCFILE” et le codec de compression “LZO”.

Résultats

Le tableau ci-dessous rapporte les résultats obtenus. La colonne intitulée “query” décrit le type de requête testée. Le nom commence par le format de fichier et est suivi par le type de compression. Les types de compression “block” et “record” sont rapporté pour le format “sequence file” et le codec de compression par défaut.

La famille de requêtes “serdesf” correspond à un mode de sérialisation SerDe que nous avons créé sur mesure et qui encode chacune des colonnes de notre jeu de données dans un format binaire aussi approprié que possible. Dans notre cas, le champ code peut être stocké comme un caractère (soit 1 byte), le champs value_2 peut être stocké comme la différence entre sa valeur réelle et celle du champs value_1 (soit 2 bytes). Au total, une ligne est stockée sous 16 bytes contre 65 bytes à l’origine.

Les requêtes “bss” utilise la sérialisation BinarySortableSerDe qui est un Hive SerDe personnalisé et qui s’associe au format “sequence file”.

La famille de requêtes “b64” utilisent le paquet “base64” présent dans les contributions de Hive.

query time size
sf 2mn 3s 7.91 Go
sf_string 2mn 22s 8.72 Go
sf_df_block 2mn 17s 8.72 Go
sf_df_record 2mn 12s 7.32 Go
sf_bz 2h 43mn 24s 9.9 Go
sf_gz 2mn 29s 8.72 Go
sf_lzo 2mn 36s 8.80 Go
sf_snappy 3mn 55s 8.23 Go
tf 1mn 45s 6.44 Go
tf_bz 2mn 14s 1.12 Go
tf_df 2mn 16s 1.12 Go
tf_gz 48s 1.34 Go
tf_lzo 1mn 28s 2.41 Go
tf_snappy 1mn 2s 2.55 Go
rc 1mn 30s 5.78 Go
rc_df 5mn 15s 917.68 Mo
rc_gz 4mn 36s 917.80 Mo
rc_snappy 52s 1.85 Go
rc_lzo 38s 1.67 Go
serdesf 59s 3.63 Go
serdesf_df 1mn 27s 4.61 Go
serdesf_bz 3h 6mn 9s 9.63 Go
serdesf_gz 1mn 51s 6.02 Go
serdesf_snappy 1mn 35s 4.80 Go
bss 1mn 25s 5.73 Go
b64 2mn 5s 9.17 Go
b64_bz 21mn 15s 1.14 Go
b64_df 21mn 25s 1.14 Go
b64_gz 53s 1.62 Go
b64_snappy 59s 2.89 Go

Quelques notes

Nous souhaitions faire tourner ces tests sur un jeu de données plus conséquent avec une structure de données plus classique mais les ressources serveurs furent très limitées à cet instant. Au final, les tailles finales des fichiers sont sans doutes représentatives mais les résultats sur les temps de création doivent être interprété avec plus de précaution.

Les vitesses mesurées reflètent le temps nécessaire à l’importation des données seulement (avec une structure des données en entrée pas trop standard) et non comment ces formats se comportent avec des tâches map/reduce.

Nous avons aussi testé le type de représentation block contre d’autre type de codec et nous avons pu conclure que cela n’avait aucun effet et que celui-ci de n’appliquait que pour des fichiers de type “sequence file”.

Finalement, nous avons essayé de faire tourner les tests serdesf en utilisant le format RCFILE au lieu de sequence file mais les résultats sont identiques à ceux de la famille de requêtes rc.

Interprétation

La requête “tf” peut être considérée comme une référence dans la mesure où le stockage est celui d’un format CSV non compressé. Il nous fut très étrange de constater que toutes les requêtes “sequence file” ont générées des fichiers plus larges que leurs amies les “Text file”. Voilà un fait que nous n’avions pas anticipé et peut-être est-ce dû à l’utilisation intensive du type “integer”.

Pour ce qui est de la taille des fichiers, le format “RCFILE” associé la compression par défault et “gz” ont obtenu les meilleurs résultats. Le “base64” SerDe utilisant le “sequence file” avec les compressions “bz” et “default” ne sont pas si loin de ces résultats. Les résultats “base64” sont suffisamment lents pour être mis de côté.

En terme de vitesse, les formats “RCFILE” avec les compressions “lzo” et “snappy” sont très rapides tout en préservant de forts taux de compression.

A propos LZ4

Nous n’avons pas testé la compression LZ4. Le support pour LZ4 vise les versions 0.23.1 et 0.24.0 d’Hadoop et n’est pas implémenté pour notre Cloudera CDH3U3. Si vous êtes sérieusement intéressé par LZ4, je vous invite à lire l’article comparant LZ4 avec Snappy. Cet article comparant les compressions les plus rapides en mémoire est aussi intéressant. Les 2 articles précédemment cités sont en anglais.

By |2018-06-05T22:37:21+00:00July 15th, 2012|Categories: Big Data|0 Comments

About the Author:

Passionate with programming, data and entrepreneurship, I participate in shaping Adaltas to be a team of talented engineers to share our skills and experiences.

Leave A Comment