Article
· Sept 11 4m de lecture

Utilisation des bons types de stream dans un environnement mirroré

Bonjour,

je vous soumets cet article sous forme d'ADR (Architecture decision record) que nous avons rédigé dans nos équipes.
L'objectif était d'être pertinent dans le choix de nos types de stream dans un contexte mirroré.
A noter que des éléments peuvent être utiles même dans un environnement sans miroir.

Stockage des "Character Stream" dans un environnement mirroré

  • Auteur : Matthieu LAURENT et Vincent DHEILLY
  • Date : 2024-09-11
  • Version : IRIS 2024.1

Contexte

Les streams sont très utilisées au sein d'InterSystems notamment dans 2 contextes très différents :

  • Stocker des fichiers contenant des caractères (PDF par exemple)
  • Stocker des chaines de caractères très volumineuses

Nos analyses ont été menées avec des CharacterStream. Cependant, les éléments de conclusion et de bonnes pratiques sont transposables pour les BinaryStream.

Il existe 3 classes permettant de manipuler les streams de caractère.

  • %Stream.GlobalCharacter : Avec cette classe, les streams sont stockées dans une globale dédiée.
  • %Stream.FileCharacter : Avec cette classe, les streams sont stockées dans un fichier externe. Seul un pointeur vers le fichier est stocké dans une globale.
  • %Stream.TmpCharacter : Permet de stocker une stream temporairement mais ne peut être sauvegardée.

Solutions étudiées

Le but étant d'étudier le stockage pérenne, la classe TmpCharacter est totalement exclue des solutions viables et donc étudiées.

Utilisation des GlobalCharacter

Les GlobalCharacter sont stockés dans une globale dédiée. Elles sont donc par défaut stockées dans la base de données "DATA" du namespace dans laquelle elle se trouve.

Avantages Inconvénients
Les streams sont stockées dans la base et donc mirrorées La taille conséquente des streams peuvent faire grossir la base
Aucune date de création des fichiers. Difficile d'isoler les "vieux" fichiers

Utilisation des FileCharacter

Les FileCharacter sont stockés dans des fichiers externes. Elles sont donc par défaut stockées dans un sous dossier stream de la base de données "DATA" du namespace dans laquelle elle se trouve. Seul un pointeur vers le fichier est stocké en base de données.

Avantages Inconvénients
Les fichiers sont stockés sur le serveur directement et ne font pas grossir la base Les fichiers ne sont pas mirrorés. En cas de document métier important, il faut une solution tierce pour prévoir une copie temps réel de ces fichiers
Les fichiers étant datés, une purge est facilement envisageable

Décision

L'utilisation des FileCharacter stream n'est pas une solution viable de façon autonome dans un environnement mirroré. Il est donc impossible d'utiliser ce type dans le cas d'un document de gestion persisté.

Les streams stockés dans les messages n'ont par contre aucune utilité d'être stockées de façon pérenne.

La décision est d'utiliser dans tous les cas la classe GlobalCharacter lorsque l'attribut se trouve dans une classe persistante. Elle est aussi d'utiliser dans tous les cas un FileCharacter lorsque l'attribut fait partie d'une classe sérialisable.

A noter que dans les deux cas, il est impératif de définir une localisation de stockage.

Exemple avec un GlobalCharacter pour stocker un fichier Justificatif
Toujours préfixer avec le mot clef STREAM pour identifier les globales

Property Justificatif As %Stream.GlobalCharacter(LOCATION = "^STREAMJustificatif");

Exemple avec un FileCharacter pour stocker un fichier Justificatif.
Mettre dans un dossier indiquant que c'est des streams et que c'est temporaire

Property Justificatif As %Stream.FileCharacter(LOCATION = "/stream/tmp/justificatif");

Dans le cas des FileCharacter, prévoir dès l'implémentation une stratégie de purge des fichiers sur base de date.

Conséquences

En choisissant cette stratégie, voici les conséquences :

  1. Mirroring automatique : Toutes les streams persistantes sont automatiquement mirrorées

  2. Stockage maîtrisé : Les streams non pérennes peuvent être facilement purgées. Attention, ce n'est pas automatique, purge manuelle via le système de fichier nécessaire. Il est également possible de créer des tâches de purge directement via IRIS.

  3. Base de données dédiées aux fichiers : Les streams étant stockés dans des globales dédiées, il est possible de prévoir une base de données locales dédiées aux streams par namespace et de gérer avec une transposition de package.

Références

Discussion (1)2
Connectez-vous ou inscrivez-vous pour continuer

Merci pour cette article @Matthieu LAURENT 

L'utilisation du parameter LOCATION est une très bonne pratique pour éviter un piège.

Par défaut si ce n'est pas précisé le système enregistre dans la global qui  correspond au nom de la classe en se terminant par un S (ex :  ^User.TestStreamS pour la classe User.TestStream).  Ce n'est pas forcément un problème, mais à l'usage: si quelqu'un fait 

Set obj.Justificatif = ##class(%Stream.GlobalCharacter).%New() 

Le stream se retrouve par défaut dans ^CacheStream ce qui peut devenir un problème si on répète cela avec des streams de différentes classes.

L'utilisation du parameter LOCATION évite cela même dans ce cas de figure.