2017-01-17 2 views
5

Ich habe untersucht, wie Spark Statistiken (min/max) in Parkett sowie wie es die Informationen für die Abfrageoptimierung verwendet. Ich habe ein paar Fragen. Erste Einrichtung: Spark 2.1.0, im Folgenden wird ein Dataframe von 1000 Zeilen mit einem langen Typ und einer Zeichenfolge-Spalte eingerichtet. Sie sind jedoch nach verschiedenen Spalten sortiert.Spark Parkett Statistiken (min/max) Integration

scala> spark.sql("select id, cast(id as string) text from range(1000)").sort("id").write.parquet("/secret/spark21-sortById") 
scala> spark.sql("select id, cast(id as string) text from range(1000)").sort("Text").write.parquet("/secret/spark21-sortByText") 

Ich habe einige Code Parkett-Tools Statistiken auszudrucken und untersuchen die generierten Dateien Parkett:

hadoop jar parquet-tools-1.9.1-SNAPSHOT.jar meta /secret/spark21-sortById/part-00000-39f7ac12-6038-46ee-b5c3-d7a5a06e4425.snappy.parquet 
file:  file:/secret/spark21-sortById/part-00000-39f7ac12-6038-46ee-b5c3-d7a5a06e4425.snappy.parquet 
creator:  parquet-mr version 1.8.1 (build 4aba4dae7bb0d4edbcf7923ae1339f28fd3f7fcf) 
extra:  org.apache.spark.sql.parquet.row.metadata = {"type":"struct","fields":[{"name":"id","type":"long","nullable":false,"metadata":{}},{"name":"text","type":"string","nullable":false,"metadata":{}}]} 

file schema: spark_schema 
-------------------------------------------------------------------------------- 
id:   REQUIRED INT64 R:0 D:0 
text:  REQUIRED BINARY O:UTF8 R:0 D:0 

row group 1: RC:5 TS:133 OFFSET:4 
-------------------------------------------------------------------------------- 
id:   INT64 SNAPPY DO:0 FPO:4 SZ:71/81/1.14 VC:5 ENC:PLAIN,BIT_PACKED STA:[min: 0, max: 4, num_nulls: 0] 
text:   BINARY SNAPPY DO:0 FPO:75 SZ:53/52/0.98 VC:5 ENC:PLAIN,BIT_PACKED 

hadoop jar parquet-tools-1.9.1-SNAPSHOT.jar meta /secret/spark21-sortByText/part-00000-3d7eac74-5ca0-44a0-b8a6-d67cc38a2bde.snappy.parquet 
file:  file:/secret/spark21-sortByText/part-00000-3d7eac74-5ca0-44a0-b8a6-d67cc38a2bde.snappy.parquet 
creator:  parquet-mr version 1.8.1 (build 4aba4dae7bb0d4edbcf7923ae1339f28fd3f7fcf) 
extra:  org.apache.spark.sql.parquet.row.metadata = {"type":"struct","fields":[{"name":"id","type":"long","nullable":false,"metadata":{}},{"name":"text","type":"string","nullable":false,"metadata":{}}]} 

file schema: spark_schema 
-------------------------------------------------------------------------------- 
id:   REQUIRED INT64 R:0 D:0 
text:  REQUIRED BINARY O:UTF8 R:0 D:0 

row group 1: RC:5 TS:140 OFFSET:4 
-------------------------------------------------------------------------------- 
id:   INT64 SNAPPY DO:0 FPO:4 SZ:71/81/1.14 VC:5 ENC:PLAIN,BIT_PACKED STA:[min: 0, max: 101, num_nulls: 0] 
text:   BINARY SNAPPY DO:0 FPO:75 SZ:60/59/0.98 VC:5 ENC:PLAIN,BIT_PACKED 

Die Frage ist also, warum Spark, vor allem, 2.1.0, nur erzeugen min/max für numerische Spalten, aber nicht für Strings (BINARY) -Felder, auch wenn das String-Feld in der Sortierung enthalten ist? Vielleicht habe ich eine Konfiguration verpasst?

Die zweite Frage, wie kann ich bestätigen, Spark nutzt die min/max?

scala> sc.setLogLevel("INFO") 
scala> spark.sql("select * from parquet.`/secret/spark21-sortById` where id=4").show 

Ich habe viele Zeilen wie diese:

17/01/17 09:23:35 INFO FilterCompat: Filtering using predicate: and(noteq(id, null), eq(id, 4)) 
17/01/17 09:23:35 INFO FileScanRDD: Reading File path: file:///secret/spark21-sortById/part-00000-39f7ac12-6038-46ee-b5c3-d7a5a06e4425.snappy.parquet, range: 0-558, partition values: [empty row] 
... 
17/01/17 09:23:35 INFO FilterCompat: Filtering using predicate: and(noteq(id, null), eq(id, 4)) 
17/01/17 09:23:35 INFO FileScanRDD: Reading File path: file:///secret/spark21-sortById/part-00193-39f7ac12-6038-46ee-b5c3-d7a5a06e4425.snappy.parquet, range: 0-574, partition values: [empty row] 
... 

Die Frage ist, es sieht aus wie Funken jede Datei scannt, auch wenn von der min/max, sollten Funken der Lage sein, nur Teil bestimmen 00000 hat die relevanten Daten. Oder habe ich es falsch gelesen, dass Spark die Dateien überspringt? Vielleicht kann Spark nur den Partitionswert für das Überspringen von Daten verwenden?

Antwort

0

Für die erste Frage, ich glaube, das ist eine Frage der Definition (was wäre die min/max einer Zeichenfolge? Lexikalische Bestellung?), Aber in jedem Fall, soweit ich weiß, sparks Parkett derzeit nur Zahlen.

Wie für die zweite Frage glaube ich, dass wenn Sie tiefer schauen Sie sehen würden, dass Funke nicht die Dateien selbst lädt. Stattdessen liest es die Metadaten, so dass es weiß, ob es einen Block lesen soll oder nicht. Im Grunde drückt es das Prädikat auf die Dateiebene (Block).

0

PARQUET-686 hat Änderungen vorgenommen, um Statistiken zu Binärfeldern absichtlich zu ignorieren, wenn dies angemessen erscheint. Sie können dieses Verhalten überschreiben, indem Sie parquet.strings.signed-min-max.enabled auf true setzen.

Nach dem Einstellen dieser Konfiguration können Sie min/max im Binärfeld mit Parkett-Tools lesen.

Weitere Details in my another stackoverflow question

Verwandte Themen