Snowpipe Streaming Classic - Meilleures pratiques¶
Optimisation des coûts¶
Comme meilleure pratique, nous recommandons d’appeler l’API avec moins de clients Snowpipe Streaming qui écrivent plus de données par seconde. Utilisez l’application Java ou Scala pour agréger des données provenant de plusieurs sources telles que des IoT dispositifs ou des capteurs, puis utilisez Snowflake Ingest SDK pour appeler l’API et charger les données à des débits plus élevés. Le API regroupe efficacement les données de plusieurs tables cibles dans un compte.
Un seul client Snowpipe Streaming peut ouvrir plusieurs canaux pour envoyer des données, mais le coût du client n’est facturé que par client actif. Le nombre de canaux n’a pas d’incidence sur le coût du client. Par conséquent, nous vous recommandons d’utiliser plusieurs canaux par client pour optimiser les performances et les coûts.
L’utilisation des mêmes tables pour l’ingestion par lots et par streaming peut également entraîner une réduction des coûts de calcul de Snowpipe Streaming en raison d’opérations de migration de fichiers anticipées. Si le clustering automatique est également activé sur la même table que celle dans laquelle Snowpipe Streaming insère, les coûts de calcul pour la migration des fichiers peuvent être réduits. L’opération de clustering permet d’optimiser et de migrer les données au cours de la même transaction.
Recommandations sur les performances¶
Pour des performances optimales dans les déploiements à haut débit, nous recommandons les actions suivantes :
Si vous chargez plusieurs lignes, l’utilisation de
insertRows
est plus efficace et plus rentable que d’appelerinsertRow
plusieurs fois, car moins de temps est consacré aux verrous.Maintenez la taille de chaque lot de lignes transmis à
insertRows
en dessous de 16 MB compressés.La taille optimale des lots de lignes est comprise entre 10 et 16 MB.
Transmettez les valeurs des colonnes TIME, DATE, et toutes les colonnes TIMESTAMP comme l’un des types pris en charge du paquet
java.time
.Lorsque vous créez un canal à l’aide de
OpenChannelRequest.builder
, définissezOnErrorOption
surOnErrorOption.CONTINUE
et vérifiez manuellement la valeur de retour deinsertRows
pour détecter d’éventuelles erreurs d’ingestion. Cette approche conduit actuellement à de meilleures performances qu’en s’appuyant sur des exceptions levées lors de l’utilisation deOnErrorOption.ABORT
.Lorsque vous définissez le niveau de journalisation par défaut sur DEBUG, assurez-vous que les enregistreurs suivants continuent à connecter sur INFO : leur sortie sur DEBUG est très verbeuse, ce qui peut entraîner une forte dégradation de la performance.
net.snowflake.ingest.internal.apache.parquet
org.apache.parquet
Les canaux doivent durer longtemps lorsqu’un client insère activement des données, et ils doivent être réutilisés, car les informations de jeton de décalage sont conservées. Ne fermez pas les canaux après avoir inséré des données, car les données à l’intérieur des canaux sont automatiquement vidées en fonction du temps configuré dans
MAX_CLIENT_LAG
.
Recommandations en matière de latence¶
Lorsque vous utilisez le Snowpipe Streaming, la latence fait référence à la vitesse à laquelle les données écrites sur un canal deviennent disponibles pour une requête dans Snowflake. Snowpipe Streaming vide automatiquement les données dans les canaux toutes les secondes, ce qui signifie que vous n’avez pas besoin de fermer explicitement un canal pour que les données soient vidées.
Configuration de la latence avec MAX_CLIENT_LAG Avec les versions 2.0.4 et ultérieures de Snowflake Ingest SDK, vous pouvez affiner la latence de l’extraction des données à l’aide de l’option MAX_CLIENT_LAG
:
Tables Snowflake standard (non-Iceberg) : la valeur par défaut de MAX_CLIENT_LAG est de 1 seconde. Vous pouvez modifier ce paramètre pour définir le temps de latence souhaité entre 1 seconde et un maximum de 10 minutes.
Tables Iceberg gérées par Snowflake : prises en charge par Snowflake Ingest SDK versions 3.0.0 et ultérieures, la valeur par défaut de
MAX_CLIENT_LAG
est de 30 secondes. Cette valeur par défaut permet de s’assurer que des fichiers Parquet optimisés sont créés, ce qui est bénéfique pour la performance des requêtes. Bien que vous puissiez fixer une valeur inférieure, cela n’est généralement pas recommandé, à moins que vous ne disposiez d’un débit exceptionnellement élevé.
Recommandations en matière de latence pour des performances optimales MAX_CLIENT_LAG
Un paramètre efficace peut avoir un impact significatif sur les performances des requêtes et sur le processus de migration interne (lorsque Snowflake compacte les petites partitions).
Dans les scénarios à faible débit, où vous n’envoyez qu’une petite quantité de données (par exemple, 1 ligne ou 1 KB) par seconde, des vidanges fréquentes peuvent entraîner la formation de nombreuses petites partitions. Cela peut augmenter le temps de compilation des requêtes, car Snowflake doit résoudre de nombreuses partitions minuscules, notamment lorsque les requêtes s’exécutent avant que le processus de migration ne puisse les compacter.
Par conséquent, vous devez paramétrer MAX_CLIENT_LAG à une valeur aussi élevée que le permettent les exigences de votre cible en matière de latence. La mise en mémoire tampon des lignes insérées pendant une durée plus longue permet à Snowpipe Streaming de créer des partitions de meilleure taille, ce qui améliore les performances des requêtes et réduit les frais généraux de migration. Par exemple, si vous avez une tâche qui s’exécute toutes les minutes pour fusionner ou transformer vos données en flux, une optimisation de MAX_CLIENT_LAG
pourrait se situer entre 50 et 55 secondes. Ainsi, les données sont évacuées en gros morceaux juste avant l’exécution de votre processus en aval.
Connecteur Kafka pour Snowpipe Streaming Il est important de noter que le connecteur Kafka pour Snowpipe Streaming possède son propre tampon interne. Lorsque le temps de vidange du tampon Kafka est atteint, les données sont alors envoyées à Snowflake avec le temps de latence standard d’une seconde par le biais du flux Snowpipe. Pour plus d’informations, voir paramètre buffer.flush.time