Saat mengembangkan dengan MaxCompute, Anda mungkin perlu menganalisis biaya akun dan durasi pekerjaan untuk merencanakan serta menyesuaikan pekerjaan secara lebih efektif. Topik ini menjelaskan cara menggunakan metadata MaxCompute (Information Schema) untuk mengidentifikasi akun penagihan teratas dan pekerjaan yang paling memakan waktu. Informasi ini juga dapat didorong ke grup DingTalk.
Informasi latar belakang
Pengembang data sering menggunakan MaxCompute dalam mode standar DataWorks. Dalam mode ini, MaxCompute mencatat akun root yang sama di Information Schema sebagai pelaksana untuk sebagian besar pekerjaan, sementara hanya beberapa pekerjaan yang dijalankan oleh pengguna Resource Access Management (RAM). Hal ini menyulitkan analisis biaya dan durasi pekerjaan berdasarkan akun individu. MaxCompute menawarkan solusi berikut:
Biaya akun: Anda dapat meninjau detail penggunaan dalam tagihan Anda. Namun, metode ini tidak mengaitkan penggunaan dengan pengguna RAM tertentu. Tampilan TASKS_HISTORY di Information Schema mencatat detail pekerjaan yang telah selesai di proyek MaxCompute Anda selama 14 hari terakhir. Anda dapat melakukan backup data dari TASKS_HISTORY ke proyek MaxCompute dan menggunakannya untuk mengidentifikasi akun penagihan teratas.
Pekerjaan yang memakan waktu: Anda dapat menggunakan data di TASKS_HISTORY untuk mengidentifikasi pekerjaan yang paling memakan waktu.
Untuk informasi selengkapnya tentang fitur dan batasan Information Schema, lihat Project-level Information Schema.
Proses untuk menganalisis akun penagihan top N dan pekerjaan yang memakan waktu adalah sebagai berikut:
Langkah 1: Dapatkan layanan Information Schema
Mulai 1 Maret 2024, MaxCompute tidak lagi secara otomatis menginstal paket Information Schema tingkat proyek untuk proyek baru secara default. Jika Anda memiliki layanan yang perlu mengkueri metadata, Anda dapat mengkueri Information Schema tingkat tenant untuk mendapatkan informasi yang lebih lengkap. Untuk informasi selengkapnya tentang cara menggunakan Information Schema tingkat tenant, lihat Tenant-level Information Schema.
Untuk proyek MaxCompute yang sudah ada, Anda harus menginstal paket izin Information Schema sebelum dapat menggunakan layanan Information Schema. Instalasi ini harus dilakukan oleh pemilik proyek atau pengguna Resource Access Management (RAM) dengan role Super_Administrator untuk mendapatkan izin mengakses metadata proyek. Untuk informasi selengkapnya tentang cara memberikan role management kepada pengguna, lihat Berikan role kepada pengguna. Anda dapat menginstal paket dengan salah satu dari dua cara berikut:
Login ke MaxCompute client dan jalankan perintah berikut:
install package Information_Schema.systables;Login ke DataWorks console dan buka halaman Ad-hoc Query. Untuk informasi selengkapnya tentang kueri ad-hoc, lihat Gunakan kueri ad-hoc untuk menjalankan pernyataan SQL (opsional). Jalankan perintah berikut:
install package Information_Schema.systables;
Untuk menganalisis metadata dari beberapa proyek MaxCompute, instal paket izin Information Schema untuk setiap proyek. Kemudian, masukkan backup metadata dari semua proyek ke dalam satu tabel untuk dianalisis.
(Opsional) Langkah 2: Berikan izin kepada pengguna selain pemilik proyek
Tampilan Information Schema berisi semua data pengguna di tingkat proyek. Secara default, pemilik proyek dapat melihat data ini. Jika pengguna atau role lain di proyek perlu melihatnya, Anda harus memberikan izin kepada mereka. Untuk informasi selengkapnya, lihat Akses resource lintas proyek berdasarkan paket.
Sintaks untuk memberikan izin adalah sebagai berikut.
grant <actions> on package Information_Schema.systables to user <user_name>;
grant <actions> on package Information_Schema.systables to role <role_name>;actions: Izin yang diberikan. Nilainya harus Read.
user_name: Akun Alibaba Cloud atau pengguna RAM yang telah ditambahkan ke proyek.
Anda dapat menjalankan perintah
list users;di MaxCompute client untuk mendapatkan akun pengguna.role_name: Role yang telah ditambahkan ke proyek.
Anda dapat menjalankan perintah
list roles;di MaxCompute client untuk mendapatkan nama role.
Contoh berikut menunjukkan cara memberikan izin.
grant read on package Information_Schema.systables to user RAM$Bob@aliyun.com:user01;Langkah 3: Unduh dan backup metadata
Buat tabel backup metadata di proyek MaxCompute Anda dan jadwalkan tugas berulang untuk menulis metadata ke dalamnya. Langkah-langkah berikut memberikan contoh yang menggunakan MaxCompute client:
Login ke MaxCompute client dan jalankan perintah berikut untuk membuat tabel backup metadata.
-- project_name adalah nama proyek MaxCompute Anda. CREATE TABLE if NOT EXISTS <project_name>.information_history ( task_catalog STRING ,task_schema STRING ,task_name STRING ,task_type STRING ,inst_id STRING ,`status` STRING ,owner_id STRING ,owner_name STRING ,result STRING ,start_time DATETIME ,end_time DATETIME ,input_records BIGINT ,output_records BIGINT ,input_bytes BIGINT ,output_bytes BIGINT ,input_tables STRING ,output_tables STRING ,operation_text STRING ,signature STRING ,complexity DOUBLE ,cost_cpu DOUBLE ,cost_mem DOUBLE ,settings STRING ,ds STRING );Buka antarmuka DataWorks Data Studio, buat node ODPS SQL (information_history), dan konfigurasikan penjadwalan berkala untuk secara periodik menulis data ke tabel backup information_history. Lalu, klik ikon
di pojok kiri atas untuk menyimpan node tersebut.Untuk informasi selengkapnya, lihat Buat node ODPS SQL.
Kode berikut menunjukkan contoh perintah yang dijalankan pada node ODPS SQL:
-- project_name adalah nama proyek MaxCompute. use <project_name>; insert into table <project_name>.information_history select * from information_schema.tasks_history where ds ='datetime1';${datetime1}adalah parameter penjadwalan DataWorks. Di sebelah kanan node ODPS SQL, klik Scheduling Configuration. Pada bagian Basic Properties, atur Parameter menjadidatetime1=${yyyymmdd}.CatatanUntuk menganalisis metadata dari beberapa proyek MaxCompute secara bersamaan, buat beberapa node ODPS SQL. Konfigurasikan setiap node untuk menulis metadata dari proyek yang berbeda ke dalam tabel backup yang sama.
Langkah 4: Buat pekerjaan untuk menganalisis akun penagihan top N dan pekerjaan yang memakan waktu
Bidang settings di tampilan TASKS_HISTORY mencatat informasi dari penjadwal atau pengguna dalam format JSON. Informasi ini mencakup useragent, bizid, skynet_id, dan skynet_nodename. Anda dapat menggunakan bidang settings untuk mengidentifikasi pengguna RAM yang membuat pekerjaan tersebut. Hal ini memungkinkan Anda menggunakan tabel backup untuk menemukan akun penagihan top N dan pekerjaan yang memakan waktu. Langkah-langkahnya adalah sebagai berikut:
Login ke MaxCompute client dan buat tabel detail pengguna RAM bernama user_ram. Tabel ini akan mencatat akun dan ID akun yang akan dianalisis.
Kode berikut menunjukkan contoh perintah:
CREATE TABLE if NOT EXISTS <project_name>.user_ram ( user_id STRING ,user_name STRING );Buat tabel detail bernama cost_topn untuk mencatat detail akun penagihan top N.
Kode berikut menunjukkan contoh perintah:
CREATE TABLE if NOT EXISTS <project_name>.cost_topn ( cost_sum DECIMAL(38,5) ,task_owner STRING ) partitioned BY ( ds STRING );Buat tabel detail bernama time_topn untuk mencatat detail pekerjaan yang memakan waktu top N.
Kode berikut menunjukkan contoh perintah:
CREATE TABLE if NOT EXISTS <project_name>.time_topn ( inst_id STRING ,cost_time BIGINT ,task_owner STRING ) partitioned BY ( ds STRING );Buka antarmuka DataWorks Data Studio. Buat node ODPS SQL (topn) dan konfigurasikan penjadwalan berkala untuk secara periodik menulis data statistik dari tabel `cost_topn` ke tabel `user_ram`. Lalu, klik ikon
di pojok kiri atas untuk menyimpan node tersebut.Untuk informasi selengkapnya, lihat Buat node ODPS SQL.
Kode berikut menunjukkan contoh perintah yang dijalankan pada node ODPS SQL:
-- Aktifkan tipe data 2.0. Untuk informasi selengkapnya tentang tipe data 2.0, lihat edisi tipe data. SET odps.sql.decimal.odps2=true; -- Tulis metadata ke tabel cost_topn dan time_topn. user_id adalah ID akun. Anda dapat menemukan ID akun di halaman informasi pribadi Anda. INSERT INTO TABLE <project_name>.cost_topn PARTITION (ds = '${datetime1}') SELECT NVL(cost_sum,0) cost_sum ,CASE WHEN a.task_owner='<user_id>' OR a.task_owner='<user_id>' OR a.task_owner='<user_id>' THEN b.user_name ELSE a.task_owner END task_owner FROM ( SELECT inst_id ,owner_name ,task_type ,a.input_bytes ,a.cost_cpu ,a.status ,CASE WHEN a.task_type = 'SQL' THEN CAST(a.input_bytes/1024/1024/1024 * a.complexity * 0.3 AS DECIMAL(18,5) ) WHEN a.task_type = 'SQLRT' THEN CAST(a.input_bytes/1024/1024/1024 * a.complexity * 0.3 AS DECIMAL(18,5) ) WHEN a.task_type = 'CUPID' AND a.status='Terminated' THEN CAST(a.cost_cpu/100/3600 * 0.66 AS DECIMAL(18,5) ) ELSE 0 END cost_sum ,a.settings ,GET_JSON_OBJECT(settings, "$.SKYNET_ONDUTY") owner ,CASE WHEN GET_JSON_OBJECT(a.settings, "$.SKYNET_ONDUTY") IS NULL THEN owner_name ELSE GET_JSON_OBJECT(a.settings, "$.SKYNET_ONDUTY") END task_owner FROM information_history WHERE ds = '${datetime1}' ) a LEFT JOIN <project_name>.user_ram b ON a.task_owner = b.user_id; INSERT INTO TABLE <project_name>.time_topn PARTITION(ds = '${datetime1}') SELECT inst_id ,cost_time ,CASE WHEN a.task_owner='<user_id>' OR a.task_owner='<user_id>' OR a.task_owner='<user_id>' THEN b.user_name ELSE a.task_owner END task_owner FROM ( SELECT inst_id ,task_type ,status ,DATEDIFF(a.end_time, a.start_time, 'ss') AS cost_time ,CASE WHEN GET_JSON_OBJECT(a.settings, "$.SKYNET_ONDUTY") IS NULL THEN owner_name ELSE GET_JSON_OBJECT(a.settings, "$.SKYNET_ONDUTY") END task_owner FROM <project_name>.information_history a WHERE ds = '${datetime1}' ) a LEFT JOIN <project_name>.user_ram b ON a.task_owner = b.user_id;CatatanDalam contoh ini,
task_type = 'SQL'merepresentasikan pekerjaan SQL,task_type = 'SQLRT'merepresentasikan pekerjaan akselerasi kueri, dantask_type = 'CUPID'merepresentasikan pekerjaan Spark. Untuk menganalisis pekerjaan lain yang dikenai biaya, seperti pekerjaan MapReduce atau Mars, tambahkan baris kode berdasarkan formula penagihannya. Untuk informasi selengkapnya tentang penagihan, lihat Penagihan berbasis unit komputasi (pay-as-you-go).${datetime1}adalah parameter penjadwalan DataWorks. Di sebelah kanan node ODPS SQL, klik Scheduling Configuration. Pada bagian Basic Properties, atur Parameter menjadidatetime1=${yyyymmdd}.
Langkah 5: Buat chatbot grup DingTalk dan dorong informasi tentang akun penagihan top N dan pekerjaan yang memakan waktu
Langkah-langkah berikut menunjukkan cara membuat chatbot grup DingTalk dan mendorong informasi tentang akun penagihan top N serta pekerjaan yang memakan waktu. Contoh ini menggunakan klien PC DingTalk.
Buat chatbot grup DingTalk.
Pilih grup DingTalk target dan klik ikon
di pojok kanan atas.Pada panel Group Settings, klik Smart Group Assistant.
Pada panel Smart Group Assistant, klik Add Robot.
Pada bagian Add Robot di kotak dialog Group Robot, klik ikon
.Di kotak dialog Group Robot, klik Custom.
Di kotak dialog Robot Details, klik Add.
Di kotak dialog Add Robot, edit informasi robot.
Property Name
Configure Rules
Profile picture
Klik ikon
di pojok kanan bawah gambar profil untuk mengeditnya.Robot Name
Masukkan nama untuk robot tersebut.
Security Settings
Konfigurasikan pengaturan keamanan yang diperlukan (pilih minimal satu), pilih I have read and agree to the "Custom Robot Service and Disclaimer", lalu klik Finish.
Terdapat tiga jenis pengaturan keamanan:
Custom Keywords: Anda dapat mengatur hingga 10 kata kunci.
Add Signature: Pilih Add Signature untuk mendapatkan kunci robot.
IP Address (Range): Hanya permintaan dari rentang alamat IP yang ditentukan yang akan diproses.
Di kotak dialog Add Robot, salin URL Webhook yang dihasilkan. Lalu, klik Finish.
PentingJaga kerahasiaan URL Webhook. Jangan mempostingnya di situs web eksternal. Kebocoran URL dapat menyebabkan risiko keamanan.
Gunakan IntelliJ IDEA untuk membuat proyek Maven dan kompilasi program Java yang mendorong pesan ke grup DingTalk. Setelah dikompilasi, paket JAR akan dihasilkan.
Untuk informasi selengkapnya tentang cara menggunakan IntelliJ IDEA, klik Help di pojok kanan atas antarmuka IntelliJ IDEA.
Konfigurasikan dependensi Pom.
Kode berikut menunjukkan dependensi Pom.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>DingTalk_Information</groupId> <artifactId>DingTalk_Information</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>com.aliyun.odps</groupId> <artifactId>odps-sdk-core</artifactId> <version>0.35.5-public</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.15</version> <exclusions> <exclusion> <groupId>com.sun.jmx</groupId> <artifactId>jmxri</artifactId> </exclusion> <exclusion> <groupId>com.sun.jdmk</groupId> <artifactId>jmxtools</artifactId> </exclusion> <exclusion> <groupId>javax.jms</groupId> <artifactId>jms</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>alibaba-dingtalk-service-sdk</artifactId> <version>1.0.1</version> </dependency> <dependency> <groupId>com.aliyun.odps</groupId> <artifactId>odps-jdbc</artifactId> <version>3.0.1</version> <classifier>jar-with-dependencies</classifier> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>2.4.1</version> <configuration> <!-- get all project dependencies --> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <!-- MainClass in mainfest make a executable jar --> <archive> <manifest> <mainClass>com.alibaba.sgri.message.test</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <!-- bind to the packaging phase --> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>Kembangkan program Java dan hasilkan paket JAR topn_new.jar.
Kode berikut menunjukkan contoh Java:
package com.alibaba.sgri.message; import java.io.IOException; import java.util.concurrent.atomic.AtomicInteger; import com.aliyun.odps.Instance; import com.aliyun.odps.Odps; import com.aliyun.odps.OdpsException; import com.aliyun.odps.account.Account; import com.aliyun.odps.account.AliyunAccount; import com.aliyun.odps.data.ResultSet; import com.aliyun.odps.task.SQLTask; import com.dingtalk.api.DefaultDingTalkClient; import com.dingtalk.api.DingTalkClient; import com.dingtalk.api.request.OapiRobotSendRequest; import com.dingtalk.api.response.OapiRobotSendResponse; import com.taobao.api.ApiException; public class test { public static void main(String[] args) throws ApiException { if (args.length < 1) { System.out.println("Please enter the date parameter."); System.exit(0); } System.out.println("Start reading data."); DingTalkClient client = new DefaultDingTalkClient( "<Your chatbot's Webhook URL>"); OapiRobotSendRequest request = new OapiRobotSendRequest(); request.setMsgtype("markdown"); OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown(); // The date here is used as a parameter. markdown.setText(getContent(args[0])); markdown.setTitle("Top N jobs by consumption"); request.setMarkdown(markdown); OapiRobotSendResponse response = client.execute(request); System.out.println("Message sent successfully."); } /** * Read from ODPS to get the data to send. */ public static String getContent(String day) { Odps odps = createOdps(); StringBuilder sb = new StringBuilder(); try { //==================Billing accounts===================== String costTopnSql = "select sum(cost_sum)cost_sum,task_owner from cost_topn where ds='" + day + "' " + "group by task_owner order by cost_sum desc limit 5;"; Instance costInstance = SQLTask.run(odps, costTopnSql); costInstance.waitForSuccess(); ResultSet costTopnRecords = SQLTask.getResultSet(costInstance); sb.append("<font color=#FF0000 size=4>").append("Top N Billing Accounts (").append(day).append( ")[Calculated based on Alibaba Cloud pay-as-you-go billing]").append("</font>").append("\n\n"); AtomicInteger costIndex = new AtomicInteger(1); costTopnRecords.forEach(item -> { sb.append(costIndex.getAndIncrement()).append(".").append("Account:"); sb.append("<font color=#2E64FE>").append(item.getString("task_owner")).append("\n\n").append("</font>"); sb.append(" ").append(" ").append("Cost:").append("<font color=#2E64FE>").append(item.get("cost_sum")) .append(" CNY").append( "</font>").append("\n\n") .append("</font>"); }); //==================Time-consuming jobs===================== String timeTopnSql = "select * from time_topn where ds='" + day + "' ORDER BY cost_time DESC limit 5;"; Instance timeInstance = SQLTask.run(odps, timeTopnSql); timeInstance.waitForSuccess(); ResultSet timeTopnRecords = SQLTask.getResultSet(timeInstance); sb.append("<font color=#FF8C00 size=4>").append("Top N Time-consuming Jobs (").append(day).append(")") .append("\n\n").append("</font>"); AtomicInteger timeIndex = new AtomicInteger(1); timeTopnRecords.forEach(item -> { sb.append(timeIndex.getAndIncrement()).append(".").append("Job:"); sb.append("<font color=#2E64FE>").append(item.getString("inst_id")).append("\n\n").append("</font>"); sb.append(" ").append("Account:").append("<font color=#2E64FE>").append(item.getString("task_owner")).append("\n\n").append("</font>"); sb.append(" ").append("Duration:").append("<font color=#2E64FE>").append(item.get("cost_time")) .append("s").append( "</font>").append("\n\n"); }); } catch (OdpsException | IOException e) { e.printStackTrace(); } return sb.toString(); } /** * Create an ODPS object. */ public static Odps createOdps() { String project = "<project_name>"; // An Alibaba Cloud account AccessKey has permissions to access all APIs. This poses a high security risk. We strongly recommend that you create and use a RAM user to make API calls or perform O&M. To create a RAM user, log on to the RAM console. // This example shows how to store the AccessKey ID and AccessKey secret in environment variables. You can also store them in a configuration file as needed. // We strongly recommend that you do not hard-code the AccessKey ID and AccessKey secret in your code. This can lead to key leakage. String accessId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"); String accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"); String endPoint = "http://service.odps.aliyun.com/api"; Account account = new AliyunAccount(accessId, accessKey); Odps odps = new Odps(account); odps.setEndpoint(endPoint); odps.setDefaultProject(project); return odps; } }Unggah paket topn_new.jar yang dihasilkan sebagai resource MaxCompute.
Untuk informasi selengkapnya, lihat Buat dan gunakan resource MaxCompute.
Buat node Shell bernama dingsend, referensikan paket topn_new.jar, dan konfigurasikan jadwal berulang.
Untuk informasi selengkapnya, lihat Node Shell.
Kode berikut menunjukkan contoh perintah yang dijalankan pada node Shell:
java -jar topn_new.jar $1$1adalah parameter penjadwalan DataWorks. Di sebelah kanan node Shell, klik Scheduling Configuration. Pada bagian Basic Properties, atur Parameter menjadi${yyyymmdd}.
Langkah 6: Konfigurasikan properti penjadwalan untuk node leluhur dan node turunan serta jalankan node tersebut
Di panel alur bisnis, hubungkan node information_history, topn, dan dingsend untuk membuat dependensi. Konfigurasikan properti rerun dan dependensi node leluhur untuk setiap node. Setelah konfigurasi selesai, klik kanan pada node dan pilih Run Node.
Untuk informasi selengkapnya tentang cara mengonfigurasi dependensi, lihat Konfigurasikan dependensi penjadwalan siklus yang sama.
Untuk informasi selengkapnya tentang cara mengonfigurasi node leluhur dan node turunan, lihat Konfigurasikan konteks node.
Referensi
Dukungan online
Jika Anda memiliki pertanyaan atau saran saat menggunakan MaxCompute, Anda dapat mengirimkan tiket untuk menghubungi dukungan teknis.