Introduzione alla scalabilità automatica degli slot

Per le prenotazioni configurate per l'utilizzo della scalabilità automatica degli slot scalano automaticamente allocata per soddisfare le esigenze dei carichi di lavoro. Come carico di lavoro aumenta o diminuisce, BigQuery regola in modo dinamico slot a un livello appropriato. Prenotazioni con la scalabilità automatica degli slot è disponibile solo con BigQuery di Google Cloud.

Utilizza prenotazioni con scalabilità automatica

Non è necessario acquistare impegni di slot prima di creare la scalabilità automatica prenotazioni. Gli impegni di slot offrono una tariffa scontata per l'utilizzo costante ma sono facoltativi con le prenotazioni a scalabilità automatica. Per creare una scalabilità automatica, devi assegnare a una prenotazione un numero massimo di slot (il numero massimo dimensioni della prenotazione). Puoi identificare il numero massimo di slot a scalabilità automatica sottraendo la dimensione massima della prenotazione per eventuali slot di riferimento facoltativi assegnati la prenotazione.

Quando crei prenotazioni con scalabilità automatica, considera quanto segue:

  • BigQuery scala le prenotazioni in multipli di 100 fino a quando di slot necessari per eseguire i job, o ha raggiunto il numero massimo di slot disponibili per la prenotazione.
  • Lo scale up si basa su una stima e potrebbe comportare un provisioning eccessivo o insufficiente. Per Ad esempio, il gestore della scalabilità automatica può scalare fino a 500 slot quando sono necessari solo 400 slot. di scalare una piccola quantità quando il carico di lavoro potrebbe essere gestito senza e la scalabilità delle applicazioni.
  • Gli slot con scalabilità automatica vengono addebitati in base ai prezzi del calcolo della capacità per la tua versione associata durante lo scale up. Ti viene addebitato l'importo per il numero di slot scalati, non il numero di slot utilizzati. L'addebito si applica anche se il job che causa lo scale up di BigQuery non va a buon fine.
  • Anche se il numero di slot è sempre scalato di multipli di 100, può essere adeguato più di 100 slot in un solo passaggio. Ad esempio, se il carico di lavoro richiede e 450 slot aggiuntivi, BigQuery può tentare di scalare contemporaneamente per soddisfare il requisito di capacità.
  • BigQuery fa lo scale down quando gli slot allocati superano il numero di slot richiesti e la capacità di scalabilità automatica è rimasta stabile per un po' di tempo.

Per informazioni su come utilizzare la scalabilità automatica, consulta Utilizzare la scalabilità automatica degli slot.

Utilizzo delle prenotazioni con slot di riferimento e con scalabilità automatica

Oltre a specificare la dimensione massima della prenotazione, puoi facoltativamente specificare un numero di riferimento di slot per prenotazione. La base di riferimento è il minimo di slot che saranno sempre allocati alla prenotazione e potrai addebitarle sempre. Gli slot di scalabilità automatica vengono aggiunti solo dopo gli slot di riferimento (e quelli inattivi, se applicabili) vengono consumati. Puoi condividere contenuti inattivi slot di riferimento in una prenotazione con altre prenotazioni che richiedono capacità.

Puoi aumentare il numero di slot di riferimento in una prenotazione a intervalli minuti. Per ridurre gli slot di riferimento, il limite è una volta sola ora se di recente hai modificato la capacità slot di base e la base gli slot superano quelli impegnati. Altrimenti, puoi diminuire il valore basale a intervalli regolari di pochi minuti.

Gli slot di riferimento e con scalabilità automatica sono pensati per fornire capacità in base carico di lavoro recente. Se prevedi un grande carico di lavoro molto diverso carichi di lavoro recenti, ti consigliamo di aumentare in anticipo rispetto all'evento, anziché fare affidamento sugli slot di scalabilità automatica per per il carico di lavoro.

Se la prenotazione non ha slot di riferimento o non è configurata per il prestito slot inattivi di altri delle prenotazioni, quindi BigQuery tenta di scalare. In caso contrario, gli slot di riferimento devono essere utilizzati completamente prima della scalabilità.

Le prenotazioni utilizzano e aggiungono slot con la priorità seguente:

  1. Slot di riferimento.
  2. Condivisione di slot inattivi (se abilitata). Le prenotazioni possono condividere solo la base di riferimento inattiva o slot impegnati da altre prenotazioni create con lo stesso e nella stessa regione.
  3. Slot a scalabilità automatica.

Nell'esempio seguente, gli slot scalano in base a un importo di riferimento specificato. La Le prenotazioni etl e dashboard hanno una dimensione di riferimento di 700 e 300 slot rispettivamente.

Esempio di scalabilità automatica senza impegni.

In questo esempio, la prenotazione etl può scalare fino a 1300 slot (700 valori di riferimento più 600 slot a scalabilità automatica). Se la prenotazione dashboard non è in uso, la prenotazione etl può utilizzare i 300 slot della prenotazione dashboard se non è in esecuzione alcun job, fino a un massimo di 1600 slot possibili.

La prenotazione dashboard può scalare fino a 1100 slot (300 slot di riferimento più 800 slot a scalabilità automatica). Se la prenotazione etl è completamente inattiva, La prenotazione dashboard può scalare fino a un massimo di 1800 slot (300 base di riferimento più 800 slot a scalabilità automatica più 700 slot inattivi nella prenotazione etl).

Se la prenotazione etl richiede più di 700 slot di riferimento, che sono sempre disponibile, cerca di aggiungere slot utilizzando i metodi seguenti ordine:

  1. 700 slot di riferimento.
  2. Condivisione dello slot inattivo con 300 slot di riferimento nella prenotazione dashboard. La prenotazione condivide solo gli slot di riferimento inattivi con altre prenotazioni create con la stessa versione.
  3. Fai lo scale up di 600 slot aggiuntivi alla dimensione massima della prenotazione.

Utilizzo degli impegni slot

L'esempio seguente mostra la scalabilità automatica degli slot utilizzando gli impegni di capacità.

Esempio di scalabilità automatica

Come le basi della prenotazione, gli impegni slot consentono di allocare un di slot disponibili per tutte le prenotazioni. A differenza degli slot di riferimento, non può essere ridotto durante il periodo di validità. Gli impegni slot sono facoltativo, ma può farti risparmiare sui costi se sono necessari slot di riferimento per lunghi periodi di nel tempo.

In questo esempio, ti viene addebitata una tariffa predefinita per l'impegno di capacità slot machine. Ti viene addebitata la tariffa di scalabilità automatica per il numero gli slot dopo l'attivazione della scalabilità automatica e le prenotazioni sono in stato di alto livello. Per la percentuale di scalabilità automatica, ti viene addebitato il numero di slot scalati, non il numero di slot utilizzati.

Numero massimo di slot disponibili

Puoi calcolare il numero massimo di slot che una prenotazione può utilizzare aggiungendo gli slot di riferimento, il numero massimo di slot a scalabilità automatica e gli eventuali slot negli impegni creati con la stessa versione e non coperti dagli slot di riferimento. L'esempio nell'immagine precedente è impostato come segue:

  • Un impegno di capacità di 1000 slot annuali. Questi slot sono assegnati slot di riferimento nella prenotazione etl e nella prenotazione dashboard.
  • 700 slot di riferimento assegnati alla prenotazione etl.
  • 300 slot di riferimento assegnati alla prenotazione dashboard.
  • Slot a scalabilità automatica di 600 per la prenotazione etl.
  • Slot a scalabilità automatica di 800 per la prenotazione dashboard.

Per la prenotazione etl, il numero massimo di slot possibile è uguale a i etl slot di riferimento (700) più i dashboard slot di riferimento (300, se tutti gli slot sono inattivi) più il numero massimo di slot a scalabilità automatica (600). Quindi, il numero massimo di slot che la prenotazione etl potrebbe utilizzare in questo esempio è 1600. Questo numero supera il numero nell'impegno di capacità.

Nell'esempio seguente, l'impegno annuale supera gli slot di riferimento assegnati.

Calcolo degli slot disponibili

In questo esempio abbiamo:

  • Un impegno di capacità di 1600 slot annuali.
  • Una dimensione massima di prenotazione di 1500 (inclusi 500 slot con scalabilità automatica).
  • 1000 slot di riferimento assegnati alla prenotazione etl.

Il numero massimo di slot disponibili per la prenotazione è uguale al di base (1000) più eventuali slot inattivi impegnati non dedicati slot di riferimento (1600 slot annuali - 1000 slot di riferimento = 600) più il numero di slot con scalabilità automatica (500). Il numero massimo di slot potenziali è 2100. Gli slot a scalabilità automatica sono slot aggiuntivi al di sopra della capacità l'impegno di un'azienda.

Best practice per la scalabilità automatica

  1. Quando utilizzi per la prima volta il gestore della scalabilità automatica, imposta il numero di slot a scalabilità automatica su un numero significativo in base al rendimento passato e atteso. Una volta viene creata, monitorare attivamente il tasso di errore, le prestazioni e regolare il numero di slot a scalabilità automatica in base alle esigenze.

  2. Tieni presente che ti viene addebitato il numero di slot scalati, non il numero di slot utilizzati. Se il numero massimo di slot a scalabilità automatica è troppo grande, BigQuery potrebbe scalare di più del necessario, comportando costi aggiuntivi.

    Ad esempio, un job potrebbe utilizzare un elevato numero di slot in un determinato punto, ma poi solo un numero notevolmente inferiore. Dal giorno BigQuery non rilascia immediatamente gli slot inutilizzati, comportano un utilizzo inferiore se nessun altro job nella prenotazione può usare tali slot. Se viene ridotto il valore massimo per una prenotazione, il numero massimo di slot allocati viene ridotto, di conseguenza il job che l'utilizzo degli slot sia meno picchi e migliora l'utilizzo del job gli slot allocati.

  3. L'utilizzo degli slot può occasionalmente superare la somma della base di riferimento più la scalabilità slot machine. Non ti viene addebitato alcun costo per l'utilizzo degli slot superiore alla tua base di riferimento più slot scalati.

  4. Il gestore della scalabilità automatica è più efficiente per carichi di lavoro intensivi e a lunga esecuzione, come carichi di lavoro con più query in parallelo. Evita di inviare query una a al backend, indipendentemente dal fatto che queste query utilizzino o meno la cache. Senza slot di riferimento, ciò potrebbe causare una scalabilità imprevista e causare costi elevati.

  5. La scalabilità automatica di BigQuery è soggetta alla disponibilità della capacità. BigQuery cerca di soddisfare la domanda in termini di capacità dei clienti in base all'utilizzo storico. Per ottenere garanzie di capacità, puoi impostare uno slot facoltativo base, ovvero il numero di slot garantiti in una prenotazione. Con le basi di riferimento, gli slot sono immediatamente disponibili e paghi per il costo che li utilizzi o meno. Per garantire una capacità disponibile per grandi quantità, richieste inorganiche, come festività a traffico elevato, il team di BigQuery con diverse settimane di anticipo.

  6. Gli slot di riferimento vengono sempre addebitati. Se viene dell'impegno, potresti aver bisogno di regolare manualmente la quantità di slot di riferimento nelle prenotazioni addebiti indesiderati. Ad esempio, supponiamo che tu abbia un impegno di 1 anno con 100 slot e una prenotazione con 100 slot di riferimento. L'impegno scade e non ha un piano di rinnovo. Alla scadenza dell'impegno, pagherai per 100 slot di riferimento con pagamento a consumo di Google.

Monitora la scalabilità automatica

Quando monitori l'utilizzo degli slot con una risorsa amministrativa grafici, potresti notare un aumento di slot scalati rispetto all'utilizzo degli slot perché i grafici agevolano il numero di slot machine per il periodo di allineamento. Per visualizzare l'utilizzo degli slot con scalabilità automatica in modo più preciso riduciamo l'opzione di intervallo di tempo. Questo aggiorna automaticamente l'allineamento periodo a un incremento minore.

Nell'esempio seguente, il grafico mostra aree annuncio molto più scalate rispetto a quanto richiesto dal carico di lavoro.

Il periodo di allineamento è impostato su un intervallo di un minuto e gli slot scalati
sono più numerosi dell'utilizzo degli slot
richieste.

Tuttavia, se riduci l'opzione relativa all'intervallo di tempo in modo che il periodo di allineamento venga per due secondi, puoi vedere che il gestore della scalabilità automatica adegua alla domanda del carico di lavoro visualizza dati più accurati. Puoi modificare l'opzione relativa all'intervallo di tempo trascinando gli intervalli di inizio e fine dell'opzione relativa all'intervallo di tempo. Per visualizzare il più preciso dati sulla domanda dei carichi di lavoro, seleziona p99 dall'elenco Metrica.

Il periodo di allineamento è impostato su un intervallo di 2 secondi e gli slot scalati
sono appropriate per il carico di lavoro
domanda.

Per avere una visione più precisa dell'utilizzo della scalabilità automatica, utilizza un periodo di allineamento compreso tra 1 e 15 secondi. Per ulteriori informazioni sui periodo di allineamento dei grafici delle risorse amministrative, vedi Intervallo di tempo .

Per informazioni sulla visualizzazione dell'utilizzo degli slot, vedi Visualizza i grafici delle risorse amministrative

Monitora la scalabilità automatica con uno schema di informazioni

Puoi usare i seguenti script SQL per controllare i secondi fatturati per un un'edizione specifica. Devi eseguire questi script nello stesso progetto sono state create. Il primo script mostra i secondi degli slot fatturati coperti commitment_plan, mentre il secondo script mostra i secondi addebitati per l'area annuncio che non sono coperto da un impegno.

Per eseguire questi script, è sufficiente impostare il valore di tre variabili:

  • start_time
  • end_time
  • edition_to_check

Questi script sono soggetti alle seguenti avvertenze:

  • Le prenotazioni e gli impegni di capacità eliminati vengono rimossi dalle informazioni viste dello schema al termine del periodo di conservazione dei dati. Specifica una finestra recente di che non contiene prenotazioni e impegni eliminati per i risultati sono corretti.

  • Il risultato degli script potrebbe non corrispondere esattamente alla fattura a causa di arrotondamenti di piccole dimensioni errori.

Lo script seguente verifica l'utilizzo degli slot coperto dagli impegni per un un'edizione specifica.

Espandi per visualizzare lo script per gli scenari coperti

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

Lo script seguente verifica l'utilizzo degli slot non coperto dagli impegni per un un'edizione specifica. Questo utilizzo contiene due tipi di slot: slot scalati e slot di riferimento non coperti dagli impegni.

Espandi per visualizzare lo script per gli scenari non coperti

/*
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

Quote

La somma delle dimensioni massime della prenotazione non deve superare la quota di slot.

Per informazioni sulle quote, consulta Quote e limiti.

Passaggi successivi