le
718 mots - 4 minutes de lecture
Redshift – Des idées d’optimisation
Redshift est une base de données analytique distribuée, hébergée et gérée par Amazon, basée sur PostgreSQL 8.0.2.
Son stockage orienté colonnes lui permet une forte compression des données et une utilisation optimale des I/O, c’est idéal pour la lecture de masse et l’agrégation.
Mon expérience se base sur un cluster de 8 noeuds disposant chacun de 2 To d’espace disque et 32 Go de RAM, pouvant être amené à évoluer en fonction des besoins, et c’est là qu’opère la magie du service géré par Amazon.
Pour ajouter un ou plusieurs noeud(s) avec une configuration équivalente aux noeud en place, cela se fait en quelques clics et en live. Le transfert de données à ce nouveau noeud s’opère automatiquement. Pour configurer un nouveau type de noeud (pour modifier le moteur de stockage par exemple), on est contraint de passer le cluster en maintenance pour quelques heures, le temps de la copie des données d’un cluster à un autre.
Je vous partage ici, les premières optimisations que l’on peut apporter à un cluster Redshift, en terme de modélisation.
Le mode de stockage de Redshift, rend obsolètes certaines règles que l’on peut se fixer avec un SGBD relationnel classique.
Par exemple, ajouter foison de colonnes à faible taux de remplissage dans une table était peu recommandé, pour autant, cela peut cependant avoir un fort intérêt analytique.
Avec Redshift, il est possible, sans pénaliser le moteur de stockage ou les performances, créer et alimenter des tables à forte volumétrie et contenant de nombreuses colonnes.
Le vide importe peu, chaque colonne peut être considérée comme ‘indexée’ et n’est chargée que si elle est appelée (à l’inverse des SGBD relationnels qui pour chaque enregistrement retourné considèrera toute la ligne).
Malgré tout, il peut y avoir des optimisations à apporter, le fait que la donnée soit distribuée sur un cluster a forcément des impacts si la distribution est trop aléatoire.
Deux options clé sont donc à aborder : sort key et distribution style.
Les sort keys
Les sort keys permettent d’ordonner les données d’une table au sein du cluster afin d’améliorer les performances des requêtes de types range, agrégations, tris et les window functions
effectuées sur cette clé.
Cela évite de parcourir toute une table inutilement.
Elles sont spécifiées à la création de la table, et si elles sont multiples, deux types peuvent être utilisés :
- Compounded sort keys : ce type induit que l’ordre des champs est très important. Il est donc utile si les requêtes sont filtrées par toutes ces clés et dans l’ordre spécifié. Par ailleurs, les compounded sort keys améliorent la compression des données. En revanche, elles obligent en cas de chargement de volume important, à s’astreindre à des VACUUM et des ANALYZE fréquents, dans le cas contraire, les performances des requêtes peuvent être lourdement impactées.
- Interleaved sort keys : à l’inverse, chaque élément composant la sort key a un poids équivalent. L’usage de ces sort keys nécessitent de passer régulièrement des VACUUM REINDEX sur les tables concernées.
CREATE TABLE schema1.s1_website_audience
( /**
...
**/ )
INTERLEAVED SORTKEY (page_id, day_id);
Le distribution style
Le distribution style est à définir à la création sur chaque table pour définir la répartition des lignes sur le cluster.
Trois modes sont disponibles :
- Even : c’est le style de distribution par défaut, les lignes sont distribuées en round robin. Il est adapté lorsque la table n’est pas spécialement utilisée pour faire des jointures, qu’une clé évidente ne se détache pas ou qu’il n’y a pas d’intérêt à utiliser le style ALL.
- All : chaque noeud dispose de toutes les données d’une table. La colocation peut apporter des performances supplémentaires aux requêtes, mais cela se fait au détriment des temps de chargement et de l’espace de stockage. Cela peut donc être très utile et peu coûteux, lorsqu’il s’agit de tables de dimensions.
CREATE TABLE schema1.s1_jobs ( /** ... **/ ) DISTSTYLE ALL
- Key : on définit une clé fonctionnelle sur laquelle les jointures sont le plus souvent réalisées. Redshift répartira les données en fonction d’un modulo sur cette clé.
CREATE TABLE schema1.s1_users ( user_id integer NOT NULL, /** ... **/ ) DISTSTYLE KEY distkey(ad_id)
Même si l’utilisation de ces deux paramètres peut s’avérer contraignante en terme de maintenance, elle apporte un véritable gain en terme de performance et rendent les plans de requêtes beaucoup plus cohérents.