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 :
- Exclusion de données géospatiales
- Chiffrement d'index
- Saut de données avec jointures (pour Spark 3 uniquement)
- Exemples illustrant ces fonctions
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 colonnecity
avec une probabilité de faux positif de0.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.
- 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
- La colonne de noms d'objet stocke les noms de tous les objets indexés.
- La colonne de pied de page de l'objet métadonnées qui, en soi, est un fichier Parquet, contient, entre autres choses :
- 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.
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 :
Suivez toutes les étapes pour vérifier que PME est activé. Voir PME.
Effectuez toutes les configurations PME normales, y compris les configurations de gestion des clés.
Créez des métadonnées chiffrées pour un jeu de données :
- Suivez la procédure normale pour créer des métadonnées.
- 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
surtrue
(voir les exemples ci-dessous). - 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.