Scénario

Contoso dispose d'une application mobile et d'un site Web qui renvoient des informations d'utilisation. Une sonde (en JavaScript depuis les pages HTML, en Objective-C sur iOS, en Java depuis Android, en C# depuis Windows Phone, en C# ou en JavaScript depuis Windows 8+) envoie via HTTP POST ces informations d'usage en JSON (JavaScript Object Notation) à l'adresse http(s)://webtracker.contoso.com/t/.

Le but de cet article est de montrer comment on peut :

  • mettre en œuvre la réception de ces informations de sonde de façon à ce que cela puisse monter fortement en charge sans changement d'architecture ;
  • analyser les données ;
  • restituer ces données.
Image non disponible

Voici quelques chiffres de volumétrie visés :

  • plusieurs milliers de requêtes par seconde arrivent au Track Receiver ;
  • la partie Storage doit pouvoir stocker plusieurs To de données ;
  • l'analyse d'un jour de données doit pouvoir se faire en quelques heures.

N.B. L'article ne parle pas de la façon dont les différents clients collectent et postent leurs données en HTTP.

Conception de la solution

Voici les technologies choisies pour cette implémentation et quelques justifications de ces choix.

L'ensemble de la plateforme est hébergé sur Windows Azure. Héberger cela sur un cloud public permet à la fois d'être présent sur Internet (par définition), et de monter en charge facilement, en ajustant les ressources nécessaires à la charge constatée.

Le « Track Receiver » est un Web Role, car c'est la solution la plus souple pour ajouter des dizaines voire des centaines de machines virtuelles en fonction de la charge (rappel : un Web Role est une ferme Web comprenant des instances qui sont des machines virtuelles).

Le stockage (« Storage ») est le Windows Azure Storage Blob, car c'est la solution la plus économique pour stocker de larges volumes de données.

Le Web Role n'envoie pas directement les données dans des blobs, car il y a une phase d'accumulation des informations unitaires. C'est un Worker Role qui écrit les blobs. La liaison entre le Web Role et le Worker Role se fait via les queues du Windows Azure Storage qui a spécialement été conçu pour ce type de scénario et qui permet une bonne montée en charge.

L'analyse des données se fait avec le service Windows Azure HDInsight qui permet d'analyser des données brutes par exemple en SQL (via HIVE), en créant pour le temps du calcul des nœuds Hadoop, est capable de travailler directement sur des données dans le service de stockage de blobs de Windows Azure. Le tout peut être automatisé en PowerShell ou en C#. Ici on l'automatise en PowerShell.

La restitution des données pour visualisation se fait dans Excel, car l'outil est bien connu des utilisateurs, peut être partagé en Web via l'offre Power BI d'Office 365, et si les données à traiter deviennent plus importantes que ce que Power Pivot peut traiter, il est possible de passer, sans changer le schéma, à SQL Server Analysis Services (SSAS) qui dispose d'un modèle tabulaire compatible avec Power Pivot. La récupération des données se fait via Power Query, la visualisation dans Power View.

Le schéma de principe est le suivant :

Image non disponible

Les valeurs cibles en termes de montée en charge d'un compte de stockage Windows Azure sont décrites à http://msdn.microsoft.com/en-us/library/windowsazure/dn249410.aspx. Pour un compte de stockage, la cible est jusqu'à 20 000 requêtes par seconde. Pour une queue, c'est 2000 requêtes par seconde. Dans cet exemple, on se restreint à un compte de stockage, mais on répartit le traitement sur plusieurs queues.

Mise en œuvre

Préparation de l'environnement de développement

Pour ouvrir la solution, il est possible d'utiliser Visual Studio 2013 et le Windows Azure SDK pour .NET 2.2. Quelques informations complémentaires sont disponibles à http://www.windowsazure.com/en-us/develop/visual-studio-2013/?fb=fr-fr.

N.B. Différentes versions de Visual Studio 2013 sont téléchargeables à http://www.microsoft.com/visualstudio/fra/downloads. Le code a été développé sur Visual Studio 2013 Ultimate, mais il doit pouvoir s'ouvrir également avec Visual Studio 2013 Express pour le Web.

Une version antérieure de cette solution a été publiée à http://code.msdn.microsoft.com/Big-Data-Tracker-From-a-91b6e806. On l'adapte entre autres pour

  • la passer en Visual Studio 2013 ;
  • ajouter la compression GZip qui fait partie du .NET Framework 4.5 et qui est nativement comprise par Hadoop et donc HDInsight ;
  • y ajouter le traitement par HDInsight 2.1 qui est disponible en version GA (General Availability) depuis le 28 octobre 2013 ;
  • y ajouter la récupération dans Excel 2013, avec les versions GA de Power Query, PowerPivot (PowerPivot est intégré à Excel 2013) et Power View.

Le code source est disponible avec cet article.

Image non disponible
  • Doc contient ce document et le résultat de la visualisation.
  • Scripts contient les scripts PowerShell et Hive.
  • AppenderRole et TrackReceiverRole contiennent le code des deux roles Windows Azure. Ils font tous les deux appel à une bibliothèque commune.
  • BigDataTrackLib est cette bibliothèque commune qui contient entre autres le code d'accumulation des données.
  • TrackerBackend est le projet de déploiement en Cloud Service de Windows Azure.
  • SimpleTests est la console qui contient l'injection des données de test.

Réception des POST HTTP, écriture dans des blobs

Pour déployer les deux roles, on doit tout d'abord créer un service de cloud, et un compte de stockage. Dans ce compte de stockage, on initialise les éléments nécessaires.

Après avoir installé et configuré le module PowerShell pour Windows Azure (voir en annexes le paragraphe qui rappelle comment faire), il suffit d'utiliser le code suivant :

 
Sélectionnez
import-module Azure

#region change with your own values
$subscription = 'Azure bengui'
$suffix = "131104a"
#endregion

$serviceName = "bigdatatrack${suffix}"
$storageName = "bigdatatrack${suffix}"
$region = "North Europe"

Select-AzureSubscription -Default $subscription

# cloud service
New-AzureService -ServiceName $serviceName -Location $region

# storage account
New-AzureStorageAccount -StorageAccountName $storageName -Location $region
Set-AzureStorageAccount -StorageAccountName $storageName -GeoReplicationEnabled $false

$storageKey = (Get-AzureStorageKey -StorageAccountName $storageName).Primary
echo "storage key = '${storageKey}'" 

Set-AzureSubscription -SubscriptionName $subscription -CurrentStorageAccount $storageName

for ($i=0; $i -lt 3; $i++)
{
    New-AzureStorageQueue -Name "receiver2appender-${i}"
}

New-AzureStorageContainer -Name "trackingdata1"

Cela donne dans mon cas le résultat suivant :

 
Sélectionnez
PS C:\WINDOWS\system32> C:\dev\BigDataTrack\Scripts\CreateWindowsAzureArtifacts.ps1

OperationDescription                 OperationId                          OperationStatus                     
--------------------                 -----------                          ---------------                     
New-AzureService                     bbed9575-f647-2492-a9f6-2b3c464c7ba2 Succeeded                           
New-AzureStorageAccount              61567469-6426-2577-b248-88c70a1cdae4 Succeeded                           
Set-AzureStorageAccount              48b11e16-8413-2e3f-ae09-2d647e7982d1 Succeeded                           
storage key = 'iTBjE/YaGqg7sG5tWbjX9ePu3Rc+aKxrPZJpmd9onG9d4sS0kbV2UqqunRF64wClDtoMw0/k5DTiOYt3N+L+tw=='

   Queue End Point: https://bigdatatrack131104a.queue.core.windows.net/

Name                        Uri                         ApproximateMessageCount     EncodeMessage             
----                        ---                         -----------------------     -------------             
receiver2appender-0         https://bigdatatrack1311...                             True                      
receiver2appender-1         https://bigdatatrack1311...                             True                      
receiver2appender-2         https://bigdatatrack1311...                             True                      

    Blob End Point: https://bigdatatrack131104a.blob.core.windows.net/

Name                                         PublicAccess         LastModified                                
----                                         ------------         ------------                                
trackingdata1                                Off                  04/11/2013 11:25:25 +00:00                  
 
PS C:\WINDOWS\system32>

N.B. La clef obtenue ici (storage key) est celle que je laisse dans le code, ainsi que le nom du service de cloud ou du compte de stockage. Vous pouvez donc chercher ces valeurs pour les remplacer par vos propres valeurs dans le code (\BigDataTrack\BigDataTrackLib\DefaultValuesAndSecrets.cs, fichiers .config).

Pour déployer la solution depuis Visual Studio 2013, et après avoir mis à jour les valeurs avec le bon compte de stockage dans les fichiers de configuration, on peut procéder de la façon suivante.

Le nombre et la taille des VM qui seront créées initialement sont ajustables dans les onglets Configuration des deux éléments suivants du projet TrackerBackend :

Image non disponible

Ensuite, on peut publier directement depuis Visual Studio :

Image non disponible
Image non disponible

« Next> »

Image non disponible

« Next> »

Image non disponible

« Publish »

Si vous avez cet écran

Image non disponible

Vous pouvez choisir un nom d'utilisateur et un mot de passe qui vous serviront à vous connecter en bureau à distance sur les VM créées par le code. Cliquez ensuite sur OK, puis sur Publish à nouveau.

N.B. L'accès au bureau à distance n'est pas indispensable au fonctionnement de l'application, et vous pouvez le configurer une fois la solution déployée.

Vous pouvez suivre le déploiement depuis Visual Studio :

Image non disponible

Cela prend en général un peu plus de cinq minutes. Vous pouvez aussi suivre le déroulement depuis le portail :

Image non disponible

Une fois la solution déployée, le portail ressemble à ceci :

Image non disponible

Si vous voulez vous connecter par curiosité à l'une des instances de VM créées par le code, vous pouvez la sélectionner et cliquer sur CONNECTER.

Lors du démarrage, les valeurs par défaut ont été copiées dans la table qui était vierge. On peut voir cela par exemple dans Visual Studio, via le « Server Explorer » :

Image non disponible

On peut voir la page de test disponible à http://bigdatatrack131104a.cloudapp.net.

On la montre ici avec le code source de la page HTML, vue dans le navigateur.

Image non disponible

Cela correspond dans les sources de la solution Visual Studio à la page \BigDataTrack\TrackReceiverRole\Index.html

Analyse des données

La partie précédente ne dépend pas du type de données qui la traversent. Elle se contente d'accumuler les données ligne par ligne dans des blobs. Pour montrer comment on peut analyser des données, on injecte via une application console de test des données exemples en JSON.

Le code d'injection est le suivant :

 
Sélectionnez
            // biggest cities in France
            string[] cities = new string[] { "paris", "marseille", "lyon", (…),  "l'hay-les-roses", "chatou" };

            DateTime start = DateTime.UtcNow;
            var nbCities = cities.Length;
            Random random = new Random();
            for (int i = 0; i < 30000; i++)
            {
                if (i % 50 == 0) Console.WriteLine(i);

                var req = HttpWebRequest.Create("http://bigdatatrack131104a.cloudapp.net/t/");
                req.Method = "POST";
                using (var writeStream = req.GetRequestStream())
                {
                    using (var w = new StreamWriter(writeStream))
                    {
                        DateTime now = DateTime.UtcNow;
                        string city = cities[random.Next(0, nbCities - 1)];
                        string id = Guid.NewGuid().ToString("D");
                        string data = string.Format(
                            "{{{0}id{0}:{0}{1}{0},{0}city{0}:{0}{2}{0},{0}utcdate{0}:{0}{3:yyyy-MM-dd}{0},{0}utctime{0}:{0}{3:HH:mm:ss.fffffff}{0}}}",
                            "\"", id, city, now);
                        w.Write(data);
                    }
                }
                using (var resp = req.GetResponse())
                {
                    using (var respStream = resp.GetResponseStream())
                    {
                        using (var reader = new StreamReader(respStream))
                        {
                            if (i % 500 == 0) Console.WriteLine("[" + reader.ReadToEnd() + "]");
                        }
                    }
                }
            }
            DateTime end = DateTime.UtcNow;
            Console.WriteLine(string.Format("{0}, {1}, {2}", start, end, end - start));

Ce qui génère des données telles que :

 
Sélectionnez
{"id":"49ed9029-d5f9-460b-adc7-9d9b4501da8f","city":"reims","utcdate":"2013-10-31","utctime":"20:57:28.7517644"}
{"id":"f1efefa4-6a5e-4c24-afa0-6f8e7225d41c","city":"toulon","utcdate":"2013-10-31","utctime":"21:12:11.7517644"}
{"id":"6140ced2-1dc4-45f9-b9b2-8f3f4ea7de07","city":"versailles","utcdate":"2013-10-31","utctime":"22:09:57.7517644"}
{"id":"3951a13e-f5f1-4aa7-bc98-d0c67ea00ae0","city":"houilles","utcdate":"2013-10-31","utctime":"22:56:36.7517644"}
{"id":"7cdbb9a0-ee9c-423d-bd89-173ae9f272e0","city":"poissy","utcdate":"2013-10-31","utctime":"23:49:10.7517644"}
{"id":"7eddc671-d814-4824-b0dc-ee320188b5ac","city":"pau","utcdate":"2013-10-31","utctime":"23:56:38.7517644"}
{"id":"4a57491c-91c5-4d5c-a45a-d2f3af39b6b7","city":"troyes","utcdate":"2013-11-01","utctime":"00:38:58.7517644"}
{"id":"83c066a4-dd60-4013-8219-e9aba0f36ca4","city":"boulogne-billancourt","utcdate":"2013-11-01","utctime":"00:44:28.7517644"}
{"id":"915c5187-fc49-4c11-bd45-18c750fc27df","city":"baie-mahault","utcdate":"2013-11-01","utctime":"00:55:13.7517644"}
{"id":"d3ca8d59-dee4-462e-a8ce-9f596bf91a4b","city":"montelimar","utcdate":"2013-11-01","utctime":"01:34:16.7517644"}

Envoyons ces données au Tracker en lançant l'application console depuis Visual Studio directement.

Image non disponible

Si l'on veut avoir une latence plus faible, on peut aussi lancer l'application console depuis une machine virtuelle Windows Azure.

Image non disponible

Une fois les données injectées, on peut voir le résultat dans le blob storage de Windows Azure depuis Visual Studio, ou depuis un outil tel que CloudXplorer, ou encore depuis le portail Windows Azure :

Image non disponible
Image non disponible

On peut télécharger un de ces fichiers pour l'inspecter :

Image non disponible

Sous Windows, un fichier .gz peut s'ouvrir avec un outil tel que 7-Zip.

Image non disponible
Image non disponible

Ici les deux premières lignes correspondent à l'utilisation de la page de tests, puis les autres données sont les données JSON qui ont été injectées par l'application console. Ce sont elles qui nous intéressent. Dans notre scénario, ce sont typiquement des données envoyées par des applications mobiles.

Les deux premières lignes peuvent être ignorées. Il arrive souvent en Big Data qu'on ait quelques données qui n'ont pas le bon format. Nous verrons comment les ignorer. Pour analyser ces données, on va utiliser HIVE qui est un Framework Hadoop permettant de générer des jobs Map/Reduce à partir de code SQL. Si vous êtes intéressé par le détail, vous pouvez consulter le blog Big Data de Microsoft France à http://aka.ms/bigdatafrance.

Le code HIVE permettant de compter les hits par ville est le suivant :

 
Sélectionnez
drop table trackeddata;
create external table trackeddata (json_data string)
    row format delimited fields terminated by '\t' lines terminated by '\n' stored as textfile 
    location 'wasb://trackingdata1@bigdatatrack131104a.blob.core.windows.net/subfolder1';

drop table parseddata;
create external table parseddata (id string, city string, utcdate string, utctime string)
    row format delimited fields terminated by '\t' lines terminated by '\n' stored as textfile 
    location '/work/parseddata';

drop table hits_by_city;
create external table hits_by_city (city string, nb_hits int)
    row format delimited fields terminated by '\t' lines terminated by '\n' stored as textfile 
    location '/work/hits_by_city';

insert overwrite table parseddata
    select 
        get_json_object(json_data, '$.id') as id,
        get_json_object(json_data, '$.city') as city,
        get_json_object(json_data, '$.utcdate') as utcdate,
        get_json_object(json_data, '$.utctime') as utctime
    from trackeddata
    order by utcdate desc, utctime desc;

insert overwrite table hits_by_city
    select 
        city, count(distinct id) as nb_hits
    from parseddata
    where id IS NOT NULL
    group by city
    order by city asc;

Une table externe est une vue sur des données. En Big Data, on déclare le schéma au moment de la lecture, car, par définition, on a stocké les données sans savoir précisément comment on les lirait.

Par exemple,

 
Sélectionnez
create external table trackeddata (json_data string)
    row format delimited fields terminated by '\t' lines terminated by '\n' stored 
as textfile 
    location 
'wasb://trackingdata1@bigdatatrack131104a.blob.core.windows.net/subfolder1';

permet de voir le dossier

Image non disponible

comme un ensemble de données JSON dans des fichiers texte (le fait que les fichiers sont compressés n'est pas à déclarer, Hadoop s'en rendra compte tout seul).

Les données étant immuables en Hadoop (on les écrit, on les copie, on les supprime, mais on ne les met jamais à jour de façon à ne pas avoir de locks), on copie les tables dans d'autres tables, en les transformant au passage.

Par exemple, pour passer des données JSON brutes aux données parsées, on a

 
Sélectionnez
insert overwrite table parseddata
    select 
        get_json_object(json_data, '$.id') as id,
        get_json_object(json_data, '$.city') as city,
        get_json_object(json_data, '$.utcdate') as utcdate,
        get_json_object(json_data, '$.utctime') as utctime
    from trackeddata
    order by utcdate desc, utctime desc;

ce qui donne :

Image non disponible
Image non disponible

N.B. Sur un plus gros volume de données, cela pourrait générer plus de fichiers dans le même dossier.

Image non disponible

Finalement, le dernier fichier qui est le résultat d'un cumul est assez petit :

Image non disponible
Image non disponible
Image non disponible

La création du cluster HDInsight, le lancement du script HIVE, et la destruction du cluster se font en PowerShell avec le module azure installé et utilisé précédemment, ainsi que le module Microsoft.WindowsAzure.Management.HDInsight.Cmdlet qui peut s'installer depuis https://hadoopsdk.codeplex.com/releases. L'exemple de code ci-dessous utilise la version https://hadoopsdk.codeplex.com/releases/view/113809.

La création du cluster HDInsight, le lancement du script HIVE, et la destruction du cluster se font via le script PowerShell suivant :

 
Sélectionnez
#region imports
Import-Module azure
Import-Module Microsoft.WindowsAzure.Management.HDInsight.Cmdlet
#endregion

#region change with your own values
$subscription = 'Azure bengui'
$suffix = "131104a"
#endregion

#region initializations
$storageName = "bigdatatrack${suffix}"
$region = "North Europe"
Select-AzureSubscription -Default $subscription
Set-AzureSubscription -SubscriptionName $subscription -CurrentStorageAccount $storageName

$scriptsContainer = "scripts"
$hiveScriptName = "AnalyzeData.sql"
$clusterName = "hdinsight${suffix}"
$clusterAdminUsername = 'cornac'
$clusterAdminPassword = 'IFadlnvu51___'
$here = split-path -parent $MyInvocation.MyCommand.Definition

New-AzureStorageContainer -Name $scriptsContainer

$scriptPath = "wasb://${scriptsContainer}@${storageName}.blob.core.windows.net/${hiveScriptName}"

$passwd = ConvertTo-SecureString $clusterAdminPassword -AsPlainText -Force
$clusterAdminCredential = New-Object System.Management.Automation.PSCredential ($clusterAdminUsername, $passwd)
$subid = (Get-AzureSubscription -SubscriptionName $subscription).SubscriptionId

$storageKey = (Get-AzureStorageKey -StorageAccountName $storageName).Primary

# if you don't have a certificate, you may want to use the Get-AzurePublishSettingsFile cmdlet which will create one
$cert = (Get-AzureSubscription -SubscriptionName $subscription).Certificate

#endregion

#region create cluster
New-AzureHDInsightClusterConfig -ClusterSizeInNodes 2 |
    Set-AzureHDInsightDefaultStorage -StorageAccountName "${storageName}.blob.core.windows.net" `
        -StorageAccountKey $storageKey -StorageContainerName $clusterName |
    New-AzureHDInsightCluster -Subscription $subid -Name $clusterName -Certificate $cert `
    -Version '2.1' -Location $region -Credential $clusterAdminCredential
#endregion

# NB: may need to wait a little longer here

#region submit job, wait and retrieve log
Use-AzureHDInsightCluster -Certificate $cert -Name $clusterName -Subscription $subid

Set-AzureStorageBlobContent -File "$here\${hiveScriptName}" -Container $scriptsContainer `
    -BlobType Block -Blob $hiveScriptName -Force

$hiveJob = New-AzureHDInsightHiveJobDefinition -JobName "analyze_data" -File $scriptPath
$hiveJobId = $hiveJob | 
    Start-AzureHDInsightJob -Credential $clusterAdminCredential -Cluster $clusterName

echo $hiveJobId

Wait-AzureHDInsightJob -Credential $clusterAdminCredential -Job $hiveJobId -WaitTimeoutInSeconds 3600 |
    % { Get-AzureHDInsightJobOutput -Cluster $clusterName  -certificate $cert `
        -Subscription $subid -JobId $_.jobId -StandardError }

#endregion

#region remove cluster
Remove-AzureHDInsightCluster -Name $clusterName -Subscription $subid -Certificate $cert
#endregion

Il est à noter qu'on ne crée qu'un cluster à 2 nœuds (soit 1 fois 8 cœurs pour le « head node » et 2 fois 4 cœurs pour les « worker nodes » soit 16 cœurs qui s'ajoutent aux 2 cœurs du Web Role et aux 2 cœurs du Worker Role ; cela fait un total de 20 cœurs qui est la limite par défaut pour un compte Windows Azure, que l'on peut augmenter facilement, mais en faisant appel au support depuis le portail par exemple).

La copie d'écran suivante montre PowerShell ISE attendant la création du cluster :

Image non disponible

Visualisation des données

Pour lire les données dans Excel avec Power Query (téléchargeable à partir de ce lien : http://office.microsoft.com/en-us/excel/download-microsoft-power-query-for-excel-FX104018616.aspx) on procède comme suit :

Image non disponible
Image non disponible

Coller la clef du compte de stockage

iTBjE/YaGqg7sG5tWbjX9ePu3Rc+aKxrPZJpmd9onG9d4sS0kbV2UqqunRF64wClDtoMw0/k5DTiOYt3N+L+tw==

dans mon cas

Image non disponible
Image non disponible
Image non disponible
Image non disponible
Image non disponible
Image non disponible
Image non disponible

Renommer la première colonne en « ville », la seconde en « nb_hits ».

Puis changer le format de la seconde :

Image non disponible

Les différentes étapes ont été enregistrées et pourront être rejouées lors d'un rafraîchissement comme on le voit ci-dessous.

Image non disponible
Image non disponible

On charge les données dans PowerPivot plutôt qu'Excel

Image non disponible

N.B. Pour activer Power Pivot dans Excel 2013, il suffit d'activer le composant. File, Options, Add-Ins, COM Add-Ins, Go…, cocher « Microsoft PowerPivot for Excel 2013 », OK.

Image non disponible
Image non disponible

Renommer la colonne en Pays et mettre comme formule : ="France"

Image non disponible

Puis spécifier que ville est une ville et France un pays :

Image non disponible

Vérifier qu'Excel a deviné pour le pays.

Image non disponible
Image non disponible
Image non disponible
Image non disponible
Image non disponible

Remonter le champ pays

Image non disponible
Image non disponible
Image non disponible

Double-cliquer sur le pays (drill down) pour avoir la vue par ville :

Image non disponible

Ici, toutes les valeurs sont assez équivalentes (n_hits) puisque, pour rappel, notre application console d'injection de données de tracking s'appuie sur la méthode Next d'une instance de la classe Random.

Image non disponible

Améliorations de la solution

La solution présentée ici peut bien sûr être améliorée. En particulier les éléments suivants sont des pistes intéressantes :

  • prise en compte des requêtes CORS (http://www.w3.org/TR/cors/) de façon à autoriser les requêtes venant de sites Web qui sont dans d'autres domaines que le « Track Receiver » ;
  • possibilité d'augmenter encore la montée en charge en proposant plusieurs queues de stockage (déjà pris en compte) sur plusieurs comptes de stockages. Cela permettrait d'aller au-delà de 20 000 requêtes par seconde, qui est la limite d'un compte de stockage comme indiqué à http://msdn.microsoft.com/en-us/library/windowsazure/dn249410.aspx);
  • gestion de partitions dans HIVE pour analyser uniquement les nouvelles données ;
  • mise en place de l'autoscaling sur les web role et worker role.

Combien ça coûte ?

Le coût dépend du nombre de serveurs que l'on met au niveau des rôles, de la quantité de données stockées, de la taille du cluster et de la fréquence à laquelle on l'utilise. Prenons donc pour hypothèses :

  • stockage de 1 To glissant, plus 1 To pour les calculs intermédiaires ;
  • analyse sur un cluster de 10 nœuds pendant 1 h tous les jours ;
  • un Web role de 4 nœuds et un Worker role de 4 nœuds le jour (12 h/jour), et passage des deux roles à 2 nœuds la nuit soit en moyenne 3 nœuds sur chaque role ;
  • le niveau de support développeur.

Dans la calculatrice que l'on trouve à http://www.windowsazure.com/pricing, cela donne :

Image non disponible
Image non disponible

1 milliard de transactions de stockage correspondent à peu près à 500 millions de messages (1 transaction par écriture dans la queue de stockage, puis on les récupère 32 par 32 et ensuite, on les traite en volume). Ici cela représente une moyenne d'à peu près 190 messages/s jour et nuit, ce qui n'empêche pas d'avoir des pics à plusieurs milliers/s.

Image non disponible

N.B. L'essentiel de la donnée entre dans le datacenter, et c'est gratuit

Image non disponible

Soit 1,43 € * 31 j ~= 44,33 € dans le mois

Image non disponible

Soit à peu près

Image non disponible

On voit que l'essentiel du coût vient ici de la collecte de la donnée, et non de l'analyse avec Hadoop de cette donnée.

Conclusion

Nous avons vu comment collecter des informations JSON (ou autre) venant de différentes instances d'applications mobiles sur une ferme Web, agréger ces données sous forme de fichiers dans le nuage (blobs). Nous avons également vu comment créer par script un cluster Hadoop en tant que service, comment lui soumettre un script à la SQL (HIVE) pour analyser les données ainsi collectées avant de détruire le cluster. Enfin, nous avons vu comment récupérer les résultats (sans que le cluster Hadoop ait besoin d'être allumé) dans Excel Power Query, pour alimenter un modèle Power Pivot et visualiser le résultat sur une carte dans Power View.

Ces différentes parties sont relativement indépendantes. Elles peuvent être réutilisées indépendamment les unes des autres. Ensemble, elles constituent une solution de type cloud hybride, où des applications mobiles situées par définition à des endroits très divers envoient des données dans le cloud pour analyse avant visualisation dans les murs de l'entreprise (Excel).

Le cloud hybride, cela peut correspondre à des solutions aussi concrètes que cela !

Téléchargements

Le code source est disponible en téléchargement ici.

Annexes

Téléchargement et installation du module PowerShell pour gérer Windows Azure

Pour manipuler l'environnement Windows Azure depuis du code et depuis une machine Windows, PowerShell est un excellent environnement. PowerShell lui-même fait partie de Windows depuis déjà un certain nombre d'années. En revanche, le module de gestion de Windows Azure doit être téléchargé. Depuis la machine « dans-mes-murs », on se rend donc à l'adresse suivante :

http://www.windowsazure.com/fr-fr/downloads/#cmd-line-tools

Image non disponible

On télécharge et installe ce module.

Image non disponible

Puis on exécute Windows PowerShell

Image non disponible

Et l'on tape les commandes suivantes :

 
Sélectionnez
Import-module azure
Get-command -module azure
Image non disponible

Ensuite, on ajoute le compte avec lequel on peut se connecter au portail Windows Azure (http://manage.windowsazure.com) de façon à pouvoir disposer des mêmes ressources depuis PowerShell.

N.B. Si vous n'avez pas de compte Windows Azure, vous pouvez vous en procurer un avec l'offre d'essai gratuite. Rendez-vous par exemple à http://aka.ms/tester-mon-azure.

Tapez en PowerShell :

 
Sélectionnez
Add-AzureAccount

Puis laissez-vous guider

Image non disponible

Une façon de vérifier que tout est correct est de taper :

 
Sélectionnez
Get-AzureSubscription

Cela doit vous donner la liste des abonnements auxquels votre compte entré ci-dessus a droit.

La suite des opérations dans PowerShell se fera dans l'IDE de PowerShell appelé ISE. On le démarre de la façon suivante :

Image non disponible
Image non disponible

Le bouton Image non disponible (ou F5) permet d'exécuter tout le script saisi.

Le bouton Image non disponible (ou F8) permet d'exécuter uniquement le code sélectionné.

Si on dispose de plusieurs abonnements Azure, comme c'est mon cas, on peut choisir l'abonnement par défaut de la façon suivante :

 
Sélectionnez
Select-AzureSubscription -Default "Azure bengui"

Dans votre cas, remplacez « Azure bengui » par le nom de votre propre abonnement.