Question

Arrière-plan:

J'ai une base de données PostgreSQL (v8.3) fortement optimisée pour OLTP.

J'ai besoin d'en extraire des données sur une base semi-temps réel (quelqu'un se demandera forcément ce que signifie semi-temps réel et la réponse est aussi souvent que possible, mais je serai pragmatique, en tant que référence, disons que nous j'espère toutes les 15 minutes) et l'introduire dans un entrepôt de données.

Combien de données ?Aux heures de pointe, nous parlons d'environ 80 à 100 000 lignes par minute du côté OLTP, tandis qu'en dehors des heures de pointe, cela chutera considérablement à 15 à 20 000.Les lignes les plus fréquemment mises à jour font environ 64 octets chacune, mais il existe plusieurs tableaux, etc., de sorte que les données sont assez diverses et peuvent aller jusqu'à 4 000 octets par ligne.L'OLTP est actif 24h/24, 5j/7.

Meilleure solution?

D'après ce que je peux reconstituer, la solution la plus pratique est la suivante :

  • Créez un TRIGGER pour écrire toutes les activités DML dans un fichier journal CSV rotatif
  • Effectuez toutes les transformations nécessaires
  • Utilisez l'outil natif de pompage de données DW pour pomper efficacement le CSV transformé dans le DW

Pourquoi cette approche ?

  • LES DÉCLENCHEURS permettent de cibler des tables sélectives plutôt que d'être à l'échelle du système + la sortie est configurable (c'est-à-diredans un CSV) et sont relativement faciles à écrire et à déployer.SLONY utilise une approche similaire et les frais généraux sont acceptables
  • CSV facile et rapide à transformer
  • Facile à pomper du CSV dans le DW

Alternatives envisagées....

  • Utilisation de la journalisation native (http://www.postgresql.org/docs/8.3/static/runtime-config-logging.html).Le problème est que cela semblait très verbeux par rapport à ce dont j'avais besoin et était un peu plus difficile à analyser et à transformer.Cependant, cela pourrait être plus rapide car je suppose qu'il y a moins de surcharge par rapport à un TRIGGER.Certes, cela faciliterait l'administration car cela s'applique à l'ensemble du système, mais encore une fois, je n'ai pas besoin de certaines tables (certaines sont utilisées pour le stockage persistant des messages JMS que je ne souhaite pas enregistrer).
  • Interroger les données directement via un outil ETL tel que Talend et les pomper dans le DW...le problème est que le schéma OLTP aurait besoin d'être modifié pour prendre en charge cela et cela a de nombreux effets secondaires négatifs
  • Utilisation d'un SLONY modifié/piraté - SLONY fait un bon travail de journalisation et de migration des modifications vers un esclave, le cadre conceptuel est donc là, mais la solution proposée semble simplement plus simple et plus propre.
  • Utiliser le WAL

Quelqu'un a-t-il déjà fait cela ?Vous souhaitez partager vos réflexions ?

Était-ce utile?

La solution

En supposant que vos tables d'intérêt ont (ou peuvent être complétées par) une clé séquentielle unique, indexée, vous obtiendrez alors une bien meilleure valeur en émettant simplement SELECT ... FROM table ... WHERE key > :last_max_key avec sortie dans un fichier, où last_max_key est la dernière valeur clé de la dernière extraction (0 si première extraction.) une approche progressive et découplée évite présentation déclencher la latence dans le chemin de données d'insertion (qu'il s'agisse de déclencheurs personnalisés ou de Slony modifié), et en fonction de votre configuration, il pourrait mieux évoluer avec le nombre de processeurs, etc.(Cependant, si vous devez également piste UPDATEs, et la clé séquentielle a été ajoutée par vous, alors votre UPDATE les déclarations devraient SET la colonne clé pour NULL il obtient donc une nouvelle valeur et est sélectionné lors de la prochaine extraction.Tu ferais ne pas pouvoir suivre DELETEs sans déclencheur.) Est-ce ce que vous aviez en tête lorsque vous avez mentionné Talend ?

Je voudrais n'utilisez pas la fonction de journalisation à moins que vous ne puissiez pas mettre en œuvre la solution ci-dessus;la journalisation implique très probablement verrouillage au-dessus pour garantir que les lignes de journal sont écrites de manière séquentielle et ne se chevauchent/s'écrasent pas lorsque plusieurs backends écrivent dans le journal (vérifiez la source Postgres.) La surcharge de verrouillage n'est peut-être pas catastrophique, mais vous pouvez vous en passer si vous pouvez utiliser l'incrémental SELECT alternative.De plus, la journalisation des déclarations serait noyée tout message d'AVERTISSEMENT ou d'ERREUR utile, ainsi que le l'analyse elle-même ne sera pas instantanée.

À moins que vous ne souhaitiez analyser les WAL (y compris le suivi de l'état des transactions et que vous soyez prêt à réécrire le code à chaque mise à niveau de Postgres), je n'utiliserais pas nécessairement les WAL non plus - c'est-à-dire, à moins que vous disposer du matériel supplémentaire, auquel cas vous pourriez expédier les WAL vers une autre machine pour l'extraction (sur la deuxième machine, vous pouvez utiliser les déclencheurs sans vergogne -- ou même la journalisation des instructions -- puisque quoi qu'il arrive, cela n'affecte pas INSERT/UPDATE/DELETE performances sur la machine principale.) Notez qu'en termes de performances (sur la machine principale), à ​​moins que vous ne puissiez écrire les journaux sur un SAN, vous obtiendrez une performance comparable (en termes de destruction du cache du système de fichiers, principalement) en expédiant les WAL. vers une autre machine à partir de l'exécution de l'incrémental SELECT.

Autres conseils

si vous pouvez penser à une « table de contrôle » qui ne contient que les ID et le « contrôle », vous pouvez non seulement faire une sélection rapide des nouveaux dossiers mais aussi les enregistrements modifiés et supprimés.

la somme de contrôle pourrait être une fonction de contrôle crc32 vous le souhaitez.

La nouvelle clause ON CONFLIT dans PostgreSQL a changé la façon dont je fais beaucoup de mises à jour. Je tire les nouvelles données (sur la base d'un row_update_timestamp) dans une table temporaire puis dans une instruction SQL INSERT dans la table cible avec MISE À JOUR DE CONFLIT. Si votre table cible est partitionné, vous devez sauter puis à travers quelques cerceaux (à savoir frapper directement sur la table de partition). L'ETL peut arriver que vous chargez le tableau Temp (le plus probable) ou dans le SQL ON CONFLIT (si trivial). Par rapport à d'autres systèmes « upsert » (mise à jour, insérer si aucune ligne, etc.) cela montre une grande amélioration de la vitesse. Dans notre environnement particulier DW nous ne avons pas besoin / veulent accueillir DELETE. Consultez la documentation de CONFLICT - il donne la MERGE d'Oracle une course pour son argent

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top