0 / 0
Retourner à la version anglaise de la documentation
Saut de données (data skipping) pour Spark SQL
Dernière mise à jour : 21 nov. 2024
Saut de données (data skipping) pour Spark SQL

Le saut de données peut considérablement améliorer les performances des requêtes SQL en ignorant les fichiers ou objets de données non pertinents en fonction des métadonnées récapitulatives associées à chaque objet.

Le saut de données utilise la bibliothèque open source Xskipper pour créer, gérer et déployer des index des données à omettre avec Apache Spark. Consultez Xskipper - An Extensible Data Skipping Framework.

Pour plus de détails sur la façon d'utiliser Xskipper, consultez :

Outre les fonctionnalités open source de Xskipper, les fonctionnalités suivantes sont disponibles :

Non prise en compte des données géospatiales

Vous pouvez également utiliser des données ignorées lors de l'interrogation des ensembles de données géospatiales à l'aide des fonctions géospatiales à partir de la bibliothèque spatio-temporelle.

  • Pour profiter du saut de données dans les jeux de données contenant des colonnes de latitude et de longitude, vous pouvez collecter les index min/max sur ces colonnes.
  • Les données ignorées peuvent être utilisées dans des fichiers avec une colonne de géométrie (colonne UDT) à l'aide d'un Plug-in Xskipper intégré.

Les sections suivantes montre comment utiliser le plug-in géospatial.

Mise en place dud plug-in géospatial

Pour utiliser le plug-in, chargez les implémentations appropriées à l'aide du module d'enregistrement. Notez que vous ne pouvez utiliser Scala que dans les applications d'IBM Analytics Engine powered by Apache Spark, et non dans watsonx.ai Studio.

  • Pour Scala :

    import com.ibm.xskipper.stmetaindex.filter.STMetaDataFilterFactory
    import com.ibm.xskipper.stmetaindex.index.STIndexFactory
    import com.ibm.xskipper.stmetaindex.translation.parquet.{STParquetMetaDataTranslator, STParquetMetadatastoreClauseTranslator}
    import io.xskipper._
    
    Registration.addIndexFactory(STIndexFactory)
    Registration.addMetadataFilterFactory(STMetaDataFilterFactory)
    Registration.addClauseTranslator(STParquetMetadatastoreClauseTranslator)
    Registration.addMetaDataTranslator(STParquetMetaDataTranslator)
    
  • Pour Python :

    from xskipper import Xskipper
    from xskipper import Registration
    
    Registration.addMetadataFilterFactory(spark, 'com.ibm.xskipper.stmetaindex.filter.STMetaDataFilterFactory')
    Registration.addIndexFactory(spark, 'com.ibm.xskipper.stmetaindex.index.STIndexFactory')
    Registration.addMetaDataTranslator(spark, 'com.ibm.xskipper.stmetaindex.translation.parquet.STParquetMetaDataTranslator')
    Registration.addClauseTranslator(spark, 'com.ibm.xskipper.stmetaindex.translation.parquet.STParquetMetadatastoreClauseTranslator')
    

Génération d'un index

Pour générer un index, vous pouvez utiliser l'API addCustomIndex . Notez que vous ne pouvez utiliser Scala que dans les applications d'IBM Analytics Engine powered by Apache Spark, et non dans watsonx.ai Studio.

  • Pour Scala :

    import com.ibm.xskipper.stmetaindex.implicits._
    
    // index the dataset
    val xskipper = new Xskipper(spark, dataset_path)
    
    xskipper
      .indexBuilder()
      // using the implicit method defined in the plugin implicits
      .addSTBoundingBoxLocationIndex("location")
      // equivalent
      //.addCustomIndex(STBoundingBoxLocationIndex("location"))
      .build(reader).show(false)
    
  • Pour Python :

    xskipper = Xskipper(spark, dataset_path)
    
    # adding the index using the custom index API
    xskipper.indexBuilder() \
            .addCustomIndex("com.ibm.xskipper.stmetaindex.index.STBoundingBoxLocationIndex", ['location'], dict()) \
            .build(reader) \
            .show(10, False)
    

Fonctions prises en charge

La liste des fonctions géospatiales prises en charge inclut les éléments suivants :

  • ST_Distance
  • ST_Intersects
  • ST_Contains
  • ST_Equals
  • ST_Crosses
  • ST_Touches
  • ST_Within
  • ST_Overlaps
  • ST_EnvelopesIntersect
  • ST_IntersectsInterior

Chiffrement des index

Si vous utilisez un magasin de métadonnées Parquet, les métadonnées peuvent si nécessaire être chiffrées au moyen de Parquet Modular Encryption (PME). On procède pour ce faire en stockant les métadonnées elles-mêmes en tant que jeu de données Parquet. PME peut alors être utilisé pour les chiffrer. Cette possibilité peut être étendue à tous les formats d'entrée. Ainsi, par exemple, un jeu de données stocké au format CSV pourra avoir ses métadonnées chiffrées avec PME.

Dans la section suivante, sauf indication contraire, les références aux pieds de page, colonnes, etc. concernent les objets métadonnées, et non les objets du jeu de données indexé.

Le chiffrement d'index est modulaire et granulaire à ces égards :

  • Chaque index peut être chiffré (avec une granularité de clé par index) ou laissé en texte en clair
  • Colonne de pied de page + noms d'objet :
    • La colonne de pied de page de l'objet métadonnées qui, en soi, est un fichier Parquet, contient, entre autres choses :
      • Le schéma de l'objet métadonnées, qui révèle les types, paramètres et noms de colonne de tous les index collectés. Par exemple, vous pouvez apprendre qu'un BloomFilter est défini dans la colonne city avec une probabilité de faux positif de 0.1.
      • Le chemin complet du jeu de données d'origine ou un nom de table dans le cas d'une table de métamagasin Hive.
    • La colonne de noms d'objet stocke les noms de tous les objets indexés.
  • La colonne de pied de page + métadonnées peut être :
    • Toutes les deux chiffrées avec la même clé. Il s'agit de la valeur par défaut. Dans ce cas, la configuration de pied de page en texte normal pour les objets Parquets comprenant les métadonnées est en mode pied de page chiffré, et la colonne des noms d'objet est chiffrée avec la clé sélectionnée.

    • Tous les deux en texte normal. Dans ce cas, les objets Parquets comprenant les métadonnées sont en mode pied de page en texte normal, et la colonne des noms d'objet n'est pas chiffrée.

      Si au moins un index est repéré comme étant chiffré, une clé de pied de page doit être configurée, peu importe que le mode pied de page en texte normal soit activé ou non. Si le pied de page est en texte normal, la clé de pied de page n'est utilisée que pour l'inviolabilité. Notez que, dans ce cas, la colonne des noms d'objet n'est pas inviolable.

      Si une clé de pied de page est configurée, alors au moins un index doit être chiffré.

Avant d'utiliser le chiffrement d'index, vous devez vérifier la documentation sur PME et vous assurer que vous les concepts vous sont familiers.

Important: Lorsque vous utilisez le chiffrement d'index, chaque fois qu'un key est configuré dans une API Xskipper, il s'agit toujours du libellé ` JAMAIS la clé elle-même `.

Pour utiliser le chiffrement d'index :

  1. Suivez toutes les étapes pour vérifier que PME est activé. Voir PME.

  2. Effectuez toutes les configurations PME normales, y compris les configurations de gestion des clés.

  3. Créez des métadonnées chiffrées pour un jeu de données :

    1. Suivez la procédure normale pour créer des métadonnées.
    2. Configurez une clé de pied de page. Si vous souhaitez définir une colonne de nom d'objet et de pied de page en texte en clair, définissez io.xskipper.parquet.encryption.plaintext.footer sur true (voir les exemples ci-dessous).
    3. Dans IndexBuilder, pour chaque index à chiffrer, ajoutez le libellé de la clé à utiliser pour l'index.

    Pour utiliser les métadonnées lors de la requête ou pour régénérer les métadonnées existantes, aucune configuration n'est nécessaire autre que la configuration PME normale requise pour s'assurer que les clés sont accessibles (littéralement la même configuration nécessaire pour lire un fichier chiffré).

Echantillons

Les exemples suivants montrent la création de métadonnées à l'aide d'une clé nommée k1 en tant que clé de pied de page + de nom d'objet, et une clé nommée k2 comme clé pour chiffrer un MinMax pour temp, tout en créant un ValueList pour city, qui est laissé en texte en clair. Notez que vous ne pouvez utiliser Scala que dans les applications d'IBM Analytics Engine powered by Apache Spark, et non dans watsonx.ai Studio.

  • Pour Scala :

    // index the dataset
    val xskipper = new Xskipper(spark, dataset_path)
    // Configuring the JVM wide parameters
    val jvmComf = Map(
      "io.xskipper.parquet.mdlocation" -> md_base_location,
      "io.xskipper.parquet.mdlocation.type" -> "EXPLICIT_BASE_PATH_LOCATION")
    Xskipper.setConf(jvmConf)
    // set the footer key
    val conf = Map(
      "io.xskipper.parquet.encryption.footer.key" -> "k1")
    xskipper.setConf(conf)
    xskipper
      .indexBuilder()
      // Add an encrypted MinMax index for temp
      .addMinMaxIndex("temp", "k2")
      // Add a plaintext ValueList index for city
      .addValueListIndex("city")
      .build(reader).show(false)
    
  • Pour Python

    xskipper = Xskipper(spark, dataset_path)
    # Add JVM Wide configuration
    jvmConf = dict([
      ("io.xskipper.parquet.mdlocation", md_base_location),
      ("io.xskipper.parquet.mdlocation.type", "EXPLICIT_BASE_PATH_LOCATION")])
    Xskipper.setConf(spark, jvmConf)
    # configure footer key
    conf = dict([("io.xskipper.parquet.encryption.footer.key", "k1")])
    xskipper.setConf(conf)
    # adding the indexes
    xskipper.indexBuilder() \
            .addMinMaxIndex("temp", "k1") \
            .addValueListIndex("city") \
            .build(reader) \
            .show(10, False)
    

Si vous voulez que les pied de page + noms d'objet soient laissés en mode texte normal (comme mentionné plus haut), vous devez ajouter le paramètre de configuration :

  • Pour Scala :

    // index the dataset
    val xskipper = new Xskipper(spark, dataset_path)
    // Configuring the JVM wide parameters
    val jvmComf = Map(
      "io.xskipper.parquet.mdlocation" -> md_base_location,
      "io.xskipper.parquet.mdlocation.type" -> "EXPLICIT_BASE_PATH_LOCATION")
    Xskipper.setConf(jvmConf)
    // set the footer key
    val conf = Map(
      "io.xskipper.parquet.encryption.footer.key" -> "k1",
      "io.xskipper.parquet.encryption.plaintext.footer" -> "true")
    xskipper.setConf(conf)
    xskipper
      .indexBuilder()
      // Add an encrypted MinMax index for temp
      .addMinMaxIndex("temp", "k2")
      // Add a plaintext ValueList index for city
      .addValueListIndex("city")
      .build(reader).show(false)
    
  • Pour Python

    xskipper = Xskipper(spark, dataset_path)
    # Add JVM Wide configuration
    jvmConf = dict([
    ("io.xskipper.parquet.mdlocation", md_base_location),
    ("io.xskipper.parquet.mdlocation.type", "EXPLICIT_BASE_PATH_LOCATION")])
    Xskipper.setConf(spark, jvmConf)
    # configure footer key
    conf = dict([("io.xskipper.parquet.encryption.footer.key", "k1"),
    ("io.xskipper.parquet.encryption.plaintext.footer", "true")])
    xskipper.setConf(conf)
    # adding the indexes
    xskipper.indexBuilder() \
            .addMinMaxIndex("temp", "k1") \
            .addValueListIndex("city") \
            .build(reader) \
            .show(10, False)
    

Saut de données avec jointures (pour Spark 3 uniquement)

Avec Spark 3, vous pouvez utiliser le saut de données dans des requêtes de jointure telles que :

SELECT *
FROM orders, lineitem 
WHERE l_orderkey = o_orderkey and o_custkey = 800

Cet exemple présente un schéma en étoile basé sur le schéma de référence TPC-H (voir TPC-H) où lineitem est un tableau de faits et contient de nombreux enregistrements, alors que le tableau des commandes est un tableau de dimension dont le nombre d'enregistrements est relativement faible par rapport aux tableaux de faits.

La requête ci-dessus a un prédicat sur la table orders. Or, celle-ci contenant un petit nombre d'enregistrements, l'utilisation de min/max ne bénéficiera pas beaucoup du saut de données.

Ignorer les données dynamiques est une fonction qui permet aux requêtes telles que celles ci-dessus de bénéficier des données ignorées en extrayant d'abord les valeurs l_orderkey appropriées en fonction de la condition sur le tableau orders, puis de l'utiliser pour pousser un prédicat sous l_orderkey qui utilise des index de sauts de données pour filtrer les objets non pertinents.

Pour utiliser cette fonction, activez la règle d'optimisation suivante. Notez que vous ne pouvez utiliser Scala que dans les applications d'IBM Analytics Engine powered by Apache Spark, et non dans watsonx.ai Studio.

  • Pour Scala :

      import com.ibm.spark.implicits.
    
      spark.enableDynamicDataSkipping()
    
  • Pour Python :

        from sparkextensions import SparkExtensions
    
        SparkExtensions.enableDynamicDataSkipping(spark)
    

Puis utilisez l'API Xskipper comme à l'accoutumée. Vos requêtes bénéficieront alors de l'utilisation du saut de données.

Par exemple, dans la requête ci-dessus, l'indexation l_orderkey à l'aide de min / max permet d'ignorer le tableau lineitem et d'améliorer les performances de la requête.

Pris en charge des anciennes métadonnées

Xskipper accepte sans problème les anciennes métadonnées créées par le MetaIndexManager. Les anciennes métadonnées peuvent être utilisées pour le saut de données, car les mises à jour des métadonnées Xskipper sont menées à bien automatiquement par l'opération de rafraîchissement suivante.

Si vous voyez DEPRECATED_SUPPORTED devant fun index lors de l'établissement de la liste des index ou de l'exécution d'une opération describeIndex, la version de métadonnées est obsolète, mais est toujours prise en charge, et l'exclusion fonctionnera. La prochaine opération de rafraîchissement mettra à jour les métadonnées automatiquement.

Recherche et réponse à l'IA générative
Ces réponses sont générées par un modèle de langue de grande taille dans watsonx.ai en fonction du contenu de la documentation du produit. En savoir plus