Du PHP sans état grâce au stockage objet

le jeudi 24 septembre 2020

Bearstech | Dernière mise à jour : lundi 21 septembre 2020

Avec la croissance du Cloud Computing, les techniques de stockage de données évoluent. L'une des méthodes les plus utilisées sur le Cloud actuellement est le stockage objet, une solution qui présente plusieurs avantages.

Notre prochain webinar

Dans ton cloud

Pour accéder aux promesses de l'hébergement dans le nuage, il faut quelques prérequis, dont le premier est d'avoir une application sans état. Sans état, cela veut simplement dire que votre application n'écrira rien directement sur un disque dur.

Globalement, la persistance est déjà assurée par une base de données (comme Mariadb) et les sessions sont centralisées (dans Memcache par exemple), tout comme les journaux. Vous ne faites plus de mises à jour sur place, depuis une interface d'admin, mais vous livrez un conteneur avec la nouvelle version. Il ne reste que les téléversements de fichiers finalement.

Sans état, enfin, avec des états assurés par des services (qui eux garantiront la cohérence des modifications concurrentes, une éventuelle réplication ou conservation de l'historique des modifications), votre application va pouvoir être :

  • dupliquée (pour suivre une montée en charge) ;
  • déplacée (pour redimensionner son matériel) ;
  • réinstanciée sur une autre machine (suite à un incident matériel).

Hangar 51

Stockage distant

Il existe 3 approches pour avoir du stockage distant.

Stockage en mode bloc

Le protocole, comme du iSCSI ou NBD, expose un volume distant simulant un disque dur que l'on formatera à sa guise. Le stockage pourra être redondé (avec du RAID en réseau) ou snapshoté, mais seuls quelques systèmes de fichiers exotiques permettront un accès concurrent depuis plusieurs machines.

Stockage en mode fichier

Le protocole, comme NFS, SMB ou CephFS, expose des fichiers et permet un accès concurrent depuis plusieurs machines. Le partage en mode fichier est transparent pour l'application, mais les énumérations ou les accès concurrents vont poser des problèmes de performance. SMB, le protocole de Windows n'est pas adapté au Cloud, donc on oublie. NFS ne propose rien pour la réplication sur plusieurs machines, mais il existe d'autres protocoles plus confidentiels, qui permettent la distribution, comme Gluster ou CephFS.

Stockage en mode objet

Une des premières recettes secrètes livrées par Google fut leur réponse pour le stockage distribué. Pour pouvoir répliquer les données sans risque de corruption, le mode objet utilise des documents immuables. Quand on veut modifier un document, bah, on crée une nouvelle version, et quand cette version a atteint son quorum de réplication, on peut effacer la version antérieure. Le white paper de Google a donné HDFS en open source, mais le produit reste une niche pour les calculs scientifiques sur des volumes déraisonnables de données.

Amazon, de manière assez rustique, a adapté la notion de document immuable et versionné à HTTP pour créer S3, comme Simple Storage Service en 2006.

HTTP est tout à fait adapté à cette notion de document immuable et permet de profiter simplement de tout son écosystème, comme les URLs, les entêtes, les redirections, les proxys et surtout son usage depuis n'importe quel client HTTP, comme le sont les navigateurs web.

Le 3 de S3 est aussi le nombre d'instances d'un document stocké, ce qui permet d'être confiant sur sa durabilité. Toutes les offres d'hébergement Cloud proposent un service de stockage objet, avec une compatibilité S3.

L'implémentation libre de référence est Minio autant adapté au poste du développeur qu'à un hébergement distribué. Minio met à disposition une élégante interface web et un outil en ligne de commande, mc, fort pratique.

Abstraire le stockage dans son code

S3 est un standard de fait, mais pas une norme. Même s’il existe de multiples implémentations de la partie serveur, il n'est pas aussi trivial à déployer qu'un bête disque dur. Il est sage d'utiliser une bibliothèque adaptée à son framework préféré, et pour PHP, le vainqueur semble être Flysystem, qui permet d'abstraire la notion de stockage en fournissant un adaptateur pour S3. Flysytem documente son utilisation dans les frameworks majeurs PHP dont un bundle Symfony. L'application pourra alors être déployée sur un très classique serveur dédié et son disque dur, ou sur un nuage et son stockage objet.

Démonstration Flysystem

La démo utilise docker-compose pour mettre en place un Nginx devant un php-fpm et un minio.

Composer permet d'aller chercher tout ce qu'il faut : le driver officiel S3, l'abstraction de Flysystem et l'adaptateur adéquat.

<?php
require __DIR__ . '/vendor/autoload.php';

use Aws\S3\S3Client;
use League\Flysystem\AwsS3v3\AwsS3Adapter;
use League\Flysystem\Filesystem;

Comme le préconisent les 12 facteurs, la configuration vient des variables d'environnement. $filesystem est l'objet de base de Flysystem.

$s3Cfg = [
    'credentials' => [
        'key'    => $_SERVER['ACCESS_KEY'],
        'secret' => $_SERVER['SECRET_KEY'],
    ],
    'region' => $_SERVER['REGION'],
    'version' => 'latest',
];
if ($_SERVER['S3_ENDPOINT']) {
    $s3Cfg['endpoint'] = $_SERVER['S3_ENDPOINT'];
    $s3Cfg['use_path_style_endpoint'] = true;
}
$client = new S3Client($s3Cfg);
$adapter = new AwsS3Adapter($client, $_SERVER['BUCKET'], 'upload'); // client, bucket, préfixe de chemin
$filesystem = new Filesystem($adapter);

Le très classique formulaire d'upload…

    <form action="/" method="post" enctype="multipart/form-data">
        <input type="file" name="fileToUpload" id="fileToUpload">
        <input type="submit" value="Upload Image" name="submit">
    </form>

… qui est écrit sur le service de stockage avec la méthode writeStream.

$uploadName = "fileToUpload";

if ($_FILES[$uploadName] != null) {
    $stream = fopen($_FILES[$uploadName]['tmp_name'], 'r+');
    $up = $filesystem->writeStream(
        $_FILES[$uploadName]['name'],
        $stream
    );
    if(! $up) {
        echo "oups";
    };
    if (is_resource($stream)) {
        fclose($stream);
    }
}

L'API permet aussi de lister le contenu stocké. Le Nginx utilisé devant php-fpm redirige les urls vers les documents téléversés.

    <ul>
    <?php
        $contents = $filesystem->listContents('', false); // chemin, récursivité
        foreach ($contents as $object) { ?>
            <li><a href="/upload/<?=$object['path']?>"><?=$object['basename']?></a></li>
        <?php } ?>
    </ul>

L'ensemble de la démo est disponible sur Github.

Aller plus loin

moaaar storage pliz

Bande passante

Il est possible d'exposer S3 directement aux utilisateurs, et même leur confier des droits temporaires leur permettant de téléverser ou télécharger une URL précise si l'on souhaite externaliser les soucis de bande passante. L'utilisation du protocole HTTP permet de router le trafic S3 (ce qui est fait dans la démo) et même de le cacher, ce qui est proposé par les différents CDN.

Pour des volumétries raisonnables (vous n'hébergez ni images disque Linux, ni films en haute résolution), il est sage de router son trafic S3 derrière le même nom de domaine (et certificat) que le reste de son application, sinon, allez vérifier comment la bande passante est facturée.

Droits

La gestion des droits de S3 peut être très fine, mais aussi très complexe. Il arrive régulièrement que des données confidentielles soient stockées sur S3 sans authentification parce que c'est pénible à faire quand on a plusieurs comptes. Ce n'est jamais une bonne idée d'avoir des données accessibles sur Internet, confidentielles, et sans mot de passe.

Dans la démonstration, le partage est accessible en lecture seule pour les clients non authentifiés.

Sauvegarde

Le stockage S3 se prête aussi au stockage de données privées et il est possible d'archiver au fil de l'eau des journaux (via fluentd par exemple) ou même des bases de données.

Redimensionnement

Une fois résolue la contrainte de la persistance, vous pouvez profiter des possibilités de redimensionnement de votre hébergement et gérer sereinement les pics de montées en charge, en gardant toujours un œil sur vos tableaux de bord pour surveiller performance et coût d'exploitation.

Service Audit de Performance web php

Bearstech vous propose ses services Audit de Performance web php

Découvrir ce service

Partager cet article

Flux RSS

flux rss

Partager cet article :