パフォヌマンスApache Parquet

良いテストの悪い䟋。



最近、喫煙宀では、Apache Hadoopのさたざたなストレヌゞ圢匏CSV、JSON、Apache Avro、Apache Parquetなどのパフォヌマンスを比范する議論が頻繁に行われおいたす。 ほずんどの参加者はすぐにテキスト圢匏を明癜な郚倖者ずしお华䞋し、AvroずParquetの間のコンテストの䞻な陰謀を残したした。







䞀般的な意芋は、デヌタセット党䜓を操䜜するずきに1぀の圢匏が「より良い」ように芋え、2番目の「より良い」が列のサブセットのク゚リを凊理するずいう未確認の噂でした。







他の自尊心のある゚ンゞニアず同様に、本栌的なパフォヌマンステストを実斜しお、どちらが正しいかを最終的に確認するこずをお勧めしたす。 比范の結果は切り捚おられおいたす。







アパッチ寄朚现工のロゎ







翻蚳者泚

圓初、この蚘事は、 Apache Sparkを䜿甚しおApache AvroずApache Parquetを比范した経隓に関するCloudera Engineering BlogのDon Drakeのテキスト @dondrake の無料翻蚳ずしお構想されたした。 しかし、翻蚳プロセス䞭に詳现を調べお、テストで倚くの論争点を芋぀けたした。 蚘事にサブタむトルを远加したした。テキストには、䞍正確さを瀺す悪意のあるコメントが含たれおいたす。


テストデヌタセット



テストに実際のデヌタず実際のク゚リを䜿甚するのが正しいず思いたした。 この堎合、実皌働環境でのパフォヌマンスはテスト環境ず同様に動䜜するこずが期埅できたす。 ぀たり、テストでは、サロゲヌトデヌタの行をカりントするこずはできたせん。







テストのための「実際のデヌタ」ず「実際のク゚リ」の遞択は、非垞に物議をかもしおいるようです。 誰もが異なる実際のデヌタず芁求を持っおいたす。 この問題を解決するために、 TPCベンチマヌクなどの兞型的なストレヌゞパフォヌマンステストが合成されたす。


私が最近䜜業したデヌタセットを調べたずころ、テストに最適な2぀のデヌタが芋぀かりたした。 1぀目は「ナロヌ」ず呌び、3列のみで構成され、8230䞇行が含たれおいたす。CSVでは3.9 GBを占めたす。







以䞋に瀺すように、これにより750〜1000 MBのシリアル化されたデヌタが生成され、50人のワヌカヌで凊理されたす。 各ワヌカヌは15〜20 MBのデヌタを取埗したす。 ほずんどの堎合、ワヌカヌの初期化はデヌタの読み取りず凊理よりも時間がかかりたす。


2぀目は、「ワむド」ず呌びたす。103列ず6億9,400䞇行で構成され、サむズが194 GBのCSVファむルになりたす。 このアプロヌチにより、倧小のファむルでどの圢匏がより適切に機胜するかを評䟡できるず思いたす。







「ワむド」デヌタセットは30倍だけでなく、8倍も長くなっおいたす。 元のサむズの49倍。 デヌタセットを「小」および「倧」ず呌ぶ方がより正確です。

さらに、サむズ比から刀断するず、デヌタセットではさたざたなタむプの列が衚されおいるようです。 この䜜業では、デヌタ型の違いは通垞無芖されたす。 䞀方、これはストレヌゞ圢匏の重芁な偎面です。


詊隓方法



テストの䞻力ずしお、Apache Spark 1.6を遞択したした。 SparkはそのたたParquetをサポヌトし、AvroおよびCSVのサポヌトは個別に接続されたす。 すべおの操䜜は、100台以䞊のマシンのCDH 5.5.xクラスタヌで実行されたした。







さたざたな皮類の凊理読み蟌み、単玔なク゚リ、重芁なク゚リ、デヌタセット党䜓の凊理、および䜿甚されおいるディスク容量のフォヌマットのパフォヌマンスを枬定するこずに興味がありたした。







䞡方のデヌタセットに察しお同じ構成でspark-shell



を介しおテストを実行したした違いぱグれキュヌタヌの数のみでした。 シェルモヌド:paste



は、むンタヌプリタヌを混乱させる可胜性のある耇数行のコマンドを心配するこずなく、ScalaコヌドをREPLに盎接コピヌできるようにしお、呜を救いたした。







 #!/bin/bash -x # Drake export HADOOP_CONF_DIR=/etc/hive/conf export SPARK_HOME=/home/drake/coolstuff/spark/spark-1.6.0-bin-hadoop2.6 export PATH=$SPARK_HOME/bin:$PATH # use Java8 export JAVA_HOME=/usr/java/latest export PATH=$JAVA_HOME/bin:$PATH # NARROW NUM_EXECUTORS=50 # WIDE NUM_EXECUTORS=500 spark-shell —master yarn-client \ —conf spark.eventLog.enabled=true \ —conf spark.eventLog.dir=hdfs://nameservice1/user/spark/applicationHistory \ —conf spark.yarn.historyServer.address=http://yarnhistserver.allstate.com:18088 \ —packages com.databricks:spark-csv_2.10:1.3.0,com.databricks:spark-avro_2.10:2.0.1 \ —driver-memory 4G \ —executor-memory 2G \ —num-executors $NUM_EXECUTORS \ ...
      
      





Spark Web UIの[ゞョブ]タブからク゚リの実行時間を取埗したした。 各テストを3回繰り返し、平均時間を蚈算したした。 狭いデヌタセットぞの芁求は比范的負荷の高いクラスタヌで実行され、広いデヌタセットぞの芁求は完党なアむドルクラスタヌの時点で実行されたした。 それは意図的に起こったのではなく、偶然です。







テスト間で異なる環境異なる数のワヌカヌず異なるクラスタヌ負荷を含むを䜿甚するず、絶察倀を比范するこずができなくなりたす。

ロヌドされたクラスタヌ自䜓の䜿甚は、再起動時の枬定結果の再珟性に悪圱響を及がしたす-簡単なこずではありたせん。

実隓の3回の繰り返しは統蚈的に軜埮に芋えたす-評䟡の信頌区間は非垞に倧きくなりたす。 ただし、著者は信頌区間に぀いおも蚀及しおいたせん。


デヌタの前凊理



CSVから狭いデヌタセットを読み取るずきに、回路を出力したせんでしたが、 String



型のString



をTimestamp



に倉換する必芁がありたした。 結果にこの倉換の時間を含めたせんでした。なぜなら、 ストレヌゞ圢匏には適甚されたせん。 広いデヌタセットを䜿甚する堎合、回路の出力を䜿甚したしたが、この時間も考慮したせんでした。







スキヌマの出力元の- 掚論スキヌマ  DataFrame



、Reflectionを䜿甚したRDD



からDataFrame



ぞの暗黙的な倉換を意味したす 。


テストプロセス䞭に、Timestampタむプの列を持぀Avroファむルを保存するこずが䞍可胜であるこずを知っお驚いた。 実際、Avroバヌゞョン1.7.xは基本的にDate



たたはTimestamp



サポヌトしおいたせん。







Avro 1.8 は、論理型Date



、 Timestamp



およびそれらの掟生型をサポヌトしおいたす。 実際、これらはint



たたはlong



単なるラッパヌです。


狭いデヌタセットのテスト



最初に、AvroたたはParquet圢匏で狭いデヌタセットをディスクに曞き蟌むこずができる時間を芋積もりたした。 デヌタをデヌタフレヌムに読み蟌んだ埌、蚘録に有効な時間のみを考慮したした。 統蚈誀差の範囲内で差が埗られたした。 したがっお、狭いデヌタセットの曞き蟌みパフォヌマンスは、䞡方の圢匏でほが同じです。







ネットワヌクのオヌバヌヘッドなどを考慮しおも、シリアル化の時間は非垞に長くなりたした。結局のずころ、1人のワヌカヌの出力は20 MB未満です。

䜜成者が読み取りず凊理の時間ず曞き蟌みの時間を誀っお分離したように芋えたす。 この堎合、この時間のほずんどが4ギガバむトのCSVファむルを読み蟌んでいる可胜性があり、おそらく1぀のストリヌムでさえです。 そしお、他のすべおは5-10秒かかりたす。


狭いデヌタセットをディスクに曞き蟌む時間秒単䜍少ないほど良い

狭い名前で保存







その埌、狭いデヌタセットの行数を単玔にカりントするのにかかる時間を調べたした。 AvroずParquetの実行速床は等しく[^ fast-row-count]です。 比范のため、たた読者を脅すために、非圧瞮CSVのカりント時間も蚈算したした。







寄朚现工のファむルには、メタデヌタにブロック内のオブゞェクトの数が含たれおいたす。 ワヌカヌごずのデヌタ量のこの比率では、それぞれが1぀のParquetブロックのみを取埗したす。 したがっお、カりントするには、すべおの人が1぀の数倀を読み取っおから、䞀般的な瞮小を行っお合蚈を取埗するだけで十分です。

Avroの堎合、タスクははるかに耇雑です-Avroブロックにはブロック内のオブゞェクトの数も含たれたすが、ブロック自䜓ははるかに小さく デフォルトでは64 KB 、ファむルには倚くのブロックが含たれたす。 理論的には、avroファむル内のすべおのオブゞェクトのカりント時間は長くする必芁がありたす。 実際には、このような小さなファむルの堎合、違いに気付かない堎合がありたす。

CSVファむルの行数をカりントするには、Avroの堎合ず同様に、このファむルを完党に読み取る必芁がありたす。 4 GBファむルを正しく分割するず、各ワヌカヌは80 MBのデヌタを持ち、数秒で読み取るこずができたす。 ただし、䜜成者の読み取りプロセスには45秒かかりたす。これは、ファむルが十分に䞊列化されおいないこずを瀺したす。


狭いデヌタセットの行数を秒単䜍で数える少ない方が良い

狭い行数







GROUP BY



グルヌピングを䜿甚したより耇雑なク゚リを詊した埌。 このデヌタセットの列の1぀はタむムスタンプであり、毎日別の列の量を蚈算したした。 なぜなら AvroはDate



ずTimestamp



サポヌトしおいたせん。同様の結果を埗るためにク゚リを埮調敎する必芁がありたした。







寄朚现工のお問い合わせ







 val sums = sqlContext.sql("""select to_date(precise_ts) as day, sum(replacement_cost) from narrow_parq group by to_date(precise_ts) """)
      
      





Avroク゚リのク゚リ







 val a_sums = sqlContext.sql("""select to_date(from_unixtime(precise_ts/1000)) as day, sum(replacement_cost) from narrow_avro group by to_date(from_unixtime(precise_ts/1000)) """)
      
      





グルヌプ化されたク゚リの堎合、ParquetはAvroより2.6倍高速でした。

狭いグルヌプ







次に、 DataFrame



eで.map()



DataFrame



を実行しお、デヌタセット党䜓の凊理をシミュレヌトするこずにしたした。 行の列数をカりントし、すべおの䞀意の倀を収集する倉換を遞択したした。







 def numCols(x: Row): Int = { x.length } val numColumns = narrow_parq.rdd.map(numCols).distinct.collect
      
      





.distinct()



操䜜はタスクを非垞に耇雑にしたす。 簡単にするために、プロセスにリデュヌスフェヌズを远加するず想定できたす。これは、デヌタセット党䜓の.map()



が枬定されるだけでなく、ワヌカヌ間のデヌタ亀換のオヌバヌヘッドも枬定されるこずを意味したす。


これは実際のデヌタ凊理䞭に実行されるタスクそのものではありたせんが、それでもデヌタセット党䜓の凊理を匷制したす。 たた、ParquetはAvroのほが2倍高速です。

狭い地図







最埌に行う必芁があるのは、ディスク䞊のデヌタセットのサむズを比范するこずです。 グラフはサむズをバむト単䜍で瀺したす。 AvroはSnappy圧瞮コヌデックを䜿甚するように構成され、Parquetにはデフォルト蚭定が䜿甚されたした。







ParquetのデヌタセットはAvroよりも25少ないこずが刀明したした。

狭いディスク䜿甚量







デフォルトの圧瞮蚭定を䜿甚し、それらを調べないこずは非垞に悪い習慣です。

ただし、Parquet はデフォルトでgzipを䜿甚したす 。 Gzipは、Snappyよりも著しく匷力に圧瞮されたす。 突然、サむズの違いは単にコヌデックの違いによるものですか 正しい比范のために、同じ圧瞮を䜿甚する堎合、たたはたったく䜿甚しない堎合のデヌタセットのサむズを蚈算する必芁がありたす。

たた、正盎なずころ、通垞はテキストファむルを時々圧瞮できるこずに泚意しおください。 積極的にgzipベヌスの゜ヌスCSVファむルが1.5 GBを超えないこずを認めたす。 したがっお、バむナリ圢匏の利点はそれほど劇的ではありたせん。


ワむドデヌタセットテスト



倧芏暡な「ワむド」デヌタセットに察しお同様の操䜜を実行したした。 このデヌタセットには10​​3列ず6億9,400䞇行が含たれおおり、194 GBの非圧瞮CSVファむルに倉換されるこずに泚意しおください。







そしお、今埌、5 GBのParquetず17 GBのAvroが埗られるこずをお知らせしたす。 500人の埓業員がいるず、Parquetの堎合は100 MB、Avroの堎合は340 MBの負荷がかかりたす。 もちろん、寄朚现工はコンパクトな収玍で勝ちたした。 しかし、Avroファむルはより倚くのブロックを持぀こずが刀明したした。぀たり、ワヌカヌの数を増やすこずで凊理速床を䞊げるこずができたす。 そのため、クラスタヌを倩井からロヌドし、ワヌカヌの数を動的に蚈算するず、これらのテストよりも優れたAvroパフォヌマンスを実珟できたす。


最初に、䞡方の圢匏で幅広いデヌタセットを保存する時間を枬定したした。 パヌケットは毎回Avroよりも高速でした。

ワむドセヌブずしお







行数の蚈算で、ParquetはAvroを完党に砎壊し、3秒よりも速く結果を出したした。

広い行数







Parquetはデフォルトで、 128 MBのブロックサむズを䜿甚したす。これは、ワヌカヌごずの平均デヌタ量よりも倧きくなりたす。 したがっお、Parquetを䜿甚する堎合、「狭い」デヌタセットからのトリックは匕き続き機胜したす。デヌタセット内の行数を蚈算するには、メタデヌタから1぀の数倀を読み取るだけで十分です。

Avroファむルの堎合は、デヌタセットを完党に読み取り、各ブロックのメタデヌタのみを解釈し、デヌタ自䜓をデシリアラむズせずにスキップする必芁がありたす。 これは、ディスクの「実際の」䜜業に倉換されたす。 CSVの堎合、状況はさらに悪化したす。そこでは、すべおのバむトを解析する必芁がありたす。


より耇雑なGROUP BY



ク゚リの堎合、Parquetが再びリヌドしたす。

広いグルヌプ







ここでは、Avroで3.4倍のワヌカヌを起動できるこずを思い出しおください。 寄朚现工はその埌リヌダヌシップを維持したすか


そしお、デヌタセット党䜓の.map()



倉換の堎合でも、パヌケットは説埗力のあるマヌゞンで再び勝利したす。

広い地図







たた、ここでは、Avroで3.4倍以䞊のワヌカヌを起動できるこずも芚えおおく必芁がありたす。 そしお、操䜜時間のどの割合が.distinct()



を必芁ずし、どの郚分が実際にディスクから読み取られたすか


最新のテストであるディスク䜿甚効率のテストでは、䞡方の参加者に印象的な結果が瀺されたした。 Parquetは元の194 GBを4.7 GBに圧瞮するこずができ、97を超える倧きな圧瞮を実珟したした。 たた、Avroは、デヌタを16.9 GBに圧瞮する91の圧瞮ずいう印象的な結果を瀺したした。 䞡方の参加者に称賛

広いディスク䜿甚量







おわりに



その結果、Parquetは各テストで少なくずも最悪のパフォヌマンスを瀺したせんでした。 デヌタ量が増加するに぀れお、その利点が明らかになりたした。 AvroはParquetの3.5倍の読み取りを行う必芁があったため、Parquetの良い結果は圧瞮効率の向䞊に䞀郚起因しおいたす。 たた、Avroは、圌に起因するず噂されおいるデヌタセット党䜓を読み取ったずきに、その高いパフォヌマンスを瀺したせんでした。







Hadoopでストレヌゞ圢匏を遞択する必芁がある堎合、サヌドパヌティアプリケヌションずの統合、スキヌムの進化、特定のデヌタタむプのサポヌトなど、倚くの芁因を考慮する必芁がありたす...しかし、パフォヌマンスを最前線に眮いた堎合、䞊蚘のテストはParquetが最良の遞択であるこずを確信的に瀺したす。







そしお、自分から远加したす。 これは、フォヌマットのパフォヌマンスの完党に適切な枬定です。 これは、私たちのチヌムの業界経隓からの倚数の散芋的な芳察によっお確認されおいたす。 それでも、テスト方法論は、倖郚アクションCSV、 GROUP BY', '.distinct()



などGROUP BY', '.distinct()



枬定をゆがめるこずがあり、重芁な問題圧瞮、デヌタ圢匏などを完党に無芖するこずがありたす。 「蒞留」メトリックを䜿甚しお暙準テストを実行するのは簡単ではないこずを理解しおいたす。 しかし、Clouderaのブログからは、たさにそれを期埅しおいたした。



All Articles