WikiMiNET

La documentation technique et administrative

Outils pour utilisateurs

Outils du site


wiki:divers:ha:cdn

Content Delivery Networks

Qu'est ce qu'un CDN ?

CDN signifie Content Delivery Network. C'est un réseau sur lequel on va pouvoir stocker des images, des vidéos ( en fait des contenus qui ne conviennent pas aux bases de données ou au NoSQL ).

La problématique d'utilisation d'un CDN ici est simple : on a plein de serveurs webs qui travaillent en parallèle, et on ne peut stocker d'informations sur ceux ci comme on pourrait le faire avec un serveur web classique. En effet, les autres serveurs webs ne pourraient y avoir accès. On doit donc stocker nos informations ailleurs. Pour ce qui est nombres et textes, des bases de données et du NoSQL seront utilisés.

Pour ce qui est des images / vidéos / autre uploadé par l'utilisateur il faut utiliser un espace de stockage centralisé. Utiliser directement un système d'espace de stockage centralisé ne suffit pas ( opérations concurrentes possibles, ce qui mènerait tel que je le vois à une coûteuse gestion gestion de verrou sur les serveurs webs … ). C'est là que les CDNs font leur entrée en jeu. En gros on met des données dessus depuis les serveurs webs, et on les récupère sur le CDN quand on en a besoin.

On attend par ailleurs d'un CDN que les contenus soit répliqués dans plusieurs DataCenter ( pour des raisons de coûts / performances ).

La solution classique et que beaucoup choisissent c'est des CDNs payants ( c'est après tout moins cher que de déployer et entretenir le sien … ) . Je peux citer ( merci wikipédia ) Amazon cloudfront, CDNetworks, CloudFlare … Vous l'aurez compris ( et vous devez commencer à me connaître … ), nous essayerons ici de trouver des pistes pour utiliser notre propre CDN ( et pas celui des voisins … ).

Utiliser CEPH

CEPH est un système de fichier orienté Object Storage. Il est donc particulièrement adapté pour être utilisé en temps que CDN.

Vous trouverez sur cette page des détails sur CEPH.

CEPH introduit une Object gateway, qui nous fournis une interface RESTFULL. On pourra donc, très simplement, depuis nos serveurs webs, via le protocole http ajouter / consulter / modifier / supprimer le contenu.

Instalation de CEPH Object Gateway

Nous allons installer CEPH Object Gateway sur un de nos moniteurs ( vous pouvez mettre sans problème deux CEPH Object gateway derrière un HAproxy… ).

Nous allons utiliser apache2 ainsi que FastCGI. Pour les installer, rien de plus simple :

  apt-get install apache2 libapache2-mod-fastcgi

On active ensuite les modules rewrite et fast-cgi :

  a2enmod rewrite
  a2enmod fastcgi

On crée les virtualHost rgw.conf : /etc/apache2

FastCgiExternalServer /var/www/s3gw.fcgi -socket /tmp/radosgw.sock
 
<VirtualHost *:80>
        ServerName benwa-ceph-master-1
        ServerAdmin benwa@minet.net
        DocumentRoot /var/www
 
        <IfModule mod_fastcgi.c>
                <Directory /var/www>
                        Options +ExecCGI
                        AllowOverride All
                        SetHandler fastcgi-script
                        Order allow,deny
                        Allow from all
                        AuthBasicAuthoritative Off
                </Directory>
        </IfModule>
 
        AllowEncodedSlashes On
        ErrorLog /var/log/apache2/error.log
        CustomLog /var/log/apache2/access.log combined
        ServerSignature Off
 
</VirtualHost>

Puis on l'active :

  a2ensite rgw.conf

Et on désactive le virtual Host par défaut :

  a2dissite default

Bon maintenant créons le fichier /var/www/s3gw.fcgi :

#!/bin/sh
exec /usr/bin/radosgw -c /etc/ceph/ceph.conf -n client.radosgw.gateway

Maintenant il ne reste plus qu'à installer rados ( qui gère les objets de la CEPH Object Gateway ) :

  apt-get install radosgw

La configuration se fait ensuite dans /etc/ceph/conf :

[global]
        fsid = 1af68adc-4fff-46a5-ba0b-d0f7e9f12cca
        mon_initial_members = benwa-ceph-master-1, benwa-ceph-master-2
        mon_host = 192.168.103.222,192.168.103.223
        auth_cluster_required = cephx
        auth_service_required = cephx
        auth_client_required = cephx
        filestore_xattr_use_omap = true



[client.radosgw.gateway]
        host = benwa-ceph-master-1
        keyring = /etc/ceph/keyring.radosgw.gateway
        rgw socket path = /tmp/radosgw.sock
        log file = /var/log/ceph/radosgw.log
        rgw enable ops log = false

Comme nous utilisons l'authentification via cephx il nous faut générer nos clés :

    ceph-authtool --create-keyring /etc/ceph/keyring.radosgw.gateway
    chmod +r /etc/ceph/keyring.radosgw.gateway
    ceph-authtool /etc/ceph/keyring.radosgw.gateway -n client.radosgw.gateway --gen-key
    ceph-authtool -n client.radosgw.gateway --cap osd 'allow rwx' --cap mon 'allow rw' /etc/ceph/keyring.radosgw.gateway
    ceph -k /etc/ceph/ceph.client.admin.keyring auth add client.radosgw.gateway -i /etc/ceph/keyring.radosgw.gateway

Chez moi ça marche ;-)

Limites

Cette fonctionnalité de CEPH est très sympa et rempli simplement le contrat fournit initialement. Néanmoins je note un certain nombre de bémols :

  • L'utilisation de CEPH Object Gateway n'est pas transparente à l'application web que nous déployons. Il faudra en tenir compte lors de la programmation.
  • Moins grave, des clients pour l'API swift ne sont disponibles que pour les langages suivants : python ruby et Java. L'API compatible Amazon S3 élargie un peu la gamme de langages possibles ( mais y a pas de node.js ).
  • Et pour finir, la répartition des données se fait via les CRUSH tables. Comme il s'agit d'une politique globale, cela veut dire qu'on ne peut pas avoir une politique orientée cas particulier.

Je m'explique : imaginez youtube. Ils ont envie d'avoir plusieurs copies de la vidéo de Cyprien sur tous leurs data-centers afin de pouvoir tenir la charge, minimiser leurs transits de donnée, et fournir une meilleure qualité de service à leurs clients. En revanche ils ne voudront garder que deux exemplaires de ma vidéo sur l'usage de l'emmental rapé en Ukraine car tout le monde s'en fout, ce n'est pas demandé, et ça leur coute de l'espace disque.

Ce genre de politique peut être obtenue via CEPH en jouant sur les pools sur lequel on écrira l'objet. Décision prise par les serveurs webs ( pas cool ). Et pire, le résultat obtenu sera “statique” : si ma vidéo fait le buzz parce que j'ai mis un chapeau péruvien ridicule et que je zozotait, il sera assez difficile de la changer de pool, et le tout de manière transparente.

  • Dernier point, CEPH Object Gateway s'interface avec les serveurs webs. Si je regarde une vidéo, elle passera par les serveurs webs ( et surchargera donc mes liens en interne de manière somme toute assez inutile… Je pourrais vouloir que mon client la récupère directement ( sans passer par un serveur web… ).

Bien sur tout ceci est à nuancer, et CEPH Object Gateway est vraiment un outil super, mais il ne conviendra à mon sens pas à certaines situations particulières et exigeantes.

Liens

Un CDN personnalisé ?

Bon, supposons que j'apporte un attention très poussée à la gestion de la réplication des données sur mon CDN. Je veux aussi pas surcharger mes liens internes. Comment faire ?

Bah j'ai cherché longtemps, et je n'ai pas trouvé. On va dire que proposer une solution libre et simple serait un de mes projets.

Architecture de la solution

L'architecture s’appuierai sur quatre éléments :

  • Des serveurs NGinx en front pour permettre aux clients de consulter les éléments du CDN.
  • Un système de fichier distribué, sur lequel sont stockés les objets du CDN. Le mot “distribué” est important : il permet aux serveurs NGinx d'accéder tous au même contenus.
  • Un ensemble de contrôleurs. Son but est de :
    1. Gérer l'ajout de fichier dans le CDN ( requête PUT depuis les serveurs webs )
    2. Gérer la suppression ( requête DELETE depuis un des serveurs webs )
    3. Gérer la réplication de l'objet vers les autres nœuds du CDN.
  • Du NoSQL clé / valeur, pour stocker les infos sur un objet, ce dont ont besoin les contrôleurs. Je me serais orienté vers REDIS.

Un petit schéma vous permettra de mieux comprendre de quoi il en retourne…

Pour plus de souplesse, le système s'appuiera sur un ensemble de scores :

  1. Initial, envoyé lors du PUT ( permettra a la vidéo de Cyprien d'être directement dupliquée sur de nombreux data-centers…)
  2. En fonction du nombres de vues… L'objet serais copié en cas de nécessité vers les autres data-centers.

Clairement, compte tenu de ces choix il nous faut :

  • Modifier NGINX afin que :
    1. Il redirige la requête client vers un datacenter possédant l'objet si lui ne le possède pas (lecture de la fiche REDIS sur cet objet)
    2. Il notifie ses vues et avertisse un de ces contrôleurs en cas de besoin de réplication. ( pour le dernier point on pourrait aussi opter pour une tache de fond sur les contrôleurs )
  • Complètement écrire le code du contrôleur. Je le verrai bien en node.js…

Conclusion

Le projet est dans les cartons et attend un peu de temps libre pour avancer.

Note : j'entrevois une difficultée : c'est l'authentification lors de l'accès au contenu… Comme on ne passe plus par les serveurs webs, ça complique les choses… A moins de renoncer dans ce cas à servir directement le client…

Benoit Tellier 2014/02/18 21:26

wiki/divers/ha/cdn.txt · Dernière modification: 2020/06/27 18:16 (modification externe)