Calculer l'utilisation des ressources des comptes personnels en mode standard DataWorks

Contexte Lors de l'utilisation de MaxCompute, les utilisateurs analysent généralement les tâches SQL exécutées par un compte spécifique via la table de vue Task_history du schéma d'information pour obtenir l'allocation des coûts SQL ou l'optimisation des coûts de temps SQL. Cependant, la plupart des utilisateurs utilisent MaxCompute en mode standard DataWorks. De cette façon, les informations de vue des métadonnées fournies par MaxCompute enregistreront tous les comptes d'exécution des travaux de production comme le même compte principal, et seule une petite partie des comptes d'exécution des travaux de développement sont des sous-comptes RAM personnels. Cet article présente principalement comment compter l'utilisation des ressources des comptes personnels en mode standard DataWorks.

Comme le montre la figure ci-dessus, la plupart des coûts ne peuvent pas être mis à niveau vers des comptes RAM spécifiques, et les audits et allocations de coûts ne peuvent pas être effectués. Solution Lorsque vous utilisez DataWorks pour développer des travaux MaxCompute, chaque nœud a une personne responsable et la valeur par défaut est le développeur actuel, qui est le sous-compte RAM actuel. Si vous pouvez obtenir ces informations et la correspondance du schéma d'information. Obtention de l'ID de la personne responsable du nœud Dans la page DataWorks, la personne responsable d'un nœud est la suivante:

 

Prenez l'exemple de la vue d'un travail exécuté dans un environnement de production réel, comme suit:

"SKYNET_ONDUTY": "219292777233523137" est la valeur que nous voulons obtenir. SKYNET_ONDUTY représente la personne responsable du nœud, et la valeur derrière est l'ID de la personne responsable (compte cloud et sous-compte) du nœud. Ou nous pouvons obtenir l'ID via la table task_history du schéma d'information. Cette valeur est enregistrée dans le champ des paramètres de la table task_history du schéma d'information et doit être analysée une fois. L'ID de compte obtenu par l'analyse est l'ID de la personne responsable du nœud (compte cloud et sous-compte).

 

 
 

- 示例 代码 : SELECT inst_id, settings, REGEXP_EXTRACT (settings, '"SKYNET_ONDUTY": "(. *?)"', 1) AS SKYNET_ONDUTY FROM information_schema.tasks_history OERE ds = 20200402 et inst_id = '20200402064857130g8zorj

L'obtention d'un sous-compte RAM ne peut obtenir qu'un seul ID à travers les étapes ci-dessus, et doit également obtenir quel sous-compte ou compte cloud correspondant à l'ID via l' API RAM .

 
 

{"requestId": "1CFF97CC-DD17-4C69-9AC7-7E869B8857AC", "isTruncated": false, "users": [{"userId": "219292777233523137", "userName": "mc_oss", "displayName": "" mc_oss "," comments ":" "," createDate ":" 2019-12-25T00: 25: 23Z "," updateDate ":" 2020-02-24T03: 44: 04Z "}, {" userId ":" 218915375439469278 "," userName ":" bigdata_wei "," displayName ":" bigdata_wei "," commentaires ":" "," createDate ":" 2019-12-04T06: 04: 29Z "," updateDate ":" 2020-02- 21T01: 43: 37Z "}]}

Ici, nous devons capturer les résultats et stocker et analyser nous-mêmes UserName et UserId. UserId est l'ID du propriétaire du nœud. La référence logique du code d'implémentation de l'API est la suivante (1) Créer une table pour stocker le nom d'utilisateur et l'ID utilisateur obtenus

 
 

créer la table liste_utilisateurs (chaîne UserName, chaîne UserId);

(2) ListUsers.java

 
 

importer Utils.Configurations; import Utils.ODPS; import com.aliyun.odps.Odps; import com.aliyun.odps.Table; import com.aliyun.odps.data.Record; import com.aliyun.odps.data.RecordWriter; import com.aliyun.odps.tunnel.TableTunnel; import com.aliyun.odps.tunnel.TunnelException; import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.IAcsClient; import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.exceptions.ServerException; import com.aliyuncs.profile.DefaultProfile; import com.aliyuncs.ram.model.v20150501.ListUsersRequest; import com.aliyuncs.ram.model.v20150501.ListUsersResponse; import java.io.IOException; import java.util.List; import java.util.Properties; public class ListUsers {public static void main (String [] args) {Properties properties = Configurations.properties (); String ai = properties.getProperty ("access_id"); String ak = properties.getProperty ("access_key"); String project = properties.getProperty ("project_name"); Profil DefaultProfile = DefaultProfile.getProfile ("cn-beijing", ai, ak); Client IAcsClient = nouveau DefaultAcsClient (profil); ListUsersRequest request = new ListUsersRequest (); request.setRegionId ("cn-beijing"); try {ListUsersResponse response = client.getAcsResponse (request); List <ListUsersResponse.User> users = response.getUsers (); // 打开 表 Odps odps = ODPS.newOdps (ai, ak, project); Table table = odps.tables (). Get ("liste_utilisateurs"); TableTunnel.UploadSession uploadSession = new TableTunnel (odps) .createUploadSession (project, table.getName ()); // 遍历 写到 表 中 Enregistreur RecordWriter = uploadSession.openBufferedWriter (); for (ListUsersResponse.User user: users) {Record record = uploadSession.newRecord (); record.setString ("nom d'utilisateur", user.getUserName ()); record.setString ("userid", user.getUserId ()); System.out.println ("写入 数据" + user.getUserId () + ":" + user.getUserName ()); writer.write (enregistrement); } writer.close (); uploadSession.commit (); System.out.println ("写入 完成 ..."); } catch (ServerException e) {e.printStackTrace (); } catch (ClientException e) {System.out.println ("ErrCode:" + e.getErrCode ()); System.out.println ("ErrMsg:" + e.getErrMsg ()); System.out.println ("RequestId:" + e.getRequestId ()); } catch (TunnelException e) {System.out.println ("创建 table 上传 session 失败"); System.out.println (e.getMessage ()); } catch (IOException e) {System.out.println ("写 数据 到 表 失败"); System.out.println (e.getMessage ()); }}} getUserName ()); record.setString ("userid", user.getUserId ()); System.out.println ("写入 数据" + user.getUserId () + ":" + user.getUserName ()); writer.write (enregistrement); } writer.close (); uploadSession.commit (); System.out.println ("写入 完成 ..."); } catch (ServerException e) {e.printStackTrace (); } catch (ClientException e) {System.out.println ("ErrCode:" + e.getErrCode ()); System.out.println ("ErrMsg:" + e.getErrMsg ()); System.out.println ("RequestId:" + e.getRequestId ()); } catch (TunnelException e) {System.out.println ("创建 table 上传 session 失败"); System.out.println (e.getMessage ()); } catch (IOException e) {System.out.println ("写 数据 到 表 失败"); System.out.println (e.getMessage ()); }}} getUserName ()); record.setString ("userid", user.getUserId ()); System.out.println ("写入 数据" + user.getUserId () + ":" + user.getUserName ()); writer.write (enregistrement); } writer.close (); uploadSession.commit (); System.out.println ("写入 完成 ..."); } catch (ServerException e) {e.printStackTrace (); } catch (ClientException e) {System.out.println ("ErrCode:" + e.getErrCode ()); System.out.println ("ErrMsg:" + e.getErrMsg ()); System.out.println ("RequestId:" + e.getRequestId ()); } catch (TunnelException e) {System.out.println ("创建 table 上传 session 失败"); System.out.println (e.getMessage ()); } catch (IOException e) {System.out.println ("写 数据 到 表 失败"); System.out.println (e.getMessage ()); }}} getUserId () + ":" + user.getUserName ()); writer.write (enregistrement); } writer.close (); uploadSession.commit (); System.out.println ("写入 完成 ..."); } catch (ServerException e) {e.printStackTrace (); } catch (ClientException e) {System.out.println ("ErrCode:" + e.getErrCode ()); System.out.println ("ErrMsg:" + e.getErrMsg ()); System.out.println ("RequestId:" + e.getRequestId ()); } catch (TunnelException e) {System.out.println ("创建 table 上传 session 失败"); System.out.println (e.getMessage ()); } catch (IOException e) {System.out.println ("写 数据 到 表 失败"); System.out.println (e.getMessage ()); }}} getUserId () + ":" + user.getUserName ()); writer.write (enregistrement); } writer.close (); uploadSession.commit (); System.out.println ("写入 完成 ..."); } catch (ServerException e) {e.printStackTrace (); } catch (ClientException e) {System.out.println ("ErrCode:" + e.getErrCode ()); System.out.println ("ErrMsg:" + e.getErrMsg ()); System.out.println ("RequestId:" + e.getRequestId ()); } catch (TunnelException e) {System.out.println ("创建 table 上传 session 失败"); System.out.println (e.getMessage ()); } catch (IOException e) {System.out.println ("写 数据 到 表 失败"); System.out.println (e.getMessage ()); }}} } catch (ClientException e) {System.out.println ("ErrCode:" + e.getErrCode ()); System.out.println ("ErrMsg:" + e.getErrMsg ()); System.out.println ("RequestId:" + e.getRequestId ()); } catch (TunnelException e) {System.out.println ("创建 table 上传 session 失败"); System.out.println (e.getMessage ()); } catch (IOException e) {System.out.println ("写 数据 到 表 失败"); System.out.println (e.getMessage ()); }}} } catch (ClientException e) {System.out.println ("ErrCode:" + e.getErrCode ()); System.out.println ("ErrMsg:" + e.getErrMsg ()); System.out.println ("RequestId:" + e.getRequestId ()); } catch (TunnelException e) {System.out.println ("创建 table 上传 session 失败"); System.out.println (e.getMessage ()); } catch (IOException e) {System.out.println ("写 数据 到 表 失败"); System.out.println (e.getMessage ()); }}}

(3) Créez un répertoire Utils sous src et placez les fichiers suivants Configurations.java, ODPS.java.

 
 

a. Configurations.java package Utils; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import java.util.ResourceBundle; public class Configurations {* obtenir des informations sur le fichier de configuration * * @return * / public static Properties properties properties () {Properties properties = new Properties (); // Utilisez ClassLoader pour charger le fichier de configuration des propriétés pour générer le flux d'entrée correspondant InputStream dans = Configurations.class.getClassLoader (). getResourceAsStream ("common.properties"); / / Utilisez l'objet de propriétés pour charger le flux d'entrée, essayez {properties.load (in); return properties;} catch (IOException e) {System.out.println ("Le fichier de configuration n'a pas été lu correctement" + e.getMessage ());} return null;} / ** * Lire le fichier de configuration * * @return * / public static ResourceBundle read () {// config est le nom du fichier de propriétés, placé dans le package com.test.config, s'il est placé sous src, directement Utilisez la configuration de ResourceBundle resourceBundle = ResourceBundle.getBundle ("common"); return resourceBundle;}}

 

b. Package ODPS.java Utils; import com.aliyun.odps.Odps; ​​import com.aliyun.odps.account.Account; import com.aliyun.odps.account.AliyunAccount; classe publique ODPS {/ ** * dans le réseau externe Utilisez pour obtenir l'objet de connexion d'odps * * @param ai * @param ak * @param project * @return * / static public Odps newOdps (String ai, String ak, String project) {Account account = new AliyunAccount (ai, ak) ; Odps odps = new Odps (compte); odps.setDefaultProject (project); return odps;} / ** * Utilisez dans l'intranet pour obtenir l'objet de connexion odps * * @param ai * @param ak * @param project * @param odpsUrl * @return * / static public Odps newOdps (String ai, String ak, String project, String odpsUrl) {Account account = new AliyunAccount (ai, ak); Odps odps = new Odps (account); odps.setEndpoint ( odpsUrl); odps.setDefaultProject (project); return odps;}}

(4) mettez common.properties dans le chemin des ressources

 
 

# Compte principal: project_name = access_id = access_key =

Après les étapes «Obtenir l'ID de responsabilité du nœud» et «Obtenir le sous-compte RAM», les informations de base sont déjà disponibles et vous devez effectuer une jointure pour obtenir le compte ou le sous-compte cloud spécifique correspondant à l'ID instance.

 

 
 

- 示例 代码 : sélectionnez a.UserName, b.SKYNET_ONDUTY dans users_list une jointure (SELECT inst_id, settings, REGEXP_EXTRACT (settings, '"SKYNET_ONDUTY": "(. *?)"', 1) AS SKYNET_ONDUTY FROM information_schema.tasks_history WHERE ds = 20200402 et inst_id = '20200402064857130g8zorjim') b sur a.UserId = b.SKYNET_ONDUTY;

⚠️: La date d'exécution de la tâche ds et inst_id doivent être remplacées en fonction de leurs propres tâches. Calculer la répartition des coûts / les exigences d'audit 1. MaxCompute fournit au service Information_Schema des métadonnées ouvertes. Grâce au tableau d'historique des tâches tasks_history du service de métadonnées Information_Schema, vous pouvez interroger les détails en temps quasi réel de l'historique des opérations du projet. Y compris: nom du projet, nom de la tâche, identifiant d'instance, heure de début, heure de fin, complexité de la tâche, utilisation du processeur de la tâche et autres champs. 2. Les utilisateurs peuvent consulter la consommation spécifique via le centre de dépenses overview aperçu du compte  enregistrements de consommation. Parallèlement, la gestion des transactions et des factures d'Alibaba Cloud, OpenAPI, offre aux utilisateurs la possibilité de gérer les ventes et la trésorerie des produits d'Alibaba Cloud. Grâce à cette API, les détails de facturation des opérations MaxCompute peuvent être obtenus par programmation. En appelant l'interface QueryUserOmsData (OMS du système de facturation d'Alibaba Cloud), vous pouvez interroger un numéro spécifique d'informations de mesure, une classification des données, un stockage, un volume de lecture SQL, un trafic Internet public en aval et d'autres informations sur le terrain. Via Information_Schema.tasks_history et le système de facturation pour calculer plus en détail les exigences de répartition / audit des coûts.

Pour le cloud, voir Yunqi: plus d'informations sur le cloud, les cas de cloud, les meilleures pratiques, l'introduction du produit, visitez: https://yqh.aliyun.com/

Cet article est le contenu original d'Alibaba Cloud et ne peut être reproduit sans autorisation.

Publié 1217 articles originaux · 90 éloges · 230 000 vues +

Je suppose que tu aimes

Origine blog.csdn.net/weixin_43970890/article/details/105518634
conseillé
Classement