全部产品
Search
文档中心

MaxCompute:Kontrol biaya komputasi

更新时间:Jul 06, 2025

Jika tagihan MaxCompute Anda terus meningkat dan biaya menjadi sulit dikelola, Anda dapat mengoptimalkan pekerjaan SQL dan pekerjaan MapReduce untuk mengurangi biaya komputasi. Topik ini menjelaskan cara mengontrol biaya komputasi untuk pekerjaan SQL dan pekerjaan MapReduce.

Estimasi biaya komputasi

Anda dapat memperkirakan biaya komputasi sebelum menjalankan pekerjaan komputasi. Untuk informasi lebih lanjut, lihat Alat TCO dalam topik "Pilih metode penagihan". Anda juga dapat mengonfigurasi peringatan untuk konsumsi sumber daya guna mencegah biaya tambahan yang tidak diinginkan. Jika biaya komputasi tinggi, Anda dapat menggunakan metode yang dijelaskan dalam topik ini untuk menguranginya.

Kontrol biaya komputasi pekerjaan SQL

Beberapa pekerjaan SQL yang memicu pemindaian tabel penuh menimbulkan biaya komputasi yang tinggi. Penjadwalan pekerjaan SQL yang sering dapat menyebabkan penumpukan pekerjaan, yang juga meningkatkan biaya komputasi. Jika terjadi penumpukan dan metode penagihan bayar sesuai pemakaian digunakan, pekerjaan akan antre dan memerlukan lebih banyak sumber daya. Akibatnya, tagihan yang dihasilkan keesokan harinya menjadi sangat tinggi. Anda dapat menggunakan metode berikut untuk mengontrol biaya komputasi pekerjaan SQL:

  • Hindari penjadwalan yang sering. MaxCompute menyediakan layanan komputasi untuk memproses sejumlah besar data sekaligus. Ini berbeda dari layanan komputasi waktu nyata. Jika pekerjaan SQL dieksekusi dalam interval pendek, frekuensi komputasi meningkat. Frekuensi komputasi yang meningkat dan eksekusi pekerjaan SQL yang tidak tepat menyebabkan peningkatan biaya komputasi. Jika Anda memerlukan penjadwalan yang sering, gunakan CostSQL untuk memperkirakan biaya pekerjaan SQL guna menghindari biaya tambahan.

  • Kurangi pemindaian tabel penuh. Anda dapat menggunakan metode berikut:

    • Tentukan parameter yang diperlukan untuk menonaktifkan fitur pemindaian tabel penuh. Anda dapat menonaktifkan fitur ini untuk Sesi atau Proyek.

      -- Nonaktifkan fitur untuk Sesi.
      set odps.sql.allow.fullscan=false;
      -- Nonaktifkan fitur untuk Proyek.
      SetProject odps.sql.allow.fullscan=false;
    • Pangkas kolom. Pemangkasan kolom memungkinkan sistem membaca data hanya dari kolom yang diperlukan. Kami merekomendasikan agar Anda tidak menggunakan pernyataan SELECT *. Hal ini karena pemindaian tabel penuh dipicu saat Anda mengeksekusi pernyataan tersebut.

      SELECT a,b FROM T WHERE e < 10;

      Dalam pernyataan ini, tabel T berisi kolom a, b, c, d, dan e. Namun, hanya kolom a, b, dan e yang dibaca.

    • Pangkas partisi. Pemangkasan partisi memungkinkan Anda menentukan kondisi filter untuk kolom kunci partisi. Dengan cara ini, sistem membaca data hanya dari partisi yang diperlukan. Ini menghindari kesalahan dan pemborosan sumber daya yang disebabkan oleh pemindaian tabel penuh.

      SELECT a,b FROM T WHERE partitiondate='2017-10-01';
    • Optimalkan kata kunci SQL yang menimbulkan biaya. Kata kunci tersebut meliputi JOIN, GROUP BY, ORDER BY, DISTINCT, dan INSERT INTO. Anda dapat mengoptimalkan kata kunci berdasarkan aturan berikut:

      • Sebelum operasi JOIN, Anda harus memangkas partisi. Jika tidak, pemindaian tabel penuh mungkin dilakukan. Untuk informasi lebih lanjut tentang skenario di mana pemangkasan partisi tidak berlaku, lihat Skenario di mana pemangkasan partisi tidak berlaku dalam topik "Periksa apakah pemangkasan partisi efektif".

      • Gunakan UNION ALL alih-alih FULL OUTER JOIN.

        SELECT COALESCE(t1.id, t2.id) AS id, SUM(t1.col1) AS col1
         , SUM(t2.col2) AS col2
        FROM (
         SELECT id, col1
         FROM table1
        ) t1
        FULL OUTER JOIN (
         SELECT id, col2
         FROM table2
        ) t2
        ON t1.id = t2.id
        GROUP BY COALESCE(t1.id, t2.id);
        -- Dioptimalkan:
        SELECT t.id, SUM(t.col1) AS col1, SUM(t.col2) AS col2
        FROM (
         SELECT id, col1, 0 AS col2
         FROM table1
         UNION ALL
         SELECT id, 0 AS col1, col2
         FROM table2
        ) t
        GROUP BY t.id;
      • Jangan masukkan GROUP BY dalam UNION ALL. Gunakan GROUP BY di luar UNION ALL.

        SELECT t.id, SUM(t.val) AS val
        FROM (
         SELECT id, SUM(col3) AS val
         FROM table3
         GROUP BY id
         UNION ALL
         SELECT id, SUM(col4) AS val
         FROM table4
         GROUP BY id
        ) t
        GROUP BY t.id;
        Dioptimalkan:---------------------------
        SELECT t.id, SUM(t.val) AS val
        FROM (
         SELECT id, col3 AS val
         FROM table3
         UNION ALL
         SELECT id, col4 AS val
         FROM table4
        ) t
        GROUP BY t.id;
      • Untuk mengurutkan data yang diekspor sementara, urutkan data menggunakan alat seperti EXCEL alih-alih ORDER BY.

      • Jangan gunakan DISTINCT. Gunakan GROUP BY sebagai gantinya.

        SELECT COUNT(DISTINCT id) AS cnt
        FROM table1;
        Dioptimalkan:---------------------------
        SELECT COUNT(1) AS cnt
        FROM (
         SELECT id
         FROM table1
         GROUP BY id
        ) t;
      • Jangan gunakan INSERT INTO untuk menulis data. Tambahkan bidang partisi sebagai gantinya. Ini mengurangi kompleksitas SQL dan menghemat biaya komputasi.

  • Jangan jalankan pernyataan SQL untuk melihat pratinjau data tabel. Anda dapat menggunakan fitur pratinjau tabel untuk melihat data tabel. Metode ini tidak mengonsumsi sumber daya komputasi. Jika Anda menggunakan DataWorks, Anda dapat melihat pratinjau tabel dan detail tabel pada halaman Data Map. Untuk informasi lebih lanjut, lihat Lihat Detail Tabel. Jika Anda menggunakan MaxCompute Studio, klik dua kali tabel untuk melihat pratinjau datanya.

  • Pilih alat yang sesuai untuk komputasi data. MaxCompute merespons permintaan dalam hitungan menit. Ini tidak cocok untuk permintaan frontend. Hasil komputasi disinkronkan ke sistem penyimpanan eksternal. Sebagian besar pengguna menggunakan database relasional untuk menyimpan hasil. Kami merekomendasikan agar Anda menggunakan MaxCompute untuk pekerjaan komputasi ringan dan database relasional, seperti ApsaraDB for RDS, untuk permintaan frontend. Permintaan frontend memerlukan pembuatan hasil permintaan secara real-time. Jika hasil permintaan ditampilkan di frontend, klausa bersyarat tidak dieksekusi pada data. Data tidak diagregasi atau dikaitkan dengan kamus. Permintaan bahkan tidak mencakup klausa WHERE.

Kontrol biaya komputasi pekerjaan MapReduce

Anda dapat menggunakan metode berikut untuk mengontrol biaya komputasi pekerjaan MapReduce:

  • Konfigurasikan pengaturan yang diperlukan

    • Ukuran Split

      Ukuran split default untuk mapper adalah 256 MB. Ukuran split menentukan jumlah mapper. Jika logika kode untuk mapper memakan waktu, Anda dapat menggunakan JobConf#setSplitSize untuk mengurangi ukuran split. Anda harus mengonfigurasi ukuran split yang sesuai. Jika tidak, sumber daya komputasi yang berlebihan mungkin dikonsumsi.

    • Instance Reduce MapReduce

      Secara default, jumlah reducer yang digunakan untuk menyelesaikan pekerjaan adalah seperempat dari jumlah mapper. Anda dapat mengatur jumlah reducer ke nilai yang berkisar antara 0 hingga 2.000. Lebih banyak reducer memerlukan lebih banyak sumber daya komputasi, yang meningkatkan biaya. Anda harus mengonfigurasi jumlah reducer dengan tepat.

  • Kurangi jumlah pekerjaan MapReduce

    Jika beberapa pekerjaan MapReduce saling terkait dan output suatu pekerjaan merupakan input pekerjaan berikutnya, kami sarankan Anda menggunakan mode pipeline. Mode pipeline memungkinkan Anda menggabungkan beberapa pekerjaan MapReduce seri menjadi satu pekerjaan. Ini mengurangi operasi disk I/O redundan yang disebabkan oleh tabel antara dan meningkatkan kinerja. Ini juga menyederhanakan penjadwalan pekerjaan dan meningkatkan efisiensi pemeliharaan proses. Untuk informasi lebih lanjut, lihat Contoh Pipeline.

  • Pangkas kolom tabel input

    Untuk tabel input yang berisi sejumlah besar kolom, hanya beberapa kolom yang diproses oleh mapper. Saat Anda menambahkan tabel input, Anda dapat menentukan kolom untuk mengurangi jumlah data yang perlu dibaca. Misalnya, untuk memproses data di kolom c1 dan c2, gunakan konfigurasi berikut:

    InputUtils.addTable(TableInfo.builder().tableName("wc_in").cols(new String[]{"c1","c2"}).build(), job);

    Setelah konfigurasi, mapper membaca data hanya dari kolom c1 dan c2. Ini tidak memengaruhi data yang diperoleh berdasarkan nama kolom. Namun, ini mungkin memengaruhi data yang diperoleh berdasarkan subskrip.

  • Hindari pembacaan sumber daya berulang

    Kami sarankan Anda membaca sumber daya di tahap setup. Ini mencegah hilangnya kinerja yang disebabkan oleh pembacaan sumber daya berulang. Anda dapat membaca sumber daya hingga 64 kali. Untuk informasi lebih lanjut, lihat Contoh Penggunaan Sumber Daya.

  • Kurangi overhead pembuatan objek

    Untuk objek Java yang digunakan setiap kali dalam tahap map dan reduce, cegah pembuatannya di fungsi map atau reduce. Anda dapat meletakkannya di tahap setup untuk mencegah overhead yang disebabkan oleh pembuatan berulang.

    {
        ...
        Record word;
        Record one;
    
        public void setup(TaskContext context) throws IOException {
    
    
          // Buat objek Java di tahap setup. Ini mencegah pembuatan ulang objek Java di setiap tahap map.
          word = context.createMapOutputKeyRecord();
    
          one = context.createMapOutputValueRecord();
    
          one.set(new Object[]{1L});
    
        }
        ...
    }
  • Gunakan combiner dengan cara yang tepat

    Jika output tugas map berisi beberapa kunci duplikat, Anda dapat menggunakan combiner untuk menggabungkan kunci tersebut. Ini mengurangi bandwidth transmisi dan overhead Pengacakan. Jika output tugas map tidak berisi beberapa kunci duplikat, menggunakan combiner dapat menimbulkan overhead tambahan. Combiner mengimplementasikan antarmuka reducer. Kode berikut mendefinisikan combiner dalam program WordCount:

    /**
       * Kelas combiner yang menggabungkan output map dengan menjumlahkannya.
       */
      public static class SumCombiner extends ReducerBase {
    
        private Record count;
    
        @Override
        public void setup(TaskContext context) throws IOException {
          count = context.createMapOutputValueRecord();
        }
    
        @Override
        public void reduce(Record key, Iterator<Record> values, TaskContext context)
            throws IOException {
          long c = 0;
          while (values.hasNext()) {
            Record val = values.next();
            c += (Long) val.get(0);
          }
          count.set(0, c);
          context.write(key, count);
        }
      }
  • Pilih kolom kunci partisi yang sesuai atau sesuaikan partisioner

    Anda dapat menggunakan JobConf#setPartitionColumns untuk menentukan kolom kunci partisi. Kolom kunci partisi default didefinisikan dalam skema kunci. Jika Anda menggunakan metode ini, data ditransfer ke reducer berdasarkan nilai hash kolom yang ditentukan. Ini mencegah masalah ekor panjang yang disebabkan oleh skew data. Anda juga dapat menyesuaikan partisioner jika perlu. Kode berikut menunjukkan cara menyesuaikan partisioner:

    import com.aliyun.odps.mapred.Partitioner;
    
    public static class MyPartitioner extends Partitioner {
    
    @Override
    public int getPartition(Record key, Record value, int numPartitions) {
      // numPartitions menunjukkan jumlah reducer.
      // Fungsi ini digunakan untuk menentukan reducer ke mana kunci tugas map ditransfer.
      String k = key.get(0).toString();
      return k.length() % numPartitions;
    }
    }

    Konfigurasikan pengaturan berikut dalam jobconf:

    jobconf.setPartitionerClass(MyPartitioner.class)

    Tentukan jumlah reducer dalam jobconf.

    jobconf.setNumReduceTasks(num)
  • Konfigurasikan parameter memori JVM sesuai kebutuhan

    Memori besar pekerjaan MapReduce meningkatkan biaya komputasi. Dalam konfigurasi standar, 1 core CPU dan 4 GB memori dikonfigurasi, dan odps.stage.reducer.jvm.mem diatur ke 4006. Rasio core CPU terhadap memori yang besar (lebih besar dari 1:4) juga meningkatkan biaya komputasi.

Referensi