Introducción al ajuste de escala automático de ranuras

Las reservas que configuras para usar el ajuste de escala automático de ranuras escalan automáticamente la capacidad asignada para satisfacer tus demandas de carga de trabajo. A medida que tu carga de trabajo aumenta o disminuye, BigQuery ajusta de forma dinámica tus ranuras a un nivel adecuado. Las reservas con ajuste de escala automático de ranuras solo están disponibles con las ediciones de BigQuery.

Usa las reservas de ajuste de escala automático

No es necesario que compres compromisos de ranuras antes de crear las reservas de ajuste de escala automático. Los compromisos de ranuras proporcionan una tarifa con descuento para las ranuras que se usan de forma coherente, pero son opcionales con reservas de ajuste de escala automático. Para crear una reserva de ajuste de escala automático, debes asignar a una reserva una cantidad máxima de ranuras (el tamaño máximo de la reserva). Para identificar la cantidad máxima de ranuras de ajuste de escala automático, resta el tamaño máximo de la reserva por cualquier ranura de referencia opcional asignada a la reserva.

Cuando crees reservas de ajuste de escala automático, ten en cuenta lo siguiente:

  • BigQuery escala las reservas casi de inmediato hasta que alcanza la cantidad de ranuras necesarias para ejecutar los trabajos o hasta alcanzar la cantidad máxima de ranuras disponibles para la reserva. Las ranuras siempre se ajustan de forma automática a un múltiplo de 50.
  • La escalabilidad se basa en el uso real y se redondea hacia arriba hasta el incremento de 50 ranuras más cercano.
  • Las ranuras con ajuste de escala automático se cobran según los precios de procesamiento de capacidad para la edición asociada mientras se escala verticalmente. Se te cobra por la cantidad de ranuras escaladas, no por la cantidad usada. Este cargo se aplica incluso si falla el trabajo que hace que BigQuery escale verticalmente. Por este motivo, no uses el esquema de información de trabajos para que coincida con la facturación. En su lugar, consulta Supervisa el ajuste de escala automático con el esquema de información.
  • Si bien la cantidad de ranuras siempre escala por múltiplos de 50, puede escalar más de 50 ranuras en un solo paso. Por ejemplo, si tu carga de trabajo requiere 450 ranuras adicionales, BigQuery puede intentar escalar en 450 ranuras a la vez para cumplir con el requisito de capacidad.
  • BigQuery se reduce la escala verticalmente cuando las tareas asociadas con la reserva ya no necesitan la capacidad (sujeto a un mínimo de 1 minuto).

Cualquier capacidad ajustada automáticamente se retiene durante al menos 60 segundos. Este período de 60 segundos se denomina ventana de reducción. Cualquier aumento repentino en la capacidad restablece la ventana de reducción y trata todo el nivel de capacidad como una nueva concesión. Sin embargo, si transcurrieron 60 segundos o más desde el último aumento de capacidad y hay menos demanda, el sistema reduce la capacidad sin restablecer la ventana de reducción, lo que permite disminuciones consecutivas sin una demora impuesta.

Para aprender a trabajar con el ajuste de escala automático, consulta Trabaja con el ajuste de escala automático de ranuras.

Usa reservas con ranuras de referencia y ajuste de escala automático

Además de especificar el tamaño máximo de reserva, puedes de manera opcional especificar una cantidad de ranuras del modelo de referencia por reserva. El modelo de referencia corresponde a la cantidad mínima de ranuras que se asignarán permanentemente a la reserva y siempre se te cobrará por ellas. Las ranuras con ajuste de escala automático solo se agregan después de que se consumen todas las ranuras del modelo de referencia (y las ranuras inactivas, si corresponde). Puedes compartir las ranuras del modelo de referencia inactivas en una reserva con otras reservas que necesiten capacidad.

Puedes aumentar la cantidad de ranuras del modelo de referencia en una reserva cada pocos minutos. Si quieres disminuir tus ranuras del modelo de referencia, tienes un límite de una vez por hora si cambiaste recientemente la capacidad de las ranuras del modelo de referencia y estas superan las ranuras confirmadas. De lo contrario, puedes disminuir tus ranuras del modelo de referencia cada pocos minutos.

Los planes de referencia y las ranuras de ajuste de escala automático están diseñados para proporcionar capacidad según tu carga de trabajo reciente. Si prevés una gran carga de trabajo que sea muy diferente a tus cargas de trabajo recientes, te recomendamos que aumentes la capacidad del modelo de referencia antes del evento, en lugar de depender de las ranuras de ajuste de escala automático para cubrir la capacidad de la carga de trabajo. Si tienes un problema para aumentar la capacidad del modelo de referencia, vuelve a intentar la solicitud después de esperar 15 minutos.

Si la reserva no tiene ranuras del modelo de referencia o no está configurada para tomar prestadas ranuras inactivas de otras reservas, BigQuery intenta escalar. De lo contrario, los espacios del modelo de referencia deben estar completamente ocupados antes de la escala.

Las reservas usan y agregan ranuras con la siguiente prioridad:

  1. Ranuras del modelo de referencia.
  2. Uso compartido de ranuras inactivas (si está habilitado). Las reservas solo pueden compartir el modelo de referencia inactivo o las ranuras confirmadas de otras reservas que se crearon con la misma edición y la misma región.
  3. Ranuras con ajuste de escala automático.

En el siguiente ejemplo, las ranuras se escalan a partir de un importe de referencia especificado. Las reservas etl y dashboard tienen un tamaño de referencia de 700 y 300 ranuras, respectivamente.

Ejemplo de escalamiento automático sin compromisos.

En este ejemplo, la reserva etl puede escalar a 1,300 ranuras (700 ranuras de modelo de referencia más 600 ranuras de ajuste de escala automático). Si la reserva dashboard noestá en uso, la reserva etl puede usar las 300 ranuras de la reserva dashboard si no se ejecuta ningún trabajo allí, lo que genera un máximo de 1,600 ranuras posibles.

La reserva dashboard puede escalar a 1,100 ranuras (300 ranuras de modelo de referencia más 800 ranuras de ajuste de escala automático). Si la reserva etl está completamente inactiva, la reserva dashboard puede escalar a un máximo de 1,800 ranuras (300 ranuras de modelo de referencia más 800 ranuras de ajuste de escala automático más 700 ranuras inactivas en la reserva etl).

Si la reserva etl requiere más de 700 ranuras de modelo de referencia, que siempre están disponibles, intenta agregar ranuras mediante los siguientes métodos en orden:

  1. 700 ranuras del modelo de referencia.
  2. Uso compartido de ranuras inactivas con las 300 ranuras de referencia en la reserva dashboard Tu reserva solo comparte las ranuras de modelo de referencia inactivas con otras reservas que se crean con la misma edición.
  3. Escala 600 ranuras adicionales hasta alcanzar el tamaño máximo de reserva.

Cómo usar los compromisos de ranuras

En el siguiente ejemplo, se muestra el ajuste de escala automático de las ranuras con compromisos de capacidad.

Ejemplo de ajuste de escala automático

Al igual que los modelos de referencia de reservas, los compromisos de ranuras te permiten asignar una cantidad fija de ranuras que están disponibles para todas las reservas. A diferencia de las ranuras del modelo de referencia, un compromiso no se puede reducir durante el plazo. Los compromisos de ranuras son opcionales, pero pueden ahorrar costos si se requieren ranuras del modelo de referencia por períodos prolongados.

En este ejemplo, se te cobra una tarifa predefinida por los intervalos de compromiso de capacidad. Se te cobra la tarifa de ajuste de escala automático por la cantidad de ranuras de ajuste de escala automático después de que se active el ajuste de escala automático y las reservas están en estado de ampliación. En el caso de la tarifa de ajuste de escala automático, se te cobra por la cantidad de ranuras escaladas, no por la cantidad usada.

Cantidad máxima de ranuras disponibles

Puedes calcular la cantidad máxima de ranuras que puede usar una reserva si agregas las ranuras de modelo de referencia, la cantidad máxima de ranuras para el ajuste de escala automático y cualquier ranura en los compromisos que se crearon con la misma edición y no están cubiertos por las ranuras de modelo de referencia. El ejemplo de la imagen anterior se configura de la siguiente manera:

  • Un compromiso de capacidad de 1,000 ranuras anuales. Esas ranuras se asignan como ranuras de modelo de referencia en la reserva etl y la reserva dashboard.
  • 700 ranuras de modelo de referencia asignadas a la reserva etl.
  • 300 ranuras de modelo de referencia asignadas a la reserva dashboard.
  • Ranuras de ajuste de escala automático de 600 para la reserva etl.
  • Ranuras de ajuste de escala automático de 800 para la reserva dashboard.

Para la reserva etl, la cantidad máxima de ranuras posible es igual a las ranuras del modelo de referencia etl (700) más las ranuras del modelo de referencia dashboard (300, si todas las ranuras están inactivas), más la cantidad máxima de ranuras con ajuste de escala automático (600). Entonces, la cantidad máxima de ranuras que la reserva etl puede usar en este ejemplo es 1,600. Esta cantidad supera la cantidad del compromiso de capacidad.

En el siguiente ejemplo, el compromiso anual excede las ranuras de referencia asignadas.

Cálculo de las ranuras disponibles

En este ejemplo, tenemos lo siguiente:

  • Un compromiso de capacidad de 1,600 ranuras anuales.
  • Un tamaño máximo de reserva de 1,500 (incluidas 500 ranuras de ajuste de escala automático)
  • 1,000 ranuras de modelo de referencia asignadas a la reserva etl.

La cantidad máxima de ranuras disponibles para la reserva es igual a las ranuras del modelo de referencia (1,000) más cualquier ranura inactiva comprometida que no esté dedicada a las ranuras del modelo de referencia (1,600 ranuras anuales - 1,000 ranuras de referencia = 600) más la cantidad de ranuras con ajuste de escala automático (500) Por lo tanto, la cantidad máxima de ranuras posibles en esta reserva es de 2,100. Las ranuras con ajuste de escala automático son ranuras adicionales por sobre el compromiso de capacidad.

Prácticas recomendadas del ajuste de escala automático

  1. Cuando uses el escalador automático por primera vez, establece la cantidad de ranuras de ajuste de escala automático en un número significativo según el rendimiento anterior y el esperado. Una vez creada la reserva, supervisa de forma activa la tasa de fallas, el rendimiento y la facturación, y ajusta la cantidad de ranuras de ajuste de escala automático según sea necesario.

  2. El escalador automático tiene un mínimo de 1 minuto antes de reducir la escala verticalmente, por lo que es importante establecer la cantidad máxima de ranuras con escalamiento automático para equilibrar el rendimiento y el costo. Si la cantidad máxima de ranuras de ajuste de escala automático es demasiado grande y tu trabajo puede usar todas las ranuras para completar un trabajo en segundos, de cualquier manera, se incurren en costos por las ranuras máximas durante todo el minuto. Si reduces la cantidad máxima de ranuras a la mitad del valor actual, tu reserva se escala a una cantidad menor y la tarea puede usar más slot_seconds durante ese minuto, lo que reduce el desperdicio. Para obtener ayuda para determinar los requisitos de tus ranuras, consulta Supervisa el rendimiento de los trabajos. Como enfoque alternativo para determinar tus requisitos de ranuras, consulta Visualiza las recomendaciones de ranuras de edición.

  3. En ocasiones, el uso de ranuras puede exceder la suma del modelo de referencia y las ranuras a gran escala. No se te cobrará por el uso de ranuras que sea mayor que tu modelo de referencia, más las ranuras escaladas.

  4. El escalador automático es más eficiente para cargas de trabajo pesadas y de larga duración, como las cargas de trabajo con varias consultas simultáneas. Evita enviar consultas de a una a la vez, ya que cada una escala la reserva, en la que permanecerá escalada durante un mínimo de 1 minuto. Si envías consultas de forma continua, lo que genera una carga de trabajo constante, establecer un modelo de referencia y comprar un compromiso proporciona una capacidad constante a un precio con descuento.

  5. El ajuste de escala automático de BigQuery está sujeto a disponibilidad de capacidad. BigQuery intenta satisfacer la demanda de capacidad del cliente según el uso histórico. Para lograr garantías de capacidad, puedes establecer un modelo de referencia de ranura opcional, que es la cantidad de ranuras garantizadas en una reserva. Con los modelos de referencia, las ranuras están disponibles de inmediato y pagas por ellas, sin importar si las usas o no. Si deseas garantizar que la capacidad esté disponible para las demandas inorgánicas grandes, como los días festivos de alto tráfico, comunícate con el equipo de BigQuery con varias semanas de anticipación.

  6. Las ranuras de referencia siempre se cobran. Si un compromiso de capacidad vence, es posible que debas ajustar de forma manual la cantidad de ranuras del modelo de referencia en tus reservas para evitar cargos no deseados. Por ejemplo, considera que tienes un compromiso de 1 año con 100 ranuras y una reserva con 100 ranuras de modelo de referencia. El compromiso vence y no tiene un plan de renovación. Una vez que venza el compromiso, pagarás por 100 ranuras de referencia en la tarifa de prepago.

Supervisa el ajuste de escala automático

Cuando supervisas el uso de ranuras con gráficos de recursos administrativos, es posible que veas ranuras mucho más escaladas que el uso de las ranuras, ya que los gráficos suavizan la cantidad de ranuras usadas durante el período de alineación. Para ver el uso de ranuras de ajuste de escala automático con detalles más precisos, reduce la opción de período. Esto actualiza automáticamente el período de alineación a un incremento menor.

En el siguiente ejemplo, el gráfico muestra ranuras mucho más escaladas que las que requiere la carga de trabajo.

El período de alineación se establece en un intervalo de un minuto y las ranuras escaladas aparecen más de lo que exige el uso de las ranuras.

Sin embargo, si acortas la opción de período para que el período de alineación sea de dos segundos, puedes ver que el escalador automático escala a la demanda de carga de trabajo y muestra datos más precisos. Para ajustar la opción del período, arrastra los rangos de inicio y finalización de la opción de período. Para mostrar los datos de demanda de carga de trabajo más precisos, selecciona p99 en la lista Métrica.

El período de alineación se establece en un intervalo de dos segundos, y las ranuras escaladas son adecuadas para la demanda de carga de trabajo.

Para obtener una vista más precisa del uso del ajuste de escala automático, usa un período de alineación de entre 1 y 15 segundos. Para obtener más información sobre el período de alineación de los gráficos de recursos administrativos, consulta Opción de períodos.

Para obtener información sobre cómo ver el uso de las ranuras, consulta Visualiza gráficos de recursos administrativos.

Supervisa el ajuste de escala automático con el esquema de información

Puedes usar las siguientes secuencias de comandos de SQL para verificar los segundos de ranura facturados de una edición en particular. Debes ejecutar estas secuencias de comandos en el mismo proyecto en el que se crearon las reservas. La primera muestra los segundos de espacio facturado cubiertos por commitment_plan, mientras que la segunda muestra los segundos de espacio facturado que no están cubiertos por un compromiso.

Solo debes establecer el valor de tres variables para ejecutar estas secuencias de comandos:

  • start_time
  • end_time
  • edition_to_check

Estas secuencias de comandos están sujetas a las siguientes advertencias:

  • Las reservas borradas y los compromisos de capacidad se quitan de las vistas de esquemas de información al final del período de retención de datos. Especifica un período reciente que no contenga reservas ni compromisos borrados para obtener resultados correctos.

  • Es posible que el resultado de las secuencias de comandos no coincida exactamente con la factura debido a pequeños errores de redondeo.

La siguiente secuencia de comandos verifica el uso de ranuras que cubren los compromisos para una edición en particular.

Expandir para ver la secuencia de comandos de las situaciones cubiertas

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

La siguiente secuencia de comandos verifica el uso de ranuras que no cubren los compromisos para una edición en particular. Este uso contiene dos tipos de ranuras: las escaladas y las del modelo de referencia que no están cubiertas por los compromisos.

Expande para ver la secuencia de comandos de situaciones no cubiertas

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

Supervisar el rendimiento del trabajo

Es posible que debas ajustar tu max_slots de escalamiento automático para evitar costos más altos. La siguiente consulta proporciona contexto sobre el rendimiento de tu trabajo para que puedas elegir la cantidad correcta de ranuras de ajuste de escala automático para tu carga de trabajo.

La siguiente consulta proporciona detalles sobre el rendimiento de los trabajos anteriores de tus reservas:

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

Reemplaza lo siguiente:

  • PROJECT_ID: El ID del proyecto
  • REGION_NAME: Es la región del proyecto.
  • START_TIME: Es la hora de creación a partir de la que deseas comenzar a ver los datos.
  • END_TIME: Es la hora de creación a partir de la cual quieres dejar de ver los datos.
  • RESERVATION_ID: es el ID de la reserva.

En el siguiente ejemplo, se obtienen los detalles de la tarea durante un período de cinco días:

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

Cuotas

La suma del tamaño máximo de reserva no debe superar tu cuota de ranuras.

Para obtener información sobre las cuotas, consulta Cuotas y límites.

¿Qué sigue?