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 por múltiplos de 100 hasta que haya alcanzado la cantidad de ranuras necesarias para ejecutar los trabajos o hasta alcanzar la cantidad máxima de ranuras disponibles para la reserva.
- El escalamiento vertical se basa en una estimación y puede exceder o no aprovisionarse. Por ejemplo, el escalador automático puede escalar a 500 ranuras cuando solo se necesitan 400, o intenta escalar una cantidad pequeña cuando la carga de trabajo puede manejarse sin escalamiento.
- 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.
- Si bien la cantidad de ranuras siempre escala por múltiplos de 100, puede escalar más de 100 ranuras en un solo paso. Por ejemplo, si tu carga de trabajo requiere 450 ranuras adicionales, BigQuery puede intentar escalar en 500 ranuras a la vez para cumplir con el requisito de capacidad.
- BigQuery reduce la escala cuando las ranuras asignadas superan la cantidad de ranuras necesarias y la capacidad de ajuste de escala automático permanece estable durante un tiempo.
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 de 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 deseas disminuir las 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 las ranuras del modelo de referencia superan las ranuras confirmadas. De lo contrario, puedes disminuir las ranuras del modelo de referencia cada pocos minutos.
Las ranuras del modelo de referencia y de ajuste de escala automático están diseñadas para proporcionar capacidad en función de 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 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, las ranuras del modelo de referencia deben usarse por completo antes del escalamiento.
Las reservas usan y agregan ranuras con la siguiente prioridad:
- Ranuras del modelo de referencia.
- 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.
- Ranuras con ajuste de escala automático.
En el siguiente ejemplo, las ranuras escalan a partir de una cantidad de modelo de referencia especificada. Las reservas etl
y dashboard
tienen un tamaño de referencia de 700 y 300 ranuras, respectivamente.
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:
- 700 ranuras del modelo de referencia.
- 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. - Escala 600 ranuras adicionales hasta alcanzar el tamaño máximo de reserva.
Usa compromisos de ranuras
En el siguiente ejemplo, se muestra el ajuste de escala automático de ranuras con compromisos de capacidad.
Al igual que los modelos de referencia de reserva, 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 las ranuras 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 del modelo de referencia en la reserva
etl
y en la reservadashboard
. - 700 ranuras de modelo de referencia asignadas a la reserva
etl
. - 300 ranuras de modelo de referencia asignadas a la reserva
dashboard
. -
Ranuras con ajuste de escala automático de 600 para la reserva
etl
. -
Ranuras con 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.
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, el máximo potencial de ranuras en esta reserva es de 2,100. Las ranuras con ajuste de escala automático son ranuras adicionales por encima del compromiso de capacidad.
Prácticas recomendadas del ajuste de escala automático
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 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.
Ten en cuenta que se te cobrará por la cantidad de ranuras escaladas, no por la cantidad de ranuras que se usan. Si la cantidad máxima de ranuras de ajuste de escala automático es demasiado grande, BigQuery podría escalar más de lo necesario, lo que genera costos adicionales.
Por ejemplo, un trabajo puede usar una gran cantidad de ranuras en un punto, pero solo necesita una cantidad significativamente menor. Debido a que BigQuery no libera las ranuras que no se usan de inmediato, esto puede reducir el uso si ningún otro trabajo en la reserva puede usar esas ranuras. Cuando se reduce el valor máximo para una reserva, se reduce la cantidad máxima de ranuras asignadas, lo que hace que el uso de ranuras del trabajo sea menos repentino y mejore el uso de trabajos de ranuras asignadas.
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.
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 una en una al backend, ya sea que las consultas usen o no la caché. Sin ranuras de referencia, esto puede causar escalamiento inesperado y generar costos altos.
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.
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.
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 de la lista p99.
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 un 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. En la primera secuencia de comandos, se muestran los segundos de ranura facturados que cubre commitment_plan
, mientras que la segunda secuencia de comandos muestra los segundos de ranura facturados que no están cubiertos por un compromiso.
Solo necesitas 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 y los compromisos de capacidad borrados se quitan de las vistas de esquema de información al final del período de retención de datos. Especifica un período reciente que no contenga las reservas y los compromisos borrados para obtener resultados correctos.
Es posible que el resultado de las secuencias de comandos no coincida con exactitud 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.
Expande 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 las ranuras que no cubren los compromisos para una edición en particular. Este uso contiene dos tipos de ranuras, ranuras escaladas y ranuras del modelo de referencia que no están cubiertas por 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
Cuotas
La suma del tamaño máximo de tu reserva no debe exceder tu cuota de ranuras.
Para obtener información sobre las cuotas, consulta Cuotas y límites.
¿Qué sigue?
- Para obtener más información sobre las ediciones de BigQuery, consulta Introducción a BigQuery.
- Para obtener más información sobre las ranuras, consulta Información sobre las ranuras.
- Para obtener más información acerca de las reservas, consulta Introducción a las reservas.