Vous pouvez utiliser l'API SelectObject pour exécuter des instructions SQL sur des objets et récupérer les résultats.
Contexte
Hadoop 3.0 permet d'exécuter des services tels que Spark, Hive et Presto sur E-MapReduce (EMR) afin de traiter les données stockées dans Object Storage Service (OSS). Les services Alibaba Cloud tels que MaxCompute et Data Lake Analytics (DLA) prennent également en charge le traitement direct des données depuis OSS.
Traditionnellement, les plateformes Big Data utilisent l'API GetObject pour télécharger des objets entiers depuis OSS avant de les filtrer et de les analyser.
L'API SelectObject résout ce problème en déportant la logique de requête, telle que les projections et les filtres, vers la couche OSS. Cela vous permet de récupérer uniquement le sous-ensemble de données nécessaire, réduisant ainsi les transferts de données, diminuant les coûts et économisant le CPU et la mémoire côté client. Cette efficacité rend l'analyse des données sur OSS plus attrayante.
Facturation
Lorsque vous utilisez l'API SelectObject pour interroger des données, vous êtes facturé en fonction du volume réel de données analysées à partir de l'objet source. Pour plus d'informations, consultez Frais de traitement des données.
Formats d'objets pris en charge
L'API SelectObject prend en charge des formats d'objets spécifiques ainsi qu'une syntaxe SQL dédiée.
Objets CSV conformes à la norme RFC 4180. Cela inclut les objets de type CSV, tels que TSV. Vous pouvez spécifier des délimiteurs de ligne, des délimiteurs de colonne et des caractères de guillemet personnalisés.
-
Objets JSON encodés en UTF-8. Deux formats sont pris en charge : DOCUMENT et LINES.
DOCUMENT : L'objet entier constitue un seul objet JSON valide.
LINES : L'objet est composé de plusieurs lignes, chaque ligne étant un objet JSON autonome. Les lignes sont séparées par un caractère de nouvelle ligne, tel que \n ou \r\n. Il n'est pas nécessaire de spécifier le délimiteur. Cependant, l'objet entier ne constitue pas un objet JSON valide.
Objets appartenant aux classes de stockage Standard et Infrequent Access. Les objets des classes de stockage Archive, Cold Archive ou Deep Cold Archive doivent être restaurés avant de pouvoir être interrogés.
Objets chiffrés à l'aide du chiffrement côté serveur avec des clés gérées par OSS ou une CMK gérée par KMS.
Syntaxe SQL prise en charge
Clauses SQL : SELECT, FROM, WHERE
Types de données : string, int (64 bits), double (64 bits), decimal (128 bits), timestamp et bool
-
Opérateurs : Logiques (AND, OR, NOT), Arithmétiques (+, -, *, /, %), De comparaison (>, =, <, >=, <=, !=) et Chaînes (LIKE, ||)
ImportantL'opérateur LIKE effectue une correspondance de motif sensible à la casse.
Types de données pris en charge
Par défaut, toutes les données d'un objet CSV sont traitées comme des chaînes de caractères. Vous pouvez utiliser la fonction CAST pour effectuer des conversions de type explicites.
L'exemple suivant montre comment utiliser une requête SQL pour convertir les valeurs des colonnes _1 et _2 en entiers :Select * from OSSOBject where cast (_1 as int) > cast(_2 as int)
L'API SelectObject prend également en charge la conversion implicite de type dans une clause WHERE. Par exemple, dans l'instruction suivante, les valeurs des première et deuxième colonnes sont implicitement converties en entiers :
Select _1 from ossobject where _1 + _2 > 100
Pour les objets JSON, si vous n'utilisez pas la fonction CAST, le type de données est déterminé par le contenu de l'objet. Les types de données JSON intégrés standard incluent null, bool, int64, double et string.
Exemples SQL
Cette section propose des exemples SQL pour les objets CSV et JSON.
-
CSV
Cas d'utilisation
Instruction SQL
Renvoyer les 10 premières lignes de données.
select * from ossobject limit 10
Renvoyer les entiers des première et troisième colonnes lorsque la valeur de la première colonne est supérieure à celle de la troisième.
select _1, _3 from ossobject where cast(_1 as int) > cast(_3 as int)
Renvoyer le nombre d'enregistrements de la première colonne commençant par « Chen ». (Remarque : Le caractère chinois après « like » doit être encodé en UTF-8.)
select count(*) from ossobject where _1 like 'Chen%'
Renvoyer tous les enregistrements dont l'horodatage de la deuxième colonne est postérieur au 09/08/2018 11:30:25 et dont la valeur de la troisième colonne est supérieure à 200.
select * from ossobject where _2 > cast('2018-08-09 11:30:25' as timestamp) and _3 > 200
Renvoyer la moyenne, la somme, le maximum et le minimum des nombres à virgule flottante de la deuxième colonne.
select AVG(cast(_6 as double)), SUM(cast(_6 as double)), MAX(cast(_6 as double)), MIN(cast(_6 as double)) from ossobject
Renvoyer tous les enregistrements où la chaîne concaténée des première et troisième colonnes commence par « Tom » et se termine par « Anderson ».
select * from ossobject where (_1
_3) like 'Tom%Anderson'
Renvoyer tous les enregistrements dont la valeur de la première colonne est divisible par 3.
select * from ossobject where (_1 % 3) = 0
Renvoyer tous les enregistrements dont la valeur de la première colonne est comprise entre 1995 et 2012.
select * from ossobject where _1 between 1995 and 2012
Renvoyer tous les enregistrements dont la valeur de la cinquième colonne est « N », « M », « G » ou « L ».
select * from ossobject where _5 in ('N', 'M', 'G', 'L')
Renvoyer tous les enregistrements où le produit des valeurs des deuxième et troisième colonnes est supérieur à la somme de 100 et de la valeur de la cinquième colonne.
select from ossobject where _2 _3 > _5 + 100
-
JSON
Supposons que vous disposiez de l'objet JSON suivant :
{ "contacts":[ { "firstName": "John", "lastName": "Smith", "isAlive": true, "age": 27, "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": "10021-3100" }, "phoneNumbers": [ { "type": "home", "number": "212 555-1234" }, { "type": "office", "number": "646 555-4567" }, { "type": "mobile", "number": "123 456-7890" } ], "children": [], "spouse": null },... # Additional contact nodes omitted for brevity. ]}Le tableau suivant présente des exemples SQL.
Cas d'utilisation
Instruction SQL
Renvoyer tous les enregistrements dont la valeur de age est 27.
select from ossobject.contacts[] s where s.age = 27
Renvoyer tous les numéros de téléphone domicile.
select s.number from ossobject.contacts[].phoneNumbers[] s where s.type = "home"
Renvoyer tous les enregistrements dont le conjoint (spouse) est null.
select * from ossobject s where s.spouse is null
Renvoyer tous les enregistrements sans enfants.
select * from ossobject s where s.children[0] is null
RemarqueIl n'existe pas de syntaxe dédiée pour représenter un tableau vide. Utilisez plutôt l'instruction précédente.
Cas d'utilisation
Les cas d'utilisation courants de SelectObject incluent l'interrogation parallèle de grands objets, l'interrogation d'objets JSON et l'analyse de fichiers journaux.
-
Interroger de grands objets en parallèle
À l'instar de la fonctionnalité de téléchargement multipart par plage d'octets fournie par l'API GetObject, l'API SelectObject prend en charge les requêtes parallèles. Vous pouvez diviser les données de deux manières :
Par ligne : Cette méthode de division des données est courante. Toutefois, pour des données clairsemées, la division par ligne peut entraîner une charge déséquilibrée entre les workers de requête.
Par split : Un split est un concept OSS relatif au partitionnement des données. Un split contient plusieurs lignes et chaque split a approximativement la même taille.
RemarqueLa division des données par split est plus efficace que la division par ligne.
Si vous pouvez confirmer que les colonnes de votre objet CSV ne contiennent pas de caractères de nouvelle ligne, la division par plage d'octets est plus simple car elle ne nécessite pas la création de métadonnées. Si les colonnes contiennent des caractères de nouvelle ligne ou si vous interrogez un objet JSON, suivez ces étapes :
Appelez l'API CreateSelectObjectMeta pour obtenir le nombre total de splits pour l'objet. Afin de réduire le temps d'analyse, nous vous recommandons d'appeler cette API de manière asynchrone avant de démarrer la requête.
En fonction de vos ressources côté client, déterminez le degré de parallélisme (n). Ensuite, divisez le nombre total de splits par n pour calculer le nombre de splits que chaque requête parallèle doit traiter.
Dans le corps de la requête, spécifiez la plage de splits à interroger, par exemple
split-range=1-20.Fusionnez les résultats de toutes les requêtes parallèles.
-
Interroger des objets JSON
Lorsque vous interrogez des objets JSON, restreignez le chemin JSON dans la clause FROM pour améliorer les performances.
Prenons l'exemple d'objet JSON suivant :
{ "contacts":[ { "firstName": "John", "lastName": "Smith", "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": "10021-3100" }, "phoneNumbers": [ { "type": "home", "number": "212 555-1234" }, { "type": "office", "number": "646 555-4567" }, { "type": "mobile", "number": "123 456-7890" } ] } ]}Pour trouver toutes les adresses postales dont le code postal commence par « 10021 », vous pouvez rédiger l'instruction SQL soit comme
select s.address.streetAddress from ossobject.contacts[*] s where s.address.postalCode like '10021%'soit commeselect s.streetAddress from ossobject.contacts[*].address s where s.postalCode like '10021%'.La deuxième instruction,
select s.streetAddress from ossobject.contacts[*].address s where s.postalCode like '10021%', offre de meilleures performances car son chemin JSON est plus précis. -
Gérer les nombres à virgule flottante haute précision dans les objets JSON
Lorsque vous devez effectuer des calculs avec des nombres à virgule flottante haute précision dans un objet JSON, nous vous recommandons de définir l'option
ParseJsonNumberAsStringsurtruepuis de convertir la valeur au type decimal. Par exemple, si un attributaa pour valeur 123456789.123456789, vous pouvez utiliser l'instructionselect s.a from ossobject s where cast(s.a as decimal) > 123456789.12345pour conserver la précision des données d'origine.
Procédure
Console OSS
Kits SDK OSS
CLI ossutil
Référence API
Les opérations décrites ci-dessus sont basées sur l'API SelectObject sous-jacente. Si vous avez des besoins avancés, vous pouvez effectuer des requêtes REST API directes. Lors de requêtes directes, vous devez calculer manuellement la signature d'authentification. Pour plus d'informations, consultez SelectObject.
> Select Content