Tutoriel - Synchronisation De Votre Application De Fonction Avec Le Concentrateur IoT Et Exemple De Connexion Avec Un Objet Sigfox

Ce tutoriel a été rédigé par Eugénie Vinet, stagiaire à la Direction Technique de Microsoft France de avril à août 2016 avec l’aide de son maître de stage Philippe Beraud, Chief Security Advisor à la Direction Technique.
Je remercie Eugénie et Philippe pour cette contribution.

Synchroniser une application de fonction avec un concentrateur IoT

Pour créer une application de fonction avec Azure Function App, procédez comme suit :

1/ Connectez-vous au portail d’Azure à l’adresse https://portal.azure.com

2/ Cliquez sur New en haut à gauche et cherchez Function App.

3/ Cliquez sur create. Entrez ensuite un nom, lié le à un de vos groupes de ressources existants (ou à défaut créez-en un nouveau). Si vous voulez que votre application de fonction fonctionne en continu, choisissez un plan de service B1 associé au minimum.
Le portail Function App s’affiche

4/ Cliquez sur Or create your own custom function en bas. Une liste des modèles disponibles s’affiche pour votre application de fonction.

5/ Selon votre choix de programmation (C# ou Node) cliquez sur EventHubTrigger – C# ou EventHubTrigger – Node.
Azure Function App propose de déclencher une fonction à partir d’un événement dans un concentrateur d’événements, mais pas dans un concentrateur IOT; cependant, un concentrateur IOT peut être vu comme un concentrateur d’événements. C’est ce que nous allons faire.

6/ Précisez le nom de votre application de fonction et configurez la connexion avec votre concentrateur IoT dans Event Hub connection.

Pour connaître le nom et la chaîne de connexion du concentrateur IoT :

a. Rendez-vous dans les paramètres de votre concentrateur IoT puis cliquez sur Messaging.

b. Notez la valeur de Event-Hub compatible name (par exemple DecodeSigfoxHub dans notre illustration) ainsi que celle de Compatible endpoint.

c. Toujours au niveau de votre concentrateur IoT, allez ensuite dans Shared Access Policies et copier la connection string – primary Key. Enlevez la partie HostName à la chaine de caractères de manière à ne garder que SharedAccessKeyName et SharedAccessKey. Vous obtenez par exemple :
SharedAccessKeyName=iothubowner;SharedAccessKey=MrsSPDzU5=8g2gZZPKXOJ9EJ5RDlo2PVzmPuGniLRwQ=

d. Retournez dans la fenêtre de votre application de fonction - ne fermez pas la fenêtre de paramètres de votre concentrateur IoT, vous en aurez besoin plus tard -. Nommez votre application de fonction comme bon vous semble :)

e. Dans Event Hub Name, entrez la valeur précédente de Event-Hub compatible name. Attention cependant, il ne supporte que les noms en minuscule. S’il y a des majuscules dans votre valeur de Event hub compatible name, passez tout en minuscule (par exemple decodesigfoxhub dans notre illustration)

f. Cliquez ensuite sur select à côté de Event Hub connection. Cliquez ensuite sur Add a connection string en haut à droite.

g. Dans Connection name, spécifiez le nom que vous souhaitez.

h. Dans Connection string, précisez :
Endpoint=<CompatibleEndpoint><SharedAccessKeyName><SharedAccessKey>
Vous obtenez une chaine de caractère semblable à :
Endpoint=sb://iothub-ns-decodesigf-499548662a53f6c.servicebus.windows.net/;SharedAccessKeyName=iothubowner;SharedAccessKey=MrsSPDzU5=8g2gZZPKXOJ9EJ5RDlo2PVzmPuGniLRwQ=

7/ Validez.
Votre application de fonction s’exécutera alors à chaque message reçu par l’utilisateur.
Vous pouvez alors modifier les informations que vous recevez de votre concentrateur IoT pour les renvoyer autre part ou les stocker par exemple.
Vous trouverez ci-après un exemple concret d’usage d’une application de fonction dans notre contexte, à savoir le décodage de trames Sigfox pour les renvoyer sur la solution préconfigurée de surveillance à distance (Cf. portail associé à l’adresse https://www.azureiotsuite.com/) .

Exemple avec IoT Suie - Objet Sigfox

Nous vous proposons dans cette section un exemple de projet utilisant Azure Function App avec un concentrateur IoT.
La solution préconfigurée de surveillance à distance s’attend recevoir des messages sur son concentrateur IoT de type :

1
2
3
4
5
6
{
DeviceId = XX,
Humidity = XX,
Temperature = XX,
ExternalTemperature = XX
}

Dans ce projet nous voulons utiliser des objets Sigfox (voir ici http://makers.sigfox.com/#about) qui envoient des trames de type :
« 422D17 » avec 42 l’identifiant du type d’objet, 2D l’humidité (45%) et 17 la température (en décimal = 23°C). »
On va supposer que l’humidité et la température sont deux entiers qui vont de 0 à 100.

Prérequis

Les prérequis sont les suivants :
• Avoir lié un device Sigfox qui envoie des données de température et d’humidité, Cf. tutoriel PUSH YOUR SIGFOX DEVICES DATA TO AZURE IOT HUB .

• Avoir créé et provisionné une solution préconfigurée de type Solution de surveillance à distance sur le site dédié à l’adresse http://www.azureiotsuite.com/.

• Avoir suivi l’étape précédente de synchronisation d’une Function App avec un concentrateur IoT en utilisant le concentrateur IoT Hub lié à l’objet Sigfox.

Si ces prérequis sont satisfaits, les étapes de mise en œuvre sont les suivantes :

• Etape 1 – Ajout de l’objet préconfiguré.

• Etape 2 – Remplissage du fichier JSON.

• Etape 3 – Ajout des paquets.

• Etape 4 – Contenu de votre application de fonction.

Nous les développons dans l’ordre au travers d’une section dédiée propre.

Etape 1 – Ajout de l’objet préconfiguré

Pour ajouter un objet, procédez comme suit :

  1. Rendez-vous à présent sur l’environnement de démonstration iotmsfrance à l’adresse https://www.azureiotsuite.com/.
  2. Connectez-vous avec votre compte. Comme cela a été indiqué précédemment, vous devez disposer de privilèges d’administration pour pouvoir enregistrer un objet.
    De plus, réalisez cette étape UNIQUEMENT si l’objet n’apparait pas dans la liste des appareils du concentrateur IoT de l’environnement de démonstration (vous pouvez vérifié via le portail Azure ou via l’application Device Explorer). Si votre objet est déjà présent dans la liste, il faudra le supprimer en utilisant le Device Explorer.
    L’application Device Explorer est téléchargeable à l’adresse https://github.com/Azure/azure-iot-sdks/releases. Le répertoire d’installation par défaut de cette application est :
    C:\Program Files (x86)\Microsoft\DeviceExplorer
  3. Une fois sur le site, dans la liste des solutions approvisionnées, sélectionnez la Solution de surveillance à distance, c.à.d. la solution .azurewebsite.net.
  4. Cliquez en bas à gauche sur Ajouter un appareil (ou Add a device en anglais).

    L’étape 1 d’ajout d’un appareil s’affiche.
  5. Dans le cadre Appareil personnalisé, sélectionnez Ajouter un nouveau. L’étape 2 s’affiche.
  6. Sélectionnez l’option Me laisser définir mon propre ID d’appareil et donnez lui le même ID que dans Sigfox /!\ ça ne marchera pas si vous choisissez un id différent.
  7. Cliquez sur Vérifier l’ID. L’ID doit être disponible.
  8. Cliquez enfin sur Créer.
    A ce stade, l’objet n’est pas activé dans la plateforme. Il va falloir modifier les informations relatives à l’objet dans la base NoSQL DocumentDB. Pour cela, connectez-vous au portail d’Azure à l’adresse https://portal.azure.com et réalisez l’étape suivante.

Etape 2 – Remplissage du fichier JSON

Pour remplir le fichier JSON d’informations lié à l’objet, procédez comme suit :

  1. Rendez-vous dans la rubrique DocumentDB Accounts sur le portail Azure à l’adresse https://portal.azure.com.
  2. Sélectionner le compte DocumentDB du projet :
  3. Cliquez ensuite sur votre base de données DevMgmtDb (1). Dans DevMgmtDB, cliquez sur Document Explorer (2).
    Vous devriez voir apparaitre une liste comme celle-ci :
{
    "DeviceProperties": {
    "DeviceID": "{NomDeVotreDevice}",
    "HubEnabledState": true,
    "CreatedTime": "0001-01-01T00:00:00",
    "DeviceState": "normal",
    "Manufacturer": "{Manufacturer}",
    "ModelNumber": "{NomDuModelDuDevice}",
    "SerialNumber": "{NumeroDeSérie}",
    "FirmwareVersion": "{FirmwareVersion}",
    "Platform": "{Plateform}",
    "Latitude": {Longitude} ,
    "Longitude": {Latitude},
    "Processor": "{processor}",
    "InstalledRAM": "{installedRam}",
},
"SystemProperties": {
    "ICCID": null
},
 "Commands": [
    {
      "Name": "PingDevice",
      "Parameters": null
    },
    {
      "Name": "StartTelemetry",
      "Parameters": null
    },
{
  "Name": "StopTelemetry",
  "Parameters": null
},
{
  "Name": "ChangeSetPointTemp",
  "Parameters": [
    {
      "Name": "SetPointTemp",
      "Type": "double"
    }
  ]
},
{
  "Name": "DiagnosticTelemetry",
  "Parameters": [
    {
      "Name": "Active",
      "Type": "boolean"
    }
  ]
},
{
  "Name": "ChangeDeviceState",
  "Parameters": [
    {
      "Name": "DeviceState",
      "Type": "string"
    }
  ]
}
],
"CommandHistory": [],
"IsSimulatedDevice": 0,
 "id": "",
 "Telemetry": [
    {
  "Name": "Temperature",
  "DisplayName": "Temperature",
  "Type": "double"
},
{
  "Name": "Humidity",
  "DisplayName": "Humidity",
  "Type": "double"
}
],
 "Version": "1.0",
 "ObjectType": "DeviceInfo"
 }
}

Si vous n’avez pas réalisé l’étape 3 si l’objet existait déjà dans le concentrateur IoT, il est possible qu’il n’y ait aucun fichier relatif à l’objet dans la base de données. Il va alors falloir en créer un en cliquant en haut à gauche.
Par contre si vous aviez réalisé l’étape 3, le fichier relatif au device devrait se trouver dans la liste. Il devrait avoir un nom de type « 2f23278e-0e82-4850-86f5-b5c3f83a8850 » ou bien le nom du device comme « BFFBA ». Pour vérifier si un fichier est lié à votre objet, il suffit de l’ouvrir et de lire le DeviceID. Il doit être identique à l’ID que vous avez enregistré sur la page web de la solution de surveillance à distance et identique à l’ID de l’objet enregistré sur le portail Sigfox. (1)
Supprimez ou modifiez le contenu du fichier dont le DeviceID est le nom de votre objet et recopier le texte à droite puis complétez/modifiez les zones en jaune comme suit :

    HubEnabledState : doit être passé à true.
    DeviceState : doit être normal. 
    CreatedTime : doit être de la forme : AAAA-MM-JJThh:mm:ss 
Avec AAAA l’année, MM le mois, JJ le jour, hh l’heure, mm les minutes et ss les secondes. 
Il est recommandé de mettre la date et l’heure qu’il est au moment où vous remplissez le fichier mais cela ne va pas avoir d’impact sur le fonctionnement général de la surveillance à distance. 
    SerialNumber : doit préciser le numéro de série de l’objet si celui en est « équipé ». A défaut, écrivez le nom de l’objet entre guillemets.
    Manufacturer : doit préciser le nom du fabricant de l’objet entre guillemets.
    ModelNumber : doit préciser le numéro de modèle de l’objet si celui en est « équipé ». A défaut, écrivez le nom de l’objet entre guillemets
    FirmwareVersion, Platform, Processor et InstalledRam : si vous ne les connaissez pas pour le device utilisé vous pouvez écrire « None ». 
    Latitude et Longitude : vous avez le choix de son emplacement. L’objet s’affichera à l’endroit indiqué sur la carte. Vous pouvez vous aider de ce site : http://www.latlong.net/ pour trouver la longitude et la latitude d’un endroit précis. Attention : la longitude et la latitude ne doivent pas être écrites entre guillemets sur le document. 
    Id : sera l’ID du document que vous avez créé/modifié. Il est recommandé d’utiliser le nom de l’objet afin de retrouver plus facilement le document. 

Etape 3 - Ajout des paquets

Tout d’abord nous allons ajouter les paquets nécessaires à notre application de fonction. Pour ceci, nous allons suivre les étapes pour charger un fichier project.json contenant le nom de tous nos paquets (rubrique Package Management sur le site https://azure.microsoft.com/en-us/documentation/articles/functions-reference-csharp/ et File Update ici https://azure.microsoft.com/en-us/documentation/articles/functions-reference/#fileupdate ).
Procédez comme suit :

  1. Rendez-vous dans les outils de votre application de fonction.
  2. Cliquez sur Kudu puis sur accédez. Vous vous retrouvez donc sur le système de gestion des fichiers de votre application de fonction.
  3. Allez dans Debug Console puis PowerShell. En utilisant la commande ou bien en utilisant l’explorateur de fichier au-dessus rendez-vous sur D:\home\site\wwwroot\>
  4. Ajoutez alors un fichier project.json qui contient les lignes suivantes - un simple glissé-déposé suffit - :

    {
    “frameworks”: {
    “net46”:{

    "dependencies": {                                                
            "Microsoft.Azure.Devices.Client":"1.0.6",
            "Newtonsoft.Json":"8.0.3",                
            "Microsoft.Azure.Devices":"1.0.6"            
            }
        }      
    }
    

    }

Etape 4 – Définition du contenu de votre application de fonction

Pour définir le contenu de votre application de fonction, procédez comme suit :

1/ Retournez sur votre application de fonction et ajoutez la classe DataToReceive. Le contenu dépendra du contenu du JSON entré pour le callback de votre Device Type dans le portail Sigfox.
Si vous avez par exemple ce JSON :

{
   "device" : "{device}",
   "data" : "{data}",
   "time" : {time},
   "snr" : {snr},
   "station" : "{station}",
   "rssi" : {rssi},
   "seqNumber" : {seqNumber}
}

Votre classe DataToReceive doit ressembler à cela :

public class DataToReceive
{
    public string device { get; set; }
    public string data { get; set; }
    public double time { get; set; }
    public string seqNumber { get; set; }
    public string rssi { get; set; }
    public string snr { get; set; }
    public string station { get; set; }
}

Il faut qu’il y ait au minimum les variables « device » et « data ».

2/ Créer ensuite une classe DataToSend qui réunira les informations que vous voulez envoyer dans votre solution préconfigurée de surveillance à distance. Nous envoyons ici que l’Id de l’objet, la température et l’humidité. Vous pouvez ajouter le paramètre External Température.

1
2
3
4
5
6
public class DataToSend
{
public string DeviceId { get; set; }
public double Humidity { get; set; }
public double Temperature { get; set; }
}

3/ Créez la classe SendToIotHub comme suit. Remplacez bien les valeurs de connectionString et d’iotHubUri par les éléments relatifs au concentrateur IoT de la solution préconfigurée.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class SendToIotHub
{
DeviceClient deviceClient;
Device device;
string jsonMessageToSend;
string connectionString = "{IotHubConnexionString}";
string iotHubUri = "{IotHubName}.azure-devices.net";
public async void sendData(DataToSend data, TraceWriter log)
{
RegistryManager registryManager = RegistryManager.CreateFromConnectionString(connectionString);
device = new Device(data.DeviceId);
device = await AddDeviceAsync1(data.DeviceId, registryManager);
deviceClient = DeviceClient.Create(iotHubUri, new DeviceAuthenticationWithRegistrySymmetricKey(data.DeviceId,device.Authentication.SymmetricKey.PrimaryKey.ToString()));
jsonMessageToSend = JsonConvert.SerializeObject(data);
var messageToSend = new Microsoft.Azure.Devices.Client.Message(System.Text.Encoding.ASCII.GetBytes(jsonMessageToSend));
deviceClient.SendEventAsync(messageToSend);
log.Info($"C# Event Hub trigger function processed a message: {jsonMessageToSend}");
}
private async Task<Device> AddDeviceAsync1(string deviceId, RegistryManager registryManager)
{
Device device;
try
{
device = await registryManager.AddDeviceAsync(new Device(deviceId));
}
catch (DeviceAlreadyExistsException)
{
device = await registryManager.GetDeviceAsync(deviceId);
}
return device;
}
}

4/ Ajoutez les directives using « de circonstance » au début de votre application de fonction :

1
2
3
4
5
using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Client;
using System;
using Microsoft.Azure.Devices.Common.Exceptions;
using Newtonsoft.Json;

5/ Complétez maintenant la méthode Run :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void Run(string myEventHubMessage, TraceWriter log)
{
log.Info($"C# Event Hub trigger function processed a message: {myEventHubMessage}");
DataToReceive receivedData = new DataToReceive();
DataToSend sentData = new DataToSend();
SendToIotHub sendDataToIotHub = new SendToIotHub();
receivedData = JsonConvert.DeserializeObject<DataToReceive>(myEventHubMessage);
if (receivedData.data != null && receivedData.data.Substring(0, 2) == "42")
{
string data = receivedData.data;
sentData.Humidity = Convert.ToInt32(data.Substring(2, 2), 16);
sentData.Temperature = Convert.ToInt32(data.Substring(4, 2), 16);
sentData.DeviceId = receivedData.device;
sendDataToIotHub.sendData(sentData, log);
}
}

Vous obtiendrez quelque chose de similaire à la capture qui suit si tout va bien :

Vous devriez voir dans les logs les messages reçus et envoyés si vous gardez les lignes de code log.info (…..).

Bien sûr, nous partons du principe que les trames à utiliser sont de la forme « 422D17 » (comme développé précédemment) mais il est possible que vous ayez à faire des calculs sur chaque élément de votre trame pour obtenir les valeurs décimales renvoyées par vos capteurs. Pour ceci, renseignez-vous auprès du constructeur de l’objet.

Et voilà !
Ceci conclut ce tutoriel.

Deploying Containers to One or Several VMs

Here is a sample test to show how Docker Swarm and Docker Compose simplify network management.

We’ll deploy a topology of 3 containers and see how they can reach each other. In the first case, we deploy it on a single node. In the second case, we deploy it on a 2 host swarm cluster.

The Swarm cluster is created as a Swarm Azure Container Service instance with the main following parameters:

  • Orchestrator configuration: Swarm (btw, other option for ACS is DC/OS)
  • Agent count: 2
  • Agent virtual machine size: (leave default)
  • Master count: 1
  • DNS prefix for container service: myacs

Two files are created

The Dockerfile contains:

1
2
3
FROM busybox
ENTRYPOINT ["init"]

The docker-compose.yml file has the following content:

1
2
3
4
5
6
7
8
9
10
11
version: '2'
services:
node1:
build: .
container_name: n1
node2:
build: .
container_name: n2
node3:
build: .
container_name: n3

on a single box

Here is what I get on the single box:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
benjguin@benjguinu1605a:~/simpletest$ docker-compose up -d
Creating network "simpletest_default" with the default driver
Creating n1
Creating n3
Creating n2
benjguin@benjguinu1605a:~/simpletest$ docker-compose ps
Name Command State Ports
------------------------------
n1 init Up
n2 init Up
n3 init Up
benjguin@benjguinu1605a:~/simpletest$ docker exec n1 ping -c 2 n2
PING n2 (172.19.0.4): 56 data bytes
64 bytes from 172.19.0.4: seq=0 ttl=64 time=0.086 ms
64 bytes from 172.19.0.4: seq=1 ttl=64 time=0.067 ms
--- n2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.067/0.076/0.086 ms
benjguin@benjguinu1605a:~/simpletest$ docker exec n1 ping -c 2 n3
PING n3 (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.072 ms
64 bytes from 172.19.0.3: seq=1 ttl=64 time=0.072 ms
--- n3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.072/0.072/0.072 ms
benjguin@benjguinu1605a:~/simpletest$ docker exec n3 ping -c 2 n1
PING n1 (172.19.0.2): 56 data bytes
64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.051 ms
64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.060 ms
--- n1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.051/0.055/0.060 ms

on a Swarm cluster

Let’s now do the same from the master node of my ACS cluster.

network information was added to the docker-compose.yml file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
version: '2'
services:
node1:
build: .
container_name: n1
networks:
- net34
node2:
build: .
container_name: n2
networks:
- net34
node3:
build: .
container_name: n3
networks:
- net34
networks:
net34:
driver: overlay

and here is the result of the test:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
export DOCKER_HOST=172.16.0.5:2375
benjguin@swarm-master-B295EC2C-0:~$ docker-compose up -d
Creating network "benjguin_net34" with driver "overlay"
Creating n1
Creating n3
Creating n2
benjguin@swarm-master-B295EC2C-0:~$ docker inspect n1 | grep swarm-agent
"Name": "swarm-agent-B295EC2C000001",
benjguin@swarm-master-B295EC2C-0:~$ docker inspect n2 | grep swarm-agent
"Name": "swarm-agent-B295EC2C000000",
benjguin@swarm-master-B295EC2C-0:~$ docker inspect n3 | grep swarm-agent
"Name": "swarm-agent-B295EC2C000000",
benjguin@swarm-master-B295EC2C-0:~$ docker exec n2 ping -c 2 n1
PING n1 (10.0.0.2): 56 data bytes
64 bytes from 10.0.0.2: seq=0 ttl=64 time=1.088 ms
64 bytes from 10.0.0.2: seq=1 ttl=64 time=0.830 ms
--- n1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.830/0.959/1.088 ms
benjguin@swarm-master-B295EC2C-0:~$ docker exec n1 ping -c 2 n2
PING n2 (10.0.0.4): 56 data bytes
64 bytes from 10.0.0.4: seq=0 ttl=64 time=0.671 ms
64 bytes from 10.0.0.4: seq=1 ttl=64 time=0.695 ms
--- n2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.671/0.683/0.695 ms
benjguin@swarm-master-B295EC2C-0:~$ docker exec n1 ping -c 2 n3
PING n3 (10.0.0.3): 56 data bytes
64 bytes from 10.0.0.3: seq=0 ttl=64 time=1.050 ms
64 bytes from 10.0.0.3: seq=1 ttl=64 time=0.783 ms
--- n3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.783/0.916/1.050 ms
benjguin@swarm-master-B295EC2C-0:~$ docker exec n2 ping -c 2 n3
PING n3 (10.0.0.3): 56 data bytes
64 bytes from 10.0.0.3: seq=0 ttl=64 time=0.068 ms
64 bytes from 10.0.0.3: seq=1 ttl=64 time=0.076 ms
--- n3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.068/0.072/0.076 ms

Conclusion

We have containers in a common network which is described only thru docker means.
This works on a single host, and also on multiple hosts (in the example, a host had 1 container, another host had 2 of the 3 containers).

MapR on Azure

Introduction

There are different ways to install Hadoop on Azure. The blog post about the different flavors of Hadoop will provide more context.

This blog post shows the main steps to start with MapR on Azure.

How to

In order to install the cluster, follow the wizzard that you’ll find in Azure portal.

Here is a quick view of this wizzard:

Step 3 gives you a chance to download the generated Azure resource manager wizzard that you can modify and deploy as described in the following article: Deploy an application with Azure Resource Manager template.

Once you’ve created the cluster, go to https://{yourclustername}-node0.{install-location}.cloudapp.azure.com:9443 and connect.

In my case, I named the cluster mapr34 and installed it in North Europe region, so it is https://mapr34-node0.northeurope.cloudapp.azure.com:9443.

NB: this mapr34-node0.northeurope.cloudapp.azure.comhost name can be found in the portal when you browse the resource group where the cluster is. It’s attached to the public IP of the node.

Use mapr as the username and the password you provided in step 2 of the wizzard as the password.

Select each node and check the disks where you want to install the distributed file system.
/dev/sdb1 is the cache disk. The 1023 GB disks are VHDs.

Use the Next button to move on

Click Install -> to start the installation process.

After a number of minutes, the installation completes.

On the final step, you can find a link to a short name. Unless you’ve created an SSH tunnel to your cluster, you may need to use the long name instead. In this example where my cluster is called mapr34 and is installed in North Europe, the URL is https://mapr34node1:8443/. I replace it by https://mapr34-node1.northeurope.cloudapp.azure.com:8443.

NB: this mapr34-node1.northeurope.cloudapp.azure.comhost name can be found in the portal when you browse the resource group where the cluster is. It’s attached to the public IP of the node.

ypou connect with the same credentials as before: mapr/{the password you provided in step 2 of the creation wizzard}.

Now that the MapR file system is installed. Let’s see it as HDFS. Let’s also check if we can access Azure blob storage.

The wasb driver (wasb stands for Windows Azure Storage Blob) is not installed by default :-( .

If you go back to the installation page you’ll have the option to install additional services:

When you’re done, you can stop the services, before shutting down the Azure virtual machines. If there are many nodes, you may want to use Azure PowerShell module or Azure Command Line Interface (Azure CLI). You can find them in the resources section of azure.com.

You may also prefer to remove all the resources that consitute the cluster: VMs, storage, vNet and so on. Of course, all the data will be removed as well, so you are asked to type the resource group before deleting it.

Conclusion

We saw how to create a MapR cluster in Azure. You just have to enter a few parameters in friendly Web interfaces and wait for the cloud and MapR to create everything for you!

:-)
Benjamin (@benjguin)

Different Flavors of Hadoop & Spark

There are four main ways to install Hadoop & Spark:

This blog post shows the different options in the context of Azure.

From Apache (http://hadoop.apache.org/releases.html)

This option is chosen by people who want to select the components themselves, and want to get the releases as soon as they are available.

If you want that option, it’s probably because your want to have control, rather than using a cluster somebody tailored for you.
The recommended way to do in Azure is to use Azure Virtual Machines, virtual network, and install everything yourself.
For that, you may want to leverage Azure Resource Manager templates. A number of examples are available on GitHub. For instance, this one deploys a Zookeeper cluster on Ubuntu VMs.

Hadoop architecture on Azure

There are several ways to deploy a Hadoop cluster on Azure, and several ways to store the data.
A virtual machine on Azure has

  • local disk which is mainly used for cache (Cache disk),
  • Virtual Hard Disks (VHD) that live in the Azure storage; in particular, this is the case of the OS disk (the only exception is with web and worker roles)
  • the virtual machine can also access blob storage which is a storage service where one can put files. It is accessible thru REST API, but also thru the wasb (Windows Azure Storage Blob) driver which is available in Hadoop.

Data Lake Store is also a new way of storing big data. For now (NOV 2015) it is in preview and can be used from Data Lake Analytics and HDInsight; later on, it will also be usable from standard distributions:

Comparing Cloudera, Hortonworks and MapR

Many articles have been written on how the distributions compare.

Here is how I see them.

Hortonworks is the closest to the Apache Hadoop distribution; All their code is Apache’s code and 100% open source. Hortonworks Data Platform (HDP) is described here.

Cloudera is the mots popular; in particular, users like Impala and Cloudera Manager. Their code is 100% open source, but not 100% Apache code (yet?). They recently decided to donate Impala and Kudu to the Apache Software Foundation.

MapR builds a distribution for business critical production applications; they are well known for their MapR file system (MapR-FS) which can be viewed as HDFS (Hadoop Distributed File System) and NFS (Network File System), and has the reputation of being fast. Mapr-FS is proprietary. The distribution is described here.

Anyway, the best solution is the one you chose!

Here is how those distribution leverage Azure. They have different approaches.

Distribution uses Cache Disk uses VHD uses blobs prices options
Cloudera Yes Yes, premium storage only for cold archive only high only because Cloudera supports only high end performances Cluster, single VM
Hortonworks not by default (HDFS) Yes (HDFS) Yes low to high Cluster, single VM, Hadoop as a service (HDInsight)
MapR Yes (Mapr-FS) Yes (Mapr-FS) No. wasb driver is not installed low to high Cluster

NB: the options mentioned above are automated ones. Of course, you can leverage Azure virtual machines and virtual networks to install any distribution you like on a single VM or on a cluster.

The fact that Cloudera only supports blob storage as a cold archive makes it more difficult to create different clusters on the same storage. It also requires that you save the data to blob storage explicitely before shutting down if you need to access the data while the cluster is off.

With MapR, as you don’t have the wasb driver, it is difficult to make the data available while the cluster is shut down.

With Hortonworks, you can use Azure blob storage as the default distributed file system. With that, you can start the cluster only when you need compute power. The rest of the time, you can bring data to the storage thru REST API, or SDKs in different languages. When you need compute, you can create a cluster that has the required size. You loose collocality (which is mainly important in the first map phase, before shuffle), but you win a lot of flexibility.

I hope that MapR and Cloudera will enhance their usage of cloud storage with Azure Data Lake Store. Azure Data Lake should meet the performance requirements of Cloudera so that they don’t use it only for cold archive. I’m quite confident that Hortonworks will add Azure Data Lake driver. This is already the case with HDInsight.

Let now see how you can deploy those distributions on Azure.

Cloudera (http://www.cloudera.com)

There are different options. This page from Cloudera’s web site show the different available distributions. From Azure marketplace, you can find the following (as of 2 DEC 2015):

An automated way of deploying a Cloudera Enterprise Data Hub cluster has been made available by Cloudera on Azure.

You’ll find a blog post on how to deploy it on the Azure web site. Also make sure to read the last paragraph (Cloudera Enterprise Deployment from GitHub) which explains there is also a template on GitHub if you need more flexibility.

If you prefer to install a single VM, you can use the Cloudera-Centos-6.6 offer. Its documentation is available at azure.microsoft.com/en-us/marketplace/partners/cloudera/cloudera-centos-6/.

HortonWorks (http://hortonworks.com)

In order to install Hadoop as a service with an Hadoop Data Platform, you can leverage HDInsight on Windows or Linux nodes. Documentation is available at azure.microsoft.com/en-us/documentation/services/hdinsight/.

Besides HDInsight, the marketplace has other options:

In order to install an HDP cluster, you can leverage the wizzard. Note that as of today (2 DEC 2015), the wizzard deploys HDP 2.1, while latest version of HDP is 2.3. An updated version of this wizzard should be made available in the coming weeks, hopefully. If you want to have an early look at this, I think this is on Github: github.com/Azure/azure-quickstart-templates/tree/master/hortonworks-on-centos.

If you want to install a single VM, a sandbox is available. If you can read French or if you know how to have the page translated for you, you are welcome to read my previous post: Hadoop : Comment réduire ses coûts HDInsight pour le développement

MapR (http://mapr.com)

MapR is also available on the Azure marketplace:

In order to install the cluster, please see this blog post

Conclusion

We saw that there are a number of options to install Hadoop on Azure.

Want to comment? I’m sorry, I didn’t leverage a tool like Disqus yet on this blog. Please feel free to e-mail me at my twitter alias at microsoft dot com and I’ll include your remarks in the body of this post.

:-)
Benjamin (@benjguin)