Sardine usa Google Cloud Datastore para impulsar parte de nuestra interfaz de investigación. Datastore es una base de datos NoSQL gestionada altamente escalable con una interfaz flexible. Datastore es muy importante para nuestra infraestructura, así que siempre buscamos optimizarla.
A medida que escalamos, notamos que los costos de Datastore también aumentan sustancialmente. Esto nos llevó a profundizar en entender los tipos de costos asociados con Datastore y cómo podíamos optimizar estos costos pensando en el escalado futuro de nuestra infraestructura.
Google también tiene un producto llamado Firestore que ahora se posiciona como la próxima generación de Datastore. Cuando comenzamos, Firestore nativo no estaba en disponibilidad general. Actualmente usamos Firestore con compatibilidad con Datastore.
Entendiendo el precio de Datastore
Nuestro primer paso en esta investigación fue entender el precio de Datastore. Datastore cobra por:
- Solicitud de lectura
- Solicitud de escritura
- Solicitud de eliminación
- Almacenamiento
Después del análisis del equipo, determinamos que la mayor parte del costo de Sardine proviene del almacenamiento de datos, principalmente porque tenemos muchos datos (y índices).
Entendiendo la indexación de Datastore
Como el almacenamiento (y la indexación) era donde necesitábamos enfocarnos, quisimos entender el sistema de indexación de Datastore, ya que esto nos ayudaría a optimizar los costos de Datastore.
Índices integrados
Datastore es un almacén de documentos flexible (similar a MongoDB), y por defecto, todas las columnas están indexadas. Esto significa que, si no tenemos cuidado, terminaremos indexando muchos campos y aumentando nuestros costos.
Índices compuestos
Para soportar consultas con múltiples filtros, debemos agregar índices compuestos. Datastore también requiere índices para ordenar, así que para soportar la siguiente consulta, necesitaremos un índice compuesto de (customer_id, timestamp)
Los índices están ordenados; para soportar el orden timestamp DESC necesitaremos otro índice.
Analizando el uso de índices
Google Cloud proporciona diversos metadatos para entender el uso de índices. Tenemos que revisar el uso tanto de índices integrados como compuestos para obtener los datos de uso correctos.
Índices integrados
Para analizar el uso de índices integrados, el equipo ejecutó la siguiente consulta:
Esta consulta revela estadísticas sobre cada índice integrado, incluyendo:
- Tamaño del índice
- Última vez usado
- Última vez actualizado
Descubrimos que indexamos accidentalmente campos de lista para cada sesión, lo que consumió mucho espacio. Y esos índices ni siquiera se usaban.
Índices compuestos
Para analizar los índices compuestos, ejecutamos la siguiente consulta:
Esta consulta revela estadísticas sobre cada índice integrado, incluyendo:
- Tamaño del índice
- Última vez usado
- Última vez actualizado
Eliminando índices
Ahora que identificamos los índices costosos, el equipo puede comenzar el proceso de eliminarlos. Para los índices compuestos, como los gestionamos en terraform, es fácil eliminarlos. Los índices integrados son más complejos, porque son por objeto.
Cuando nuestro job de dataflow escribe datos en datastore, tenemos código como el siguiente:
El código no menciona nada sobre índices. Sin embargo, en este ejemplo, el campo score está indexado, porque por defecto todos los campos están indexados.
Para evitar confusiones, construimos una función envolvente buildIndexedValue y buildUnindexedValue para que el código sea más explícito, como en el siguiente ejemplo:
Además, tuvimos que desindexar campos de miles de millones de registros existentes. No hay una forma fácil de hacer esto que sepamos. Así que escribimos un script de python que lee los datos y los reescribe con un flag excludeFromIndex actualizado.
Conclusión
Los costos de Datastore a menudo crecen silenciosamente por índices innecesarios. Al hacer lo siguiente, puedes obtener ahorros de costos notables:
- Auditar las estadísticas de índices (
__Stat_Kind_BuiltinIndex__,__Stat_Kind_CompositeIndex__), - Eliminar los índices que no se usan.
- Marcar explícitamente los campos no consultables con
excludeFromIndexes=true.
Cuéntanos qué piensas de este enfoque. ¡Asegúrate de investigar tu solución de almacenamiento de datos para buscar ahorros de costos y optimización!
Si eres alguien a quien le apasiona optimizar el uso de la nube, aplica aquí!

