Pengantar penskalaan otomatis slot

Reservasi yang Anda konfigurasi untuk menggunakan penskalaan otomatis slot akan otomatis menskalakan kapasitas yang dialokasikan untuk mengakomodasi permintaan workload Anda. Saat workload Anda meningkat atau menurun, BigQuery secara dinamis menyesuaikan slot Anda ke level yang sesuai. Reservasi dengan penskalaan otomatis slot hanya tersedia dengan edisi BigQuery.

Menggunakan reservasi penskalaan otomatis

Anda tidak perlu membeli komitmen slot sebelum membuat reservasi penskalaan otomatis. Komitmen slot memberikan tarif diskon untuk slot yang digunakan secara konsisten, tetapi bersifat opsional dengan reservasi penskalaan otomatis. Untuk membuat reservasi penskalaan otomatis, Anda menetapkan jumlah slot maksimum ke reservasi (ukuran reservasi maksimum). Anda dapat mengidentifikasi jumlah maksimum slot penskalaan otomatis dengan mengurangi ukuran reservasi maksimum dengan slot dasar pengukuran opsional yang ditetapkan untuk reservasi.

Saat Anda membuat reservasi penskalaan otomatis, pertimbangkan hal berikut:

  • BigQuery menskalakan reservasi hampir seketika hingga mencapai jumlah slot yang diperlukan untuk menjalankan tugas, atau mencapai jumlah maksimum slot yang tersedia untuk reservasi. Slot selalu diskalakan secara otomatis ke kelipatan 50.
  • Penskalaan ke atas didasarkan pada penggunaan sebenarnya, dan dibulatkan ke atas hingga kenaikan slot terdekat sebesar 50.
  • Slot yang diskalakan otomatis akan dikenai biaya berdasarkan harga komputasi kapasitas untuk edisi terkait saat meningkatkan skalanya. Anda dikenai biaya untuk jumlah slot yang diskalakan, bukan jumlah slot yang digunakan. Tagihan ini berlaku meskipun tugas yang menyebabkan BigQuery melakukan penskalaan gagal. Oleh karena itu, jangan gunakan skema informasi tugas untuk mencocokkan penagihan. Sebagai gantinya, lihat Memantau penskalaan otomatis dengan skema informasi.
  • Meskipun jumlah slot selalu diskalakan dengan kelipatan 50, contoh ini dapat menskalakan lebih dari 50 slot dalam satu langkah. Misalnya, jika workload Anda memerlukan 450 slot tambahan, BigQuery dapat mencoba menskalakan sebanyak 450 slot sekaligus untuk memenuhi persyaratan kapasitas.
  • BigQuery akan diskalakan ke bawah jika tugas yang terkait dengan reservasi tidak lagi memerlukan kapasitas (tunduk pada minimum 1 menit).

Kapasitas yang diskalakan otomatis akan dipertahankan selama minimal 60 detik. Periode 60 detik ini disebut periode penskalaan ke bawah. Setiap puncak kapasitas akan mereset jendela penskalaan ke bawah, yang memperlakukan seluruh tingkat kapasitas sebagai pemberian baru. Namun, jika 60 detik atau lebih telah berlalu sejak peningkatan kapasitas terakhir dan permintaan menurun, sistem akan mengurangi kapasitas tanpa mereset periode penurunan skala, sehingga memungkinkan penurunan berturut-turut tanpa penundaan yang diterapkan.

Untuk mempelajari cara menggunakan penskalaan otomatis, lihat Menggunakan penskalaan otomatis slot.

Menggunakan reservasi dengan slot dasar pengukuran dan penskalaan otomatis

Selain menentukan ukuran reservasi maksimum, Anda dapat secara opsional menentukan jumlah slot dasar pengukuran per reservasi. Dasar pengukuran adalah jumlah minimum slot yang akan selalu dialokasikan ke reservasi, dan Anda akan selalu dikenai biaya untuk slot tersebut. Slot penskalaan otomatis hanya ditambahkan setelah semua slot dasar pengukuran (dan slot tidak ada aktivitas jika ada) digunakan. Anda dapat membagikan slot dasar pengukuran tidak ada aktivitas di satu reservasi dengan reservasi lain yang memerlukan kapasitas.

Anda dapat meningkatkan jumlah slot dasar pengukuran dalam reservasi setiap beberapa menit. Jika ingin mengurangi slot dasar pengukuran, Anda dibatasi sekali per jam jika baru-baru ini mengubah kapasitas slot dasar pengukuran dan slot dasar pengukuran melebihi slot yang di-commit. Jika tidak, Anda dapat mengurangi slot dasar pengukuran setiap beberapa menit.

Slot dasar pengukuran dan penskalaan otomatis ditujukan untuk menyediakan kapasitas berdasarkan workload terbaru Anda. Jika Anda mengantisipasi workload besar yang sangat berbeda dengan workload Anda sebelumnya, sebaiknya tingkatkan kapasitas dasar pengukuran sebelum peristiwa tersebut, daripada mengandalkan slot penskalaan otomatis untuk menutupi kapasitas workload. Jika Anda mengalami masalah saat meningkatkan kapasitas dasar pengukuran, coba lagi permintaan setelah menunggu 15 menit.

Jika reservasi tidak memiliki slot dasar pengukuran atau tidak dikonfigurasi untuk meminjam slot tidak ada aktivitas dari reservasi lain, BigQuery akan mencoba melakukan penskalaan. Jika tidak, slot dasar pengukuran harus digunakan sepenuhnya sebelum penskalaan.

Reservasi menggunakan dan menambahkan slot dalam prioritas berikut:

  1. Slot dasar pengukuran.
  2. Berbagi slot tidak ada aktivitas (jika diaktifkan). Reservasi hanya dapat membagikan slot dasar pengukuran atau yang di-commit dari reservasi lain yang dibuat dengan edisi dan region yang sama.
  3. Slot penskalaan otomatis.

Dalam contoh berikut, slot diskalakan dari jumlah dasar pengukuran yang ditentukan. Reservasi etl dan dashboard memiliki ukuran dasar 700 dan 300 slot.

Contoh penskalaan otomatis tanpa komitmen.

Dalam contoh ini, reservasi etl dapat diskalakan hingga 1.300 slot (700 slot dasar pengukuran ditambah 600 slot penskalaan otomatis). Jika reservasi dashboard tidak digunakan, reservasi etl dapat menggunakan 300 slot dari reservasi dashboard jika tidak ada tugas yang berjalan di sana, sehingga menghasilkan maksimum 1.600 slot potensial.

Reservasi dashboard dapat diskalakan hingga 1.100 slot (300 slot dasar pengukuran ditambah 800 slot penskalaan otomatis). Jika reservasi etl benar-benar tidak ada aktivitas, reservasi dashboard dapat diskalakan hingga maksimum 1.800 slot (300 slot dasar pengukuran ditambah 800 slot penskalaan otomatis ditambah 700 slot tidak ada aktivitas di reservasi etl ).

Jika reservasi etl memerlukan lebih dari 700 slot dasar pengukuran yang selalu tersedia, reservasi akan mencoba menambahkan slot menggunakan metode berikut secara berurutan:

  1. 700 slot dasar pengukuran.
  2. Berbagi slot tidak ada aktivitas dengan 300 slot dasar pengukuran di reservasi dashboard. Reservasi Anda hanya berbagi slot dasar pengukuran tidak ada aktivitas dengan reservasi lain yang dibuat dengan edisi yang sama.
  3. Meningkatkan skala 600 slot tambahan ke ukuran reservasi maksimum.

Menggunakan komitmen slot

Contoh berikut menampilkan penskalaan otomatis slot menggunakan komitmen kapasitas.

Contoh penskalaan otomatis

Seperti dasar pengukuran reservasi, komitmen slot memungkinkan Anda mengalokasikan jumlah slot tetap yang tersedia untuk semua reservasi. Tidak seperti slot dasar pengukuran, komitmen tidak dapat dikurangi selama jangka waktu yang ditentukan. Komitmen slot bersifat opsional, tetapi dapat menghemat biaya jika slot dasar pengukuran diwajibkan untuk jangka waktu yang lama.

Dalam contoh ini, Anda akan dikenai tarif standar untuk slot komitmen kapasitas. Anda akan ditagih berdasarkan tarif penskalaan otomatis untuk jumlah slot penskalaan otomatis setelah penskalaan otomatis diaktifkan dan reservasi dalam status ditingkatkan skalanya. Untuk tarif penskalaan otomatis, Anda akan ditagih untuk jumlah slot yang diskalakan, bukan jumlah slot yang digunakan.

Slot maksimum yang tersedia

Anda dapat menghitung jumlah maksimum slot yang dapat digunakan oleh reservasi dengan menambahkan slot dasar pengukuran, jumlah maksimum slot penskalaan otomatis, dan slot apa pun dalam komitmen yang dibuat dengan edisi yang sama dan tidak tercakup oleh slot dasar pengukuran. Contoh dalam gambar sebelumnya disiapkan sebagai berikut:

  • Komitmen kapasitas 1.000 slot tahunan. Slot tersebut ditetapkan sebagai slot dasar pengukuran pada reservasi etl dan reservasi dashboard.
  • 700 slot dasar pengukuran ditetapkan ke reservasi etl.
  • 300 slot dasar pengukuran ditetapkan ke reservasi dashboard.
  • Penskalaan otomatis slot 600 untuk reservasi etl.
  • Penskalaan otomatis slot 800 untuk reservasi dashboard.

Untuk reservasi etl, jumlah maksimum slot yang memungkinkan sama dengan slot dasar pengukuran etl (700) ditambah slot dasar pengukuran dashboard (300, jika semua slot tidak ada aktivitas) ditambah jumlah maksimum slot penskalaan otomatis (600). Jadi, jumlah maksimum slot yang dapat digunakan reservasi etl dalam contoh ini adalah 1.600. Jumlah ini melebihi jumlah dalam komitmen kapasitas.

Pada contoh berikut, komitmen tahunan melebihi slot dasar pengukuran yang ditetapkan.

Menghitung slot yang tersedia

Dalam contoh ini, kita memiliki:

  • Komitmen kapasitas sebanyak 1.600 slot tahunan.
  • Ukuran reservasi maksimum 1.500 (termasuk 500 slot penskalaan otomatis).
  • 1.000 slot dasar pengukuran ditetapkan ke reservasi etl.

Jumlah maksimum slot yang tersedia untuk reservasi sama dengan slot dasar pengukuran (1.000) ditambah slot tidak ada aktivitas yang di-commit dan tidak dikhususkan untuk slot dasar pengukuran (1.600 slot tahunan - 1.000 slot dasar pengukuran = 600) ditambah jumlah slot penskalaan otomatis (500). Jadi slot potensial maksimum dalam reservasi ini adalah 2.100. Slot yang diskalakan otomatis adalah slot tambahan di atas komitmen kapasitas.

Praktik terbaik penskalaan otomatis

  1. Saat pertama kali menggunakan autoscaler, tetapkan jumlah slot penskalaan otomatis ke jumlah yang signifikan berdasarkan performa sebelumnya dan yang diperkirakan. Setelah reservasi dibuat, pantau secara aktif tingkat kegagalan, performa, dan tagihan, serta sesuaikan jumlah slot penskalaan otomatis berdasarkan kebutuhan.

  2. Autoscaler memiliki waktu minimum 1 menit sebelum penskalaan ke bawah, jadi penting untuk menetapkan jumlah maksimum slot yang diskalakan otomatis untuk menyeimbangkan performa dan biaya. Jika jumlah maksimum slot penskalaan otomatis terlalu besar dan tugas Anda dapat menggunakan semua slot untuk menyelesaikan tugas dalam hitungan detik, Anda tetap akan dikenai biaya untuk slot maksimum selama satu menit penuh. Jika Anda menurunkan slot maksimum menjadi setengah dari jumlah saat ini, reservasi Anda akan diskalakan ke angka yang lebih rendah dan tugas dapat menggunakan lebih banyak slot_seconds selama menit tersebut, sehingga mengurangi pemborosan. Untuk mendapatkan bantuan dalam menentukan persyaratan slot, lihat Memantau performa tugas. Sebagai pendekatan alternatif untuk menentukan persyaratan slot, lihat Melihat rekomendasi slot edisi.

  3. Penggunaan slot terkadang dapat melebihi jumlah dasar pengukuran Anda ditambah slot yang diskalakan. Anda tidak ditagih untuk penggunaan slot yang lebih besar dari dasar pengukuran ditambah slot yang diskalakan.

  4. Autoscaler paling efisien untuk workload yang berat dan berjalan lama, seperti workload dengan beberapa kueri serentak. Hindari mengirim kueri satu per satu, karena setiap kueri menskalakan reservasi yang akan tetap diskalakan selama minimum 1 menit. Jika Anda terus mengirim kueri, yang menyebabkan beban kerja yang konstan, menetapkan dasar pengukuran dan membeli komitmen akan memberikan kapasitas yang konstan dengan harga diskon.

  5. Penskalaan otomatis BigQuery bergantung pada ketersediaan kapasitas. BigQuery berupaya memenuhi permintaan kapasitas pelanggan berdasarkan penggunaan historis. Untuk mencapai jaminan kapasitas, Anda dapat menetapkan dasar pengukuran slot opsional, yang merupakan jumlah slot yang dijamin dalam reservasi. Dengan dasar pengukuran, slot akan segera tersedia dan Anda membayarnya, baik Anda menggunakannya atau tidak. Guna memastikan kapasitas tersedia untuk permintaan non-organik yang besar, seperti liburan dengan traffic yang tinggi, hubungi tim BigQuery beberapa minggu sebelumnya.

  6. Slot dasar pengukuran selalu ditagih. Jika komitmen kapasitas berakhir, Anda mungkin perlu menyesuaikan jumlah slot dasar pengukuran dalam reservasi secara manual untuk menghindari tagihan yang tidak diinginkan. Misalnya, anggaplah Anda memiliki komitmen 1 tahun dengan 100 slot dan pemesanan dengan 100 slot dasar pengukuran. Komitmen tersebut berakhir dan tidak memiliki rencana perpanjangan. Setelah komitmen berakhir, Anda membayar 100 slot dasar pengukuran dengan tarif bayar sesuai penggunaan.

Memantau penskalaan otomatis

Saat memantau penggunaan slot dengan diagram resource administratif, Anda mungkin melihat lebih banyak slot yang diskalakan secara signifikan daripada penggunaan slot Anda karena diagram memperlancar jumlah slot yang digunakan selama periode penyelarasan singkat ini. Untuk melihat penggunaan slot penskalaan otomatis dengan detail yang lebih akurat, kurangi opsi jangka waktu. Tindakan ini otomatis memperbarui periode penyelarasan ke peningkatan yang lebih kecil.

Pada contoh berikut, diagram menampilkan lebih banyak slot yang diskalakan secara signifikan daripada permintaan workload.

Periode penyelarasan disetel ke interval satu menit dan slot yang diskalakan muncul lebih dari permintaan penggunaan slot.

Namun, jika Anda mempersingkat opsi jangka waktu sehingga periode penyelarasan menjadi dua detik, Anda dapat melihat bahwa autoscaler dapat diskalakan sesuai dengan permintaan workload dan menampilkan data yang lebih akurat. Anda dapat menyesuaikan opsi jangka waktu dengan menarik rentang awal dan akhir dari opsi jangka waktu tersebut. Untuk menampilkan data permintaan workload yang paling akurat, pilih p99 dari daftar Metric.

Periode penyelarasan disetel ke interval dua detik dan slot yang diskalakan sesuai untuk permintaan workload.

Untuk tampilan penggunaan penskalaan otomatis yang paling akurat, gunakan periode penyelarasan antara 1 dan 15 detik. Untuk mengetahui informasi selengkapnya tentang periode penyelarasan diagram resource administratif, lihat Opsi jangka waktu.

Untuk mengetahui informasi tentang cara melihat penggunaan slot, lihat Melihat diagram resource administratif

Memantau penskalaan otomatis dengan skema informasi

Anda dapat menggunakan skrip SQL berikut untuk memeriksa detik slot yang ditagih untuk edisi tertentu. Anda harus menjalankan skrip ini di project yang sama dengan tempat pemesanan dibuat. Skrip pertama menampilkan detik slot yang ditagih dan tercakup dalam commitment_plan, sedangkan skrip kedua menampilkan detik slot yang ditagih dan tidak tercakup dalam komitmen.

Anda hanya perlu menetapkan nilai tiga variabel untuk menjalankan skrip ini:

  • start_time
  • end_time
  • edition_to_check

Skrip ini tunduk pada peringatan berikut:

  • Pemesanan dan komitmen kapasitas yang dihapus akan dihapus dari tampilan skema informasi di akhir periode retensi data. Tentukan periode waktu terbaru yang tidak berisi reservasi dan komitmen yang dihapus untuk mendapatkan hasil yang benar.

  • Hasil skrip mungkin tidak sama persis dengan tagihan karena error pembulatan kecil.

Skrip berikut memeriksa penggunaan slot yang tercakup dalam komitmen untuk edisi tertentu.

Luaskan untuk melihat skrip untuk skenario yang tercakup

DECLARE start_time,end_time TIMESTAMP;

DECLARE
  edition_to_check STRING;

/* Google uses Pacific Time to calculate the billing period for all customers,
regardless of their time zone. Use the following format if you want to match the
billing report. Change the start_time and end_time values to match the desired
window. */

/* The following three variables (start_time, end_time, and edition_to_check)
are the only variables that you need to set in the script.

During daylight savings time, the start_time and end_time variables should
follow this format: 2024-02-20 00:00:00-08. */

SET start_time = "2023-07-20 00:00:00-07";
SET end_time = "2023-07-28 00:00:00-07";
SET edition_to_check = 'ENTERPRISE';

/* The following function returns the slot seconds for the time window between
two capacity changes. For example, if there are 100 slots between (2023-06-01
10:00:00, 2023-06-01 11:00:00), then during that window the total slot seconds
will be 100 * 3600.

This script calculates a specific window (based on the variables defined above),
which is why the following script includes script_start_timestamp_unix_millis
and script_end_timestamp_unix_millis. */

CREATE TEMP FUNCTION
GetSlotSecondsBetweenChanges(
  slots FLOAT64,
  range_begin_timestamp_unix_millis FLOAT64,
  range_end_timestamp_unix_millis FLOAT64,
  script_start_timestamp_unix_millis FLOAT64,
  script_end_timestamp_unix_millis FLOAT64)
RETURNS INT64
LANGUAGE js
AS r"""
    if (script_end_timestamp_unix_millis < range_begin_timestamp_unix_millis || script_start_timestamp_unix_millis > range_end_timestamp_unix_millis) {
      return 0;
    }
    var begin = Math.max(script_start_timestamp_unix_millis, range_begin_timestamp_unix_millis)
    var end = Math.min(script_end_timestamp_unix_millis, range_end_timestamp_unix_millis)
    return slots * Math.ceil((end - begin) / 1000.0)
""";

/*
Sample CAPACITY_COMMITMENT_CHANGES data (unrelated columns ignored):
+---------------------+------------------------+-----------------+--------+------------+--------+
|  change_timestamp   | capacity_commitment_id | commitment_plan | state  | slot_count | action |
+---------------------+------------------------+-----------------+--------+------------+--------+
| 2023-07-20 19:30:27 | 12954109101902401697   | ANNUAL          | ACTIVE |        100 | CREATE |
| 2023-07-27 22:29:21 | 11445583810276646822   | FLEX            | ACTIVE |        100 | CREATE |
| 2023-07-27 23:10:06 | 7341455530498381779    | MONTHLY         | ACTIVE |        100 | CREATE |
| 2023-07-27 23:11:06 | 7341455530498381779    | FLEX            | ACTIVE |        100 | UPDATE |

The last row indicates a special change from MONTHLY to FLEX, which happens
because of commercial migration.

*/

WITH
  /*
  Information containing which commitment might have plan
  updated (e.g. renewal or commercial migration). For example:
  +------------------------+------------------+--------------------+--------+------------+--------+-----------+----------------------------+
  |  change_timestamp   | capacity_commitment_id | commitment_plan | state  | slot_count | action | next_plan | next_plan_change_timestamp |
  +---------------------+------------------------+-----------------+--------+------------+--------+-----------+----------------------------+
  | 2023-07-20 19:30:27 | 12954109101902401697   | ANNUAL          | ACTIVE |        100 | CREATE | ANNUAL    |        2023-07-20 19:30:27 |
  | 2023-07-27 22:29:21 | 11445583810276646822   | FLEX            | ACTIVE |        100 | CREATE | FLEX      |        2023-07-27 22:29:21 |
  | 2023-07-27 23:10:06 | 7341455530498381779    | MONTHLY         | ACTIVE |        100 | CREATE | FLEX      |        2023-07-27 23:11:06 |
  | 2023-07-27 23:11:06 | 7341455530498381779    | FLEX            | ACTIVE |        100 | UPDATE | FLEX      |        2023-07-27 23:11:06 |
  */
  commitments_with_next_plan AS (
    SELECT
      *,
      IFNULL(
        LEAD(commitment_plan)
          OVER (
            PARTITION BY capacity_commitment_id ORDER BY change_timestamp ASC
          ),
        commitment_plan)
        next_plan,
      IFNULL(
        LEAD(change_timestamp)
          OVER (
            PARTITION BY capacity_commitment_id ORDER BY change_timestamp ASC
          ),
        change_timestamp)
        next_plan_change_timestamp
    FROM
      `region-us.INFORMATION_SCHEMA.CAPACITY_COMMITMENT_CHANGES_BY_PROJECT`
  ),

  /*
  Insert a 'DELETE' action for those with updated plans. The FLEX commitment
  '7341455530498381779' is has no 'CREATE' action, and is instead labeled as an
  'UPDATE' action.

  For example:
  +---------------------+------------------------+-----------------+--------+------------+--------+
  |  change_timestamp   | capacity_commitment_id | commitment_plan | state  | slot_count | action |
  +---------------------+------------------------+-----------------+--------+------------+--------+
  | 2023-07-20 19:30:27 | 12954109101902401697   | ANNUAL          | ACTIVE |        100 | CREATE |
  | 2023-07-27 22:29:21 | 11445583810276646822   | FLEX            | ACTIVE |        100 | CREATE |
  | 2023-07-27 23:10:06 | 7341455530498381779    | MONTHLY         | ACTIVE |        100 | CREATE |
  | 2023-07-27 23:11:06 | 7341455530498381779    | FLEX            | ACTIVE |        100 | UPDATE |
  | 2023-07-27 23:11:06 | 7341455530498381779    | MONTHLY         | ACTIVE |        100 | DELETE |
  */

  capacity_changes_with_additional_deleted_event_for_changed_plan AS (
    SELECT
      next_plan_change_timestamp AS change_timestamp,
      project_id,
      project_number,
      capacity_commitment_id,
      commitment_plan,
      state,
      slot_count,
      'DELETE' AS action,
      commitment_start_time,
      commitment_end_time,
      failure_status,
      renewal_plan,
      user_email,
      edition,
      is_flat_rate,
    FROM commitments_with_next_plan
    WHERE commitment_plan <> next_plan
    UNION ALL
    SELECT * FROM `region-us.INFORMATION_SCHEMA.CAPACITY_COMMITMENT_CHANGES_BY_PROJECT`
  ),

  /*
  The committed_slots change the history. For example:
  +---------------------+------------------------+------------------+-----------------+
  |  change_timestamp   | capacity_commitment_id | slot_count_delta | commitment_plan |
  +---------------------+------------------------+------------------+-----------------+
  | 2023-07-20 19:30:27 | 12954109101902401697   |              100 | ANNUAL          |
  | 2023-07-27 22:29:21 | 11445583810276646822   |              100 | FLEX            |
  | 2023-07-27 23:10:06 | 7341455530498381779    |              100 | MONTHLY         |
  | 2023-07-27 23:11:06 | 7341455530498381779    |             -100 | MONTHLY         |
  | 2023-07-27 23:11:06 | 7341455530498381779    |              100 | FLEX            |
  */

  capacity_commitment_slot_data AS (
    SELECT
      change_timestamp,
      capacity_commitment_id,
      CASE
        WHEN action = "CREATE" OR action = "UPDATE"
          THEN
            IFNULL(
              IF(
                LAG(action)
                  OVER (
                    PARTITION BY capacity_commitment_id ORDER BY change_timestamp ASC, action ASC
                  )
                  IN UNNEST(['CREATE', 'UPDATE']),
                slot_count - LAG(slot_count)
                  OVER (
                    PARTITION BY capacity_commitment_id ORDER BY change_timestamp ASC, action ASC
                  ),
                slot_count),
              slot_count)
        ELSE
          IF(
            LAG(action)
              OVER (PARTITION BY capacity_commitment_id ORDER BY change_timestamp ASC, action ASC)
              IN UNNEST(['CREATE', 'UPDATE']),
            -1 * slot_count,
            0)
        END
        AS slot_count_delta,
      commitment_plan
    FROM
      capacity_changes_with_additional_deleted_event_for_changed_plan
    WHERE
      state = "ACTIVE"
      AND edition = edition_to_check
      AND change_timestamp <= end_time
  ),

  /*
  The total_committed_slots history for each plan. For example:
  +---------------------+---------------+-----------------+
  |  change_timestamp   | capacity_slot | commitment_plan |
  +---------------------+---------------+-----------------+
  | 2023-07-20 19:30:27 |           100 | ANNUAL          |
  | 2023-07-27 22:29:21 |           100 | FLEX            |
  | 2023-07-27 23:10:06 |           100 | MONTHLY         |
  | 2023-07-27 23:11:06 |             0 | MONTHLY         |
  | 2023-07-27 23:11:06 |           200 | FLEX            |
  */

  running_capacity_commitment_slot_data AS (
    SELECT
      change_timestamp,
      SUM(slot_count_delta)
        OVER (
          PARTITION BY commitment_plan
          ORDER BY change_timestamp
          RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
        )
        AS capacity_slot,
      commitment_plan,
    FROM
      capacity_commitment_slot_data
  ),

  /*

  The slot_seconds between each changes, partitioned by each plan. For example:
  +---------------------+--------------+-----------------+
  |  change_timestamp   | slot_seconds | commitment_plan |
  +---------------------+--------------+-----------------+
  | 2023-07-20 19:30:27 |     64617300 | ANNUAL          |
  | 2023-07-27 22:29:21 |       250500 | FLEX            |
  | 2023-07-27 23:10:06 |         6000 | MONTHLY         |
  | 2023-07-27 23:11:06 |            0 | MONTHLY         |
  | 2023-07-27 23:11:06 |      5626800 | FLEX            |
  */

  slot_seconds_data AS (
    SELECT
      change_timestamp,
      GetSlotSecondsBetweenChanges(
        capacity_slot,
        UNIX_MILLIS(change_timestamp),
        UNIX_MILLIS(
          IFNULL(
            LEAD(change_timestamp)
              OVER (PARTITION BY commitment_plan ORDER BY change_timestamp ASC),
            CURRENT_TIMESTAMP())),
        UNIX_MILLIS(start_time),
        UNIX_MILLIS(end_time)) AS slot_seconds,
      commitment_plan,
    FROM
      running_capacity_commitment_slot_data
    WHERE
      change_timestamp <= end_time
  )

/*

The final result is similar to the following:
+-----------------+--------------------+
| commitment_plan | total_slot_seconds |
+-----------------+--------------------+
| ANNUAL          |           64617300 |
| MONTHLY         |               6000 |
| FLEX            |            5877300 |
*/

SELECT
  commitment_plan,
  SUM(slot_seconds) AS total_slot_seconds
FROM
  slot_seconds_data
GROUP BY
  commitment_plan

Skrip berikut memeriksa penggunaan slot yang tidak tercakup dalam komitmen untuk edisi tertentu. Penggunaan ini berisi dua jenis slot, slot yang diskalakan, dan slot dasar pengukuran yang tidak tercakup oleh komitmen.

Luaskan untuk melihat skrip untuk skenario yang tidak tercakup

/*
This script has several parts:
1. Calculate the baseline and scaled slots for reservations
2. Calculate the committed slots
3. Join the two results above to calculate the baseline not covered by committed
   slots
4. Aggregate the number
*/

-- variables
DECLARE start_time, end_time TIMESTAMP;

DECLARE
  edition_to_check STRING;

/* Google uses Pacific Time to calculate the billing period for all customers,
regardless of their time zone. Use the following format if you want to match the
billing report. Change the start_time and end_time values to match the desired
window. */

/* The following three variables (start_time, end_time, and edition_to_check)
are the only variables that you need to set in the script.

During daylight savings time, the start_time and end_time variables should
follow this format: 2024-02-20 00:00:00-08. */

SET start_time = "2023-07-20 00:00:00-07";
SET end_time = "2023-07-28 00:00:00-07";
SET edition_to_check = 'ENTERPRISE';

/*
The following function returns the slot seconds for the time window between
two capacity changes. For example, if there are 100 slots between (2023-06-01
10:00:00, 2023-06-01 11:00:00), then during that window the total slot seconds
will be 100 * 3600.

This script calculates a specific window (based on the variables defined above),
which is why the following script includes script_start_timestamp_unix_millis
and script_end_timestamp_unix_millis. */

CREATE TEMP FUNCTION GetSlotSecondsBetweenChanges(
  slots FLOAT64,
  range_begin_timestamp_unix_millis FLOAT64,
  range_end_timestamp_unix_millis FLOAT64,
  script_start_timestamp_unix_millis FLOAT64,
  script_end_timestamp_unix_millis FLOAT64)
RETURNS INT64
LANGUAGE js
AS r"""
    if (script_end_timestamp_unix_millis < range_begin_timestamp_unix_millis || script_start_timestamp_unix_millis > range_end_timestamp_unix_millis) {
      return 0;
    }
    var begin = Math.max(script_start_timestamp_unix_millis, range_begin_timestamp_unix_millis)
    var end = Math.min(script_end_timestamp_unix_millis, range_end_timestamp_unix_millis)
    return slots * Math.ceil((end - begin) / 1000.0)
""";
/*
Sample RESERVATION_CHANGES data (unrelated columns ignored):
+---------------------+------------------+--------+---------------+---------------+
|  change_timestamp   | reservation_name | action | slot_capacity | current_slots |
+---------------------+------------------+--------+---------------+---------------+
| 2023-07-27 22:24:15 | res1             | CREATE |           300 |             0 |
| 2023-07-27 22:25:21 | res1             | UPDATE |           300 |           180 |
| 2023-07-27 22:39:14 | res1             | UPDATE |           300 |           100 |
| 2023-07-27 22:40:20 | res2             | CREATE |           300 |             0 |
| 2023-07-27 22:54:18 | res2             | UPDATE |           300 |           120 |
| 2023-07-27 22:55:23 | res1             | UPDATE |           300 |             0 |

Sample CAPACITY_COMMITMENT_CHANGES data (unrelated columns ignored):
+---------------------+------------------------+-----------------+--------+------------+--------+
|  change_timestamp   | capacity_commitment_id | commitment_plan | state  | slot_count | action |
+---------------------+------------------------+-----------------+--------+------------+--------+
| 2023-07-20 19:30:27 | 12954109101902401697   | ANNUAL          | ACTIVE |        100 | CREATE |
| 2023-07-27 22:29:21 | 11445583810276646822   | FLEX            | ACTIVE |        100 | CREATE |
| 2023-07-27 23:10:06 | 7341455530498381779    | MONTHLY         | ACTIVE |        100 | CREATE |
*/

WITH
  /*
  The scaled_slots & baseline change history:
  +---------------------+------------------+------------------------------+---------------------+
  |  change_timestamp   | reservation_name | autoscale_current_slot_delta | baseline_slot_delta |
  +---------------------+------------------+------------------------------+---------------------+
  | 2023-07-27 22:24:15 | res1             |                            0 |                 300 |
  | 2023-07-27 22:25:21 | res1             |                          180 |                   0 |
  | 2023-07-27 22:39:14 | res1             |                          -80 |                   0 |
  | 2023-07-27 22:40:20 | res2             |                            0 |                 300 |
  | 2023-07-27 22:54:18 | res2             |                          120 |                   0 |
  | 2023-07-27 22:55:23 | res1             |                         -100 |                   0 |
  */
  reservation_slot_data AS (
    SELECT
      change_timestamp,
      reservation_name,
      CASE action
        WHEN "CREATE" THEN autoscale.current_slots
        WHEN "UPDATE"
          THEN
            IFNULL(
              autoscale.current_slots - LAG(autoscale.current_slots)
                OVER (
                  PARTITION BY project_id, reservation_name
                  ORDER BY change_timestamp ASC, action ASC
                ),
              IFNULL(
                autoscale.current_slots,
                IFNULL(
                  -1 * LAG(autoscale.current_slots)
                    OVER (
                      PARTITION BY project_id, reservation_name
                      ORDER BY change_timestamp ASC, action ASC
                    ),
                  0)))
        WHEN "DELETE"
          THEN
            IF(
              LAG(action)
                OVER (
                  PARTITION BY project_id, reservation_name
                  ORDER BY change_timestamp ASC, action ASC
                )
                IN UNNEST(['CREATE', 'UPDATE']),
              -1 * autoscale.current_slots,
              0)
        END
        AS autoscale_current_slot_delta,
      CASE action
        WHEN "CREATE" THEN slot_capacity
        WHEN "UPDATE"
          THEN
            IFNULL(
              slot_capacity - LAG(slot_capacity)
                OVER (
                  PARTITION BY project_id, reservation_name
                  ORDER BY change_timestamp ASC, action ASC
                ),
              IFNULL(
                slot_capacity,
                IFNULL(
                  -1 * LAG(slot_capacity)
                    OVER (
                      PARTITION BY project_id, reservation_name
                      ORDER BY change_timestamp ASC, action ASC
                    ),
                  0)))
        WHEN "DELETE"
          THEN
            IF(
              LAG(action)
                OVER (
                  PARTITION BY project_id, reservation_name
                  ORDER BY change_timestamp ASC, action ASC
                )
                IN UNNEST(['CREATE', 'UPDATE']),
              -1 * slot_capacity,
              0)
        END
        AS baseline_slot_delta,
    FROM
      `region-us.INFORMATION_SCHEMA.RESERVATION_CHANGES`
    WHERE
      edition = edition_to_check
      AND change_timestamp <= end_time
  ),

  -- Convert the above to running total
  /*
  +---------------------+-------------------------+----------------+
  |  change_timestamp   | autoscale_current_slots | baseline_slots |
  +---------------------+-------------------------+----------------+
  | 2023-07-27 22:24:15 |                       0 |            300 |
  | 2023-07-27 22:25:21 |                     180 |            300 |
  | 2023-07-27 22:39:14 |                     100 |            300 |
  | 2023-07-27 22:40:20 |                     100 |            600 |
  | 2023-07-27 22:54:18 |                     220 |            600 |
  | 2023-07-27 22:55:23 |                     120 |            600 |
  */
  running_reservation_slot_data AS (
    SELECT
      change_timestamp,
      SUM(autoscale_current_slot_delta)
        OVER (ORDER BY change_timestamp RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
        AS autoscale_current_slots,
      SUM(baseline_slot_delta)
        OVER (ORDER BY change_timestamp RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
        AS baseline_slots,
    FROM
      reservation_slot_data
  ),

  /*
  The committed_slots change history. For example:
  +---------------------+------------------------+------------------+
  |  change_timestamp   | capacity_commitment_id | slot_count_delta |
  +---------------------+------------------------+------------------+
  | 2023-07-20 19:30:27 | 12954109101902401697   |              100 |
  | 2023-07-27 22:29:21 | 11445583810276646822   |              100 |
  | 2023-07-27 23:10:06 | 7341455530498381779    |              100 |
  */
  capacity_commitment_slot_data AS (
    SELECT
      change_timestamp,
      capacity_commitment_id,
      CASE
        WHEN action = "CREATE" OR action = "UPDATE"
          THEN
            IFNULL(
              IF(
                LAG(action)
                  OVER (
                    PARTITION BY capacity_commitment_id ORDER BY change_timestamp ASC, action ASC
                  )
                  IN UNNEST(['CREATE', 'UPDATE']),
                slot_count - LAG(slot_count)
                  OVER (
                    PARTITION BY capacity_commitment_id ORDER BY change_timestamp ASC, action ASC
                  ),
                slot_count),
              slot_count)
        ELSE
          IF(
            LAG(action)
              OVER (PARTITION BY capacity_commitment_id ORDER BY change_timestamp ASC, action ASC)
              IN UNNEST(['CREATE', 'UPDATE']),
            -1 * slot_count,
            0)
        END
        AS slot_count_delta
    FROM
      `region-us.INFORMATION_SCHEMA.CAPACITY_COMMITMENT_CHANGES_BY_PROJECT`
    WHERE
      state = "ACTIVE"
      AND edition = edition_to_check
      AND change_timestamp <= end_time
  ),

  /*
  The total_committed_slots history. For example:
  +---------------------+---------------+
  |  change_timestamp   | capacity_slot |
  +---------------------+---------------+
  | 2023-07-20 19:30:27 |           100 |
  | 2023-07-27 22:29:21 |           200 |
  | 2023-07-27 23:10:06 |           300 |
  */
  running_capacity_commitment_slot_data AS (
    SELECT
      change_timestamp,
      SUM(slot_count_delta)
        OVER (ORDER BY change_timestamp RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
        AS capacity_slot
    FROM
      capacity_commitment_slot_data
  ),

  /* Add next_change_timestamp to the above data,
   which will be used when joining with reservation data. For example:
  +---------------------+-----------------------+---------------+
  |  change_timestamp   | next_change_timestamp | capacity_slot |
  +---------------------+-----------------------+---------------+
  | 2023-07-20 19:30:27 |   2023-07-27 22:29:21 |           100 |
  | 2023-07-27 22:29:21 |   2023-07-27 23:10:06 |           200 |
  | 2023-07-27 23:10:06 |   2023-07-31 00:14:37 |           300 |
  */
  running_capacity_commitment_slot_data_with_next_change AS (
    SELECT
      change_timestamp,
      IFNULL(LEAD(change_timestamp) OVER (ORDER BY change_timestamp ASC), CURRENT_TIMESTAMP())
        AS next_change_timestamp,
      capacity_slot
    FROM
      running_capacity_commitment_slot_data
  ),

  /*
  Whenever we have a change in reservations or commitments,
  the scaled_slots_and_baseline_not_covered_by_commitments will be changed.
  Hence we get a collection of all the change_timestamp from both tables.
  +---------------------+
  |  change_timestamp   |
  +---------------------+
  | 2023-07-20 19:30:27 |
  | 2023-07-27 22:24:15 |
  | 2023-07-27 22:25:21 |
  | 2023-07-27 22:29:21 |
  | 2023-07-27 22:39:14 |
  | 2023-07-27 22:40:20 |
  | 2023-07-27 22:54:18 |
  | 2023-07-27 22:55:23 |
  | 2023-07-27 23:10:06 |
  */
  merged_timestamp AS (
    SELECT
      change_timestamp
    FROM
      running_reservation_slot_data
    UNION DISTINCT
    SELECT
      change_timestamp
    FROM
      running_capacity_commitment_slot_data
  ),

  /*
  Change running reservation-slots and make sure we have one row when commitment changes.
  +---------------------+-------------------------+----------------+
  |  change_timestamp   | autoscale_current_slots | baseline_slots |
  +---------------------+-------------------------+----------------+
  | 2023-07-20 19:30:27 |                       0 |              0 |
  | 2023-07-27 22:24:15 |                       0 |            300 |
  | 2023-07-27 22:25:21 |                     180 |            300 |
  | 2023-07-27 22:29:21 |                     180 |            300 |
  | 2023-07-27 22:39:14 |                     100 |            300 |
  | 2023-07-27 22:40:20 |                     100 |            600 |
  | 2023-07-27 22:54:18 |                     220 |            600 |
  | 2023-07-27 22:55:23 |                     120 |            600 |
  | 2023-07-27 23:10:06 |                     120 |            600 |
  */
  running_reservation_slot_data_with_merged_timestamp AS (
    SELECT
      change_timestamp,
      IFNULL(
        autoscale_current_slots,
        IFNULL(
          LAST_VALUE(autoscale_current_slots IGNORE NULLS) OVER (ORDER BY change_timestamp ASC), 0))
        AS autoscale_current_slots,
      IFNULL(
        baseline_slots,
        IFNULL(LAST_VALUE(baseline_slots IGNORE NULLS) OVER (ORDER BY change_timestamp ASC), 0))
        AS baseline_slots
    FROM
      running_reservation_slot_data
    RIGHT JOIN
      merged_timestamp
      USING (change_timestamp)
  ),

  /*
  Join the above, so that we will know the number for baseline not covered by commitments.
  +---------------------+-----------------------+-------------------------+------------------------------------+
  |  change_timestamp   | next_change_timestamp | autoscale_current_slots | baseline_not_covered_by_commitment |
  +---------------------+-----------------------+-------------------------+------------------------------------+
  | 2023-07-20 19:30:27 |   2023-07-27 22:24:15 |                       0 |                                  0 |
  | 2023-07-27 22:24:15 |   2023-07-27 22:25:21 |                       0 |                                200 |
  | 2023-07-27 22:25:21 |   2023-07-27 22:29:21 |                     180 |                                200 |
  | 2023-07-27 22:29:21 |   2023-07-27 22:39:14 |                     180 |                                100 |
  | 2023-07-27 22:39:14 |   2023-07-27 22:40:20 |                     100 |                                100 |
  | 2023-07-27 22:40:20 |   2023-07-27 22:54:18 |                     100 |                                400 |
  | 2023-07-27 22:54:18 |   2023-07-27 22:55:23 |                     220 |                                400 |
  | 2023-07-27 22:55:23 |   2023-07-27 23:10:06 |                     120 |                                400 |
  | 2023-07-27 23:10:06 |   2023-07-31 00:16:07 |                     120 |                                300 |
  */
  scaled_slots_and_baseline_not_covered_by_commitments AS (
    SELECT
      r.change_timestamp,
      IFNULL(LEAD(r.change_timestamp) OVER (ORDER BY r.change_timestamp ASC), CURRENT_TIMESTAMP())
        AS next_change_timestamp,
      r.autoscale_current_slots,
      IF(
        r.baseline_slots - IFNULL(c.capacity_slot, 0) > 0,
        r.baseline_slots - IFNULL(c.capacity_slot, 0),
        0) AS baseline_not_covered_by_commitment
    FROM
      running_reservation_slot_data_with_merged_timestamp r
    LEFT JOIN
      running_capacity_commitment_slot_data_with_next_change c
      ON
        r.change_timestamp >= c.change_timestamp
        AND r.change_timestamp < c.next_change_timestamp
  ),

  /*
  The slot_seconds between each changes. For example:
  +---------------------+--------------------+
  |  change_timestamp   | slot_seconds |
  +---------------------+--------------+
  | 2023-07-20 19:30:27 |            0 |
  | 2023-07-27 22:24:15 |        13400 |
  | 2023-07-27 22:25:21 |        91580 |
  | 2023-07-27 22:29:21 |       166320 |
  | 2023-07-27 22:39:14 |        13200 |
  | 2023-07-27 22:40:20 |       419500 |
  | 2023-07-27 22:54:18 |        40920 |
  | 2023-07-27 22:55:23 |       459160 |
  | 2023-07-27 23:10:06 |     11841480 |
  */
  slot_seconds_data AS (
    SELECT
      change_timestamp,
      GetSlotSecondsBetweenChanges(
        autoscale_current_slots + baseline_not_covered_by_commitment,
        UNIX_MILLIS(change_timestamp),
        UNIX_MILLIS(next_change_timestamp),
        UNIX_MILLIS(start_time),
        UNIX_MILLIS(end_time)) AS slot_seconds
    FROM
      scaled_slots_and_baseline_not_covered_by_commitments
    WHERE
      change_timestamp <= end_time AND next_change_timestamp > start_time
  )

/*
Final result for this example:
+--------------------+
| total_slot_seconds |
+--------------------+
|           13045560 |
*/
SELECT
  SUM(slot_seconds) AS total_slot_seconds
FROM
  slot_seconds_data

Memantau performa tugas

Anda mungkin perlu menyesuaikan max_slots penskalaan otomatis untuk menghindari biaya yang lebih tinggi. Kueri berikut memberikan konteks tentang performa tugas sehingga Anda dapat memilih jumlah slot penskalaan otomatis yang tepat untuk workload Anda.

Kueri berikut memberikan detail tentang performa tugas sebelumnya untuk reservasi Anda:

SELECT
    AVG(TIMESTAMP_DIFF(end_time, creation_time, MILLISECOND)) as avg_latency_ms,
    SUM(total_bytes_processed) as total_bytes,
    COUNT(*) as query_numbers,
FROM
    `PROJECT_ID.region-REGION_NAME`.INFORMATION_SCHEMA.JOBS_BY_ORGANIZATION
WHERE creation_time >= START_TIME
    AND creation_time < END_TIME
    AND (statement_type != "SCRIPT" OR statement_type IS NULL)
    AND reservation_id = RESERVATION_ID

Ganti kode berikut:

  • PROJECT_ID: ID project
  • REGION_NAME: region untuk project Anda
  • START_TIME: waktu pembuatan yang Anda inginkan untuk mulai melihat data
  • END_TIME: waktu pembuatan saat Anda ingin berhenti melihat data
  • RESERVATION_ID: ID reservasi

Contoh berikut mendapatkan detail tugas selama periode lima hari:

SELECT
    AVG(TIMESTAMP_DIFF(end_time, creation_time, MILLISECOND)) as avg_latency_ms,
    SUM(total_bytes_processed) as total_bytes,
    COUNT(*) as query_numbers,
FROM
    `myproject.region-us`.INFORMATION_SCHEMA.JOBS_BY_ORGANIZATION
WHERE creation_time >= '2024-06-25 00:00:00-07'
    AND creation_time < '2024-06-30 00:00:00-07'
    AND (statement_type != "SCRIPT" OR statement_type IS NULL)
    AND reservation_id = reservationID

Kuota

Jumlah ukuran reservasi maksimum tidak boleh melebihi kuota slot.

Untuk mengetahui informasi tentang kuota, lihat Kuota dan batas.

Langkah berikutnya

  • Untuk mengetahui informasi selengkapnya tentang edisi BigQuery, lihat Pengantar BigQuery.
  • Untuk mengetahui informasi selengkapnya tentang slot, lihat Memahami slot.
  • Untuk mengetahui informasi selengkapnya tentang reservasi, lihat Pengantar reservasi.