web-dev-qa-db-fra.com

Firebase Cloud Functions - réponse lente lors de l'interrogation de Firestore

J'ai une simple fonction cloud dans Firebase qui prend JSON dans un http POST et l'enregistre dans une collection Firestore. Il lui est alloué 512 Mo de mémoire.

Les performances de cette fonction cloud sont très médiocres. S'il est exécuté en continu, l'aller-retour varie de 200 à 600 ms et s'il est exécuté rarement (toutes les 5 à 10 minutes), cela peut prendre de 4 à 10 secondes. Je comprends le problème du démarrage à froid, mais sur AWS, je n'ai jamais vu un démarrage à froid aussi lent ni aussi fréquent.

Mon code est ci-dessous - j'apprécierais tout aperçu sur la façon d'accélérer les performances.

'use strict';

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const db = admin.firestore();

const express = require('express');
const bodyParser = require("body-parser");
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// CORS Express middleware to enable CORS Requests.
const cors = require('cors');
app.use(cors({ Origin: true }))

app.post('/submitResponse', (req, res) => {
  console.log('/submitResponse');

  if (!req.body.info)
    res.status(422).send()

  const payload = req.body.info;
  console.log(payload);

  const responses = db.collection("responses")

  responses.add({
    payload: payload,
    timestamp: admin.firestore.FieldValue.serverTimestamp()
  }).then(function(docRef) {
    console.log("Response written with ID: ", docRef.id);
    res.status(200).send(JSON.stringify(docRef.id))
  })
  .catch(function(error) {
      console.error("Error adding document: ", error);
  });
});

exports.app = functions.https.onRequest(app);
27
James Beswick

Pour répondre certains des commentaires : au moment de la rédaction Cloud Firestore for Firebase est en fait toujours en version bêta .

Firestore is in Beta

Mais Firestore n'est probablement pas le coupable dans ce cas. Le temps de démarrage à froid de la fonction cloud éclipse très probablement toute opération de base de données que vous rencontrez.

Les fonctions cloud ont besoin de temps pour faire tourner de nouvelles instances chaque fois que vous en avez

  1. Nouvelles fonctions déployées/première invocation
  2. L'instance a été recyclée
  3. Mise à l'échelle pour gérer la charge (demande atteignant une nouvelle instance)

Il y a une section sur les performances de la fonction cloud qui mentionne les gains potentiels que vous pouvez réaliser en minimisant les dépendances de votre module.

Étant donné que les fonctions sont sans état, l'environnement d'exécution est souvent initialisé à partir de zéro (lors de ce que l'on appelle un démarrage à froid). Lors d'un démarrage à froid, le contexte global de la fonction est évalué.

Si vos fonctions importent des modules, le temps de chargement de ces modules peut augmenter la latence d'invocation lors d'un démarrage à froid. Vous pouvez réduire cette latence, ainsi que le temps nécessaire au déploiement de votre fonction, en chargeant correctement les dépendances et en ne chargeant pas les dépendances que votre fonction n'utilise pas.

Consultez également le génial vidéo Cloud Performance Atlas sur le sujet qui mentionne des conseils tels que:

  • Réduction des dépendances de bibliothèque
  • Utiliser des versions plus (plus) populaires d'un package car il est plus susceptible d'être déjà mis en cache
  • Modules de chargement paresseux qui ne sont pas critiques au démarrage

En cas de dépendances de bibliothèque, le fruit le plus bas est de se débarrasser des dépendances qu'il est possible d'implémenter soi-même et/ou qui n'utilisent qu'une ou quelques fonctions mais qui nécessitent toute la bibliothèque (je vous regarde, lodash).

1
Dennis Alund