13.11.2019 / Aarni Vanamo

Lähtökohta

Uuden kehittäminen on hauskaa, mutta yhdessä kehittäminen on hauskempaa. Pari viikkoa sitten mietime tiimin kesken toimistolla, että mitä kivaa voisimme tehdä yhdessä. Pienen brainstorm-session jälkeen päädyimme ideaan, kuinka voisimme hyödyntää IoT -antureita tai koneoppimista meidän omassa toimistoympäristössä.

Demon tarkoitus

Halusimme tehdä demon ihan demomerkityksessä, niin itsellemme, kuin myös asiakkaillemme. Nyt kun IoT-pohjaisia ratkaisuja on tehty Bilotilla muutama, niin halusimme myös kokeilla, kuinka nopeasti ja helposti tällainen nousisi. Alkuvaiheessa kuuntelimme pari vinkkiä kokeneemmilta, mutta aika nopeasti demo-tiimimme pääsi ratkaisun kanssa vauhtiin.

Demon aihe ja rajaus

Päädyimme tekemään palvelun, joka erillisten sensoreiden kautta kerää mittaustietoja neuvotteluhuoneiden ilmasta kahden minuutin välein (lämpötila, kosteus, paine), ja näyttää nämä tiedot kätevässä yhteenvetomuodossa jatkuvasti päivittyvän web-applikaation kautta. Toteutettu versio demosta on katsottavissa täältä: Bilot IoT Demo, ensikäynnistyksellä pitää hetkinen odotella datan latautumista.

Tämän tyyppisen ratkaisun kohdalla tietoteknisiä arkkitehtuurivaihtoehtoja ei tarvinnut kauan puntaroida. Tässä tarvitaan jokin komponentti keräämään ja syöttämään dataa, toinen komponentti tallettamaan datat, kolmas palvelu jakelemaan tallennettu data, ja neljäs esittämään tiedot käyttäjälle kätevässä ja miellyttävässä muodossa.

Lähes yhtä nopeasti meille valkeni oikeat teknologiat: sensoreina käytetään suomalaisen Ruuvi -yhtiön IoT-sensoreita, paikallisena tiedonkeruualustana (ns. ”edge device”) käytetään Raspberry Pi -minitietokonetta, palvelimena meillä on Microsoft Azure ja applikaatio toteutetaan Reactilla.

Toteutus

Palvelin

Aloitimme palvelun rakentamisen keskeltä, eli tarvittavista Azure-palveluista. Pienen selvittelyn jälkeen Azuren tarjonnasta valittiin tähän ratkaisuun käytettäväksi:

  • Azure IoT Hub, jonka kautta määritettiin ulkoiset laitteet millä dataa kerättiin, ja joka ottaa ulkoa lähetetyn datan talteen.
  • Azure Stream Analytics, jota käytettiin lukemaan IoT hubin vastaanottamat mittaustiedot ja kirjoittamaan tiedot tietovarastoon sopivassa muodossa
  • Azure SQL Database, mihin mittaustiedot tallennettiin
  • Azure functions jota käytettiin välittämään haluttuja tietoja käyttöliittymään.

Isommassa ratkaisussa tietovarastona pelkkä Azure SQL Database ei ehkä olisi riittävä, mutta tähän käyttöön se kelpasi hyvin. Muista palveluista poiketen se ei ole ilmainen, mutta tässä tapauksessa edullisimmat versiot riittävät hyvin. Kustannus on alle 12 euroa kuukaudessa.

Varsinaiseksi palvelintoteutukseksi jäi siis IoT -hub -palvelun konfigurointi, SQL-tietokannan ja -taulujen perustaminen, Stream Analytics -palvelun ja siihen liittyvän kyselyn konfiguroiminen ja aplikaatiota palvelevan Azure-funktion laatiminen.

Mittausdatan kerääminen

Ruuvi-yhtiön Bluetooth-sensorit olivat lopulta helppo valinta, verrattuna muihin vastaaviin. Laitteiden saatavuus on hyvä, ne ovat edullisia, ja käyttäjäkunta on aktiivista, joten erilaisia foorumi- ja blogipostauksia oli sopivasti tarjolla.

Sensorit käyttäytyvät Bluetooth-majakoina, eli tällaisen lukemiseksi laitteita ei tarvitse erityisesti parittaa. Mittalaitteet vain lähettävät dataa yltympäriinsä, ja jokainen kantavuusalueella oleva Bluetooth-laite voi tätä signaalia kuunnella. Jossakin käyttötapauksessa tämä saattaa olla turhan huoleton käytäntö, mutta ainakaan demon tapauksessa emme tästä olleet murheissamme.

Lisäksi päädyimme käyttämään niin sanottua ”Edge deviceä”. Termille ei ole kovin vakiintunutta suomenkielistä käännöstä, mutta jonkinlainen ”Reunalaite” se on. Kyseessä on tietynlainen silta, internetiin kytketty laite, joka osaa keskustella Azure IoT Hubin kanssa, ja joka osaa kerätä mittaussensorien lähettämät tiedot. Edge devicen tarve on helppo nähdä tässä tilanteessa, jossa mittalaitteet lähettävät tietonsa vain Bluetoothilla, mutta tällainen välilaite on usein hyödyllinen silloinkin, kun mittaussensorit osaisivat itsekin kytkeytyä internetiin.

Meiltä kun sattui löytymään Raspberry Pi 3 valmiina ja sen käyttöön tässä tarkoituksessa löytyi hyvin ohjeita, niin se oli aika luonnollinen valinta tähän tarkoitukseen.

Seuraavaksi piti ohjelmoida Raspberry-tietokone ottamaan vastaan mittausdataa sensoreilta, ja lähettämään tämä data sopivassa muodossa Azure IoT Hub -palvelulle. Tämänkin olisi voinut tehdä monin keinoin, mutta tässä valitsimme pienimmän vastuksen tien, ja teimme Edge Device -ohjelman Pythonilla. Azuren IoT-palvelu olisi tarjonnut tähän hienompiakin konsteja, jotka olisivat mahdollistaneet Edge devicen etähallinnan ja muutakin, mutta demon vaatimustason kannalta nämä olivat tarpeettomia.

Pythoniin meille taas oli tarjolla valmis ruuvitag-sensor -kirjasto, joka tarjosi paljon aihepiiriin liittyvää toiminnallisuutta valmiina. Lisäksi tarjolle paljastui myös DeviceClient.py -kirjasto, joka tarjoaa metodit tietojen lähettämiseksi Azure IoT Hubille. Python-ohjelmalle syötettiin Azure IoT Hubista saadut tunnistetiedot, jotka toimivat tietojenlähetyksessä tunniste- ja pääsynhallintatietoina. Python-ohjelma ottaa kahden minuutin välein sensorien tiedot talteen, ja lähettää ne IoT Hubille.

(Raspberry Pi -koneeseen olisi voinut asentaa myös Windows 10:n IoT -version, mutta tätä emme kokeilleet. Koneen käyttöjärjestelmänä sai toimia oletuksena asentunut Raspbian.)

Mittausdatan tallentaminen palvelimelle

Koska palvelinpään toiminnallisuus oli tehty jo alkuvaiheessa, varsinaisen kerätyn datan tallennus ei vaatinut kuin pienen tarkastuksen. Raspberry Pi -tietokoneen Python ohjelma keräsi ja edelleen lähetti mittaustiedot aivan odotetusti, joten palvelimella lähinnä riitti todeta tilanne ja katsoa miten mittaustietorivejä ilmestyi tietokantaan.

Mittausdatan julkaiseminen

Palvelimen ja applikaation välinen tietoliikenne toteutettiin tämänhetkisen normaalikäytännön mukaisesti REST-palveluna. Azure-palveluun laadittiin ja asennettiin Azure-funktio, joka palauttaa mittaustiedot JSON -sanomana, kahdessa eri muodossa. Toinen muoto tuottaa suoraviivaisen mittausdatan: mikä lämpötila on milläkin hetkellä kussakin huoneessa ollut, toinen muokkaa mittausriveistä koostedataa, eli päivittäiset keskiarvot jokaisesta huoneesta.

Funktio toteutettiin Visual Studio 2019:lla, joka tarjoaa Azure-funktion valmiina projektityyppinä. Tietokantayhteyttä varten emme ottaneet käyttöön Entity Frameworkia, koska ajattelimme näin suoraviivaisen toteutuksen hoituvan nopsemmin suorilla ADO-kyselyillä. Todennäköisesti EF olisi kuitenkin ollut helpompi, mutta menee se näinkin. Palvelinfunktiota varten emme perustaneet CI/CD -putkea, funktio julkaistaan suoraan Visual Studiosta.

Rajapinnan hallinnan tähden otimme käyttöön Azuren API Management -palvelun, jonka kautta funktiota kutsutaan. API Managementilla pystymme rajoittamaan montako rajapintakutsua suostumme aikayksikön sisällä palvelemaan, ja täten kontrolloimaan resurssien käyttöä ja kustannuksia.

Applikaation suunnittelu ja toteutus

Kuten oikeissakin projekteissa, niin ennen kuin käyttäjäpuolen applikaatiota lähdettiin toteuttamaan, niin ensiksi se piti tietenkin suunnitella. Tässä tapauksessa käyttäjätarpeet kerättiin suoraan tiimistä, koska itsellemmehän me tätä pitkälti teimme. Kun post-iteja oli lätkitty tarpeeksi, niin alettiin sitten rakentelemaan designia Adobe XD:llä ja visuaalisia komponentteja Adobe Illustraattorilla.

Koska React on ollut viime aikoina ahkerassa käytössä, niin siihen Reduxin kanssa päädyttiin JavaScript kirjasto/framework vertailussa lähes automaattisesti.

Applikaation ulkoasun rakentamisessa lähdettiin ensiksi hyödyntämään suosittua React käyttöliittymä frameworkia, Material UI:ta, mutta jotenkin se vain tuntui epäkäytännölliseltä ja saikin poistua lähes saman tien perinteisen SCSS lähestymisen tieltä.

Joitain lisäpaketteja asenneltiin sitten vielä tarpeen mukaan:

  • Recharts osoittautui nopeaksi ja käteväksi graafi-työkaluksi
  • API-kutsut hoidettiin Axioksen avulla
  • Päivämäärien ja kellonaikojen esittämisessä hyödynnettiin js:ää

Yhteenveto

Demo valmistui jopa yllättävän sukkelasti. Azure-palveluiden asennus ja konfigurointi vei työaikaa parilta ihmiseltä noin päivän. Edge-laitteen konfigurointi ja ohjelmointi vei päivän sekin, sisältäen yllättäen eteen tulleen tarpeen opiskella Pythonia. Ensimmäisen toimivan version jälkeen molempia kohtia viimeisteltiin vielä jonkin verran, mutta voimme pää pystyssä todeta tällaisen syntyvän muutamassa päivässä.

Eniten aikaa kului applikaation toteutukseen. Tässäkin tapauksessa ensimmäinen versio syntyi parin päivän työllä, mutta suunnittelun iterointi, responsiivisuus ja käytettävyyden yksityiskohtien hiominen toivat muutamia päiviä lisää ja tuovat vielä jatkossakin, kun kerrankin on ratkaisu minkä käyttöliittymä kehityksessä ei ole mitään rajoitteita ja mihin voi palata aina yhä uudelleen, uusien ideoiden kanssa.

Alkuvaiheessa tehdyt arkkitehtuuri- ja teknologiavalinnat osoittautuivat kaikki hyviksi. Muutama pieni tyyliseikka jäi kaihertamaan, Azure-funktiota varten olisi kuitenkin kannattanut tehdä CI/CD -putki, ja olisi sen Entity Frameworkin voinut myös mukaan ottaa. Edge -laitteen Python-sovellus on myös hieman harrastusprojektihenkinen, tuotantokäyttöön tekisimme hieman viimeistellymmän ja vakaamman toteutuksen, mutta ei tämä nykyinenkään ole käynnistyksensä jälkeen mitään ongelmia tai poikkeuksia aiheuttanut.

Kaiken kaikkiaan ”projekti” oli onnistunut kokonaisuus, jossa muutaman ihmisen pienellä panostuksella saatiin hauska kokonaisuus aikaiseksi, opittiin hieman uutta ja luotiin pohja minkä päälle rakentaa lisää.

Jatkoakin on jo suunniteltu. Tarkoituksena olisi seuraavaksi integroida applikaatioon tieto neuvotteluhuoneiden varaustilanteesta, käyttöasteista jne.

Tämä blogi on kirjoitettu yhteistyössä Erkka Puustin kanssa.


4.11.2019 / News Team

Schweziska Sulzer tillverkar industriella pumpar och övrig utrustning för flödeskontroll. Utöver de fysiska produkterna utgör tjänster en viktig del av utbudet: övervakning, underhåll och reservdelar med anknytning till pumpar, motorer och övriga roterande komponenter.

Sulzer Sense är en nyligen lanserad digital lösning för trådlös, IoT-baserad övervakning av roterande komponenter, med tillhörande mobil- och webbtjänster.

Sulzer och Bilot valde att använda Azure IoT i kombination med SAP Commerce för att ge kunder och servicepersonal tillgång till avancerad analys av komponenters status och servicebehov.

Kom till SAPSA Impuls för att höra Matthew Anderson, Data Analytics and Smart Technologies Manager på Sulzer, presentera Sulzer Sense!

Details:

Date: 4-5 Nov

Venue: Clarion Hotel Sign, Östra Järnvägsgatan 35, Stockholm


30.10.2019 / Esa Vanhanen-Varho

A couple weeks ago Sulzer announced their new wireless condition monitoring system, Sulzer Sense. The service connected new hardware devices created by Treon to the existing SAP customer portal. Our team was responsible for designing and creating the backend to Azure. Naturally, when we are dealing with hardware under development, there came moments when we had to be very agile. But Azure as a platform proved once again to be very flexible.

The rest of this story concentrates on the part I know best – Azure. But naturally very big praise goes also to our SAP CX (E-commerce including Hybris that has been renamed lately) and mobile app teams together with analytics experts for making Sense (pun intended) of the raw…or a bit processed data. And thanks also to all the people at Treon and Sulzer – this was a fun journey together!

TL;DR

Below is the architecture which the rest of the blog discusses. And last week at SAP Finug event the team received the best possible praise from the customer: “If you are looking for partner who can handle SAP ERP, Hybris and Azure, Bilot is the natural choice.”

Solution is built on Azure PaaS & Serverless components which can be easily scaled based on usage. Actual compute section (Functions) scales automatically. And what already proved the scalability was the journey of implementing the solution. There is no maintenance overhead of any virtual machines etc. Some scaling options require currently manual operations, but on the other hand, they are related to growing service and easily monitored metrics & alerts. Naturally, this could be automated too, if the system load would be more random.

If you are interested in this kind of solution, we’d be glad to discuss with you here at Bilot.

Azure Architecture - Sulzer Sense

 

Developing architecture

In the beginning there were multiple choices to be made. Devices are not continuously streaming data but sending samples periodically or when an alert threshold is exceeded. Naturally we had a good idea on the number and size of the messages that the devices would be sending, but not actual data at hand.

Our main principle was that the data processing should be as close to real time as possible – even though this was not a direct requirement. Scheduled frequent runs would have been good enough. But then we would have had to think about how to scale the processing power up when more devices and data needs to be processed. So we decided to use serverless Azure Functions for the actual processing and let the platform scale up as needed and have one less thing to worry about.

The devices communicate to Azure through a separate gateway node that is connected to Azure IoT Hub service. In the first phase device provisioning was manual, but that is currently being automated in the second phase. Also, as only the gateways are directly connected to Azure, the number of gateways is not growing as fast as number of devices behind.

Devices send different types of messages, so next step was to separate these with Stream Analytics service. We had decided to use Cosmos DB as a temporary data storage, because that integrates well with Stream Analytics and Azure Functions and gives us a good access to debug the data. We were unsure in the beginning that would we actually need Cosmos DB in the final solution, but this proved to be exactly what was needed…

Surprise!

When we started receiving the data from devices under development, the first thing we noticed (and had misunderstood from the specifications) that the messages are actually fragmented – one whole message can consist of tens of message fragments. This is the reason why I, an old grumpy integration guy, insist on getting real data as early as possible from a real source – to spot those misunderstandings ASAP. But due to the nature of this development project this just wasn’t possible.

The Wirepas Mesh network the devices use has a very small packet size and the gateway just parses and passes all fragments forward. There is also no guarantee that the fragments are even received in order.

This was a bit of a surprise – but finally not a problem. As we had decided to stream all data to Cosmos DB for debugging, we already had a perfect platform to check and query on the received fragments. We could also use out-of-the-box features like Time to Live (TTL) to automatically clean up the data and prevent id overruns. Some test devices sent data much more often than planned, so this gave us a good insight to system loads. Thus we also used a couple of hours to manually optimize Cosmos DB indexing, after which the request unit consumption (read: price of Cosmos DB) dropped about 80 %.

Now that the data was streamed to Cosmos we tied Azure Functions to trigger on each received message – which turned to be every message fragment. What would be the cost implication on this. Well – only minor. First, we optimized the calculation in a way that we start processing only if we detect that we have received last fragment of a data packet for those data streams where only full data is useful. So most of the processing stops there. Actual calculation & storing of the data happens only for full valid packages. When we measured the used time and memory for the operation, we saw that 1 million message fragments would cost about 0,70 € to process – true power of the serverless! So we are basically getting compute power for free, especially when Functions offer quite a lot of free processing each month…

Naturally we had to add scheduled retries for those rare scenarios where packet ordering has changed. There we used Azure Storage Queues to store events we have to recheck later. Retries are processed with scheduled Azure Functions that just retrigger those messages that couldn’t be completed with first try by updating them in Cosmos DB.

In principle, this work could also be moved to IoT Edge as pre-processing there before sending to Azure would lower the message counts on IoT Hub a lot. In this case, hardware development schedule didn’t make it possible to place IoT Edge on gateway devices on the first phase.

Long term storage

Long term storage was another thing we thought a lot. Cosmos DB is not the cheapest option for long term storage, so we looked elsewhere. For scalar data Azure SQL is a natural place. It allows us to simply update data rows even if scalar data fragments arrive with delays (without having to do the same fragmentation check that stream data uses) and also make sure that some rolling id values are converted to be unique for very long term storage.

During development we naturally had to load test the system. We generated a stored procedure to simulate and create a few years worth of this scalar data (a few hundred million lines). Again this proved to be a great reason to use PaaS services. After we saw that our tester would run for a couple of days in our planned database scale, we could move to a lot more powerful database and finish the test data creation in a few hours – and scale back again. So we saved two development days and finished the data creation in one night by investing about 30 euros.

Part of the data is just a sequence of calculated numbers by the devices themselves. These were not suitable for storing in relational database. We could have used Cosmos, but as discussed, the price would have been probably a bit high. Instead, we decided to store this kind of data directly to Blob Storage. Then it was just a question on how to efficiently return the data for the customer requests. And that could be easily solved with creating a time based hierarchy on the blob storage to easily find the requested data. At least so far it works perfectly even without using Azure Search, which is kept as an option for later use, if needed.

Both long term storages can be easily opened up for data analysts and machine learning use cases.

API for users

So far we have discussed only what happened to the incoming data. But how to expose that to the end users then? In this case we had the luxury of already having a customer portal ready, so all we needed to do was to create APIs for the backend to get the data in a secure way. This was accomplished with API Management in front of more Azure Functions. API Management is also used as a proxy when we need to query some data from the portal’s data API to give serverless Functions platform a single outgoing IP address.

All the database queries, blob searches and different calculations, unit and time zone conversions are executed in the serverless platform, so scaling is not an issue. Functions may occasionally suffer from cold starts and have a small delay for those requests, but there is always the Premium Plan to mitigate that – so far there has been no need for this.

We have also planned for the use of Azure Cache for Redis if we need to speed up data requests and see from usage patterns that some data could be prefetched in typical browsing sessions.

Conclusions

What did we learn – at least we once again confirmed that using platform services is very suitable for this kind of work and leaves so much effort to more important things than maintaining infrastructure. It’s just so easy to test and scale your environment, and even partially automated.

Also the importance of tuning Cosmos DB was clear – that couple of hours tuning session was easily worth a few hundred euros per month in saved running costs.

And that the architecture is never perfect. New services appear and you have to choose the tools you use based on one point in time balancing between existing services and if you dare believe that some services come out of preview in time. But the key here is to plan everything in a way that can be easily changed later, if – and when – more efficient service comes available.

(PS. And really, always prioritize getting real data out of the systems you are integrating as early as possible if you can)


19.09.2019 / Pekka Tiusanen

What Do I Need and How Will It Fit?

What tools for AI/ML should be adopted in my organization and how to integrate advanced analytics in data architecture? Implementations are driven by business cases with various technological requirements. There are plenty of options in the market and different SaaS products have characteristic strengths and weaknesses. Existing architecture is a significant factor in decision making as well.

Limited Use of AI/ML within Reporting Tools

Although programming language support and AI/ML capabilities exist for reporting tools, there are certain limitations and hindrances to them. For example, writing R scripts in Tableau requires one to adopt a product-specific workflow and programming logic.

Reporting software can still be utilized to produce small-scale solutions. One of the common use cases for advanced analytics in reporting is key figure forecasting. URL-based integration also allows to embed AI/ML applications in reporting. For example, interactive Shiny apps ® dashboards can be included in Tableau reports. However, these are minimal implementations.

Shortcomings of Graphical AI/ML Tools

Graphical AI/ML utilities, such Azure ML Studio and RapidMiner, are a step up from reporting tools, but they still lack flexibility that is necessary to fulfil large-scale production requirements. Despite having support for R and Python, this is not the standard way to use graphical tools for AI/ML, which reflects to associated usability.

When it comes to training workloads, adding a powerful computation engine on top of other features has not been sufficient for RapidMiner to remain relevant. This is partially because the industry is taken over by end-to-end design and seamlessly conacatenated cloud products from source to consumption.

Finally, mere REST API model deployment without scalability is often not good enough for real-time implementations. On the contrary, IaaS-based solutions for scaling are too tricky to maintain for many organizations. Such solutions also require extra DevOps programming work compared to standardized cloud products for the purpose.

Microsoft Azure Cloud Platform for Scalability, Power and End-To-End Features

Cloud-based programming environments have invaded the AI/ML scene. These products provide calculation power, scaling features and end-to-end readiness. Model training may necessitate a true computation cannon to be swift enough. Furthermore, it is sometimes required for models to be consumed by X thousands of users with a minimal response time. Reasons to prefer such SaaS or MLaaS (machine learning as a service) solutions over custom applications include cloud platform compatibility, ease of maintenance and standardization.

AI tools

Note: Model training in Spark is available for Azure ML Service. However, Databricks a more comprehensive tool for AI/ML development work.

Azure Databricks – Where Data Science Meets Data Engineering

Demand for large scale training computation loads can be met by employing a Spark-driven tool called Azure Databricks. It supports role-based access control and allows data scientists, data engineers and other people involved to collaborate in advanced analytics projects. Developers can write R, Scala, Python and SQL in Databricks notebooks. The resulting AI/ML modelling pipelines can be scheduled by using Azure Data Factory. Version control is typically managed through Azure DevOps.

Note: Databricks is available in AWS too. 

Real-Time Scenario

Scalability requirements for a large user base and stable real-time performance can be addressed by adding Azure ML Service to the chain of sequentially employed cloud products. A typical way to do this would be deploying the solution to Azure Container Service. Kubernetes clusters are often employed in this scenario, but other deployment targets are supported too. Additional custom features can be built inside the web service.

Batch Scenario

If real-time responses are not required by the AI/ML business case, Azure building blocks can be used to generate a batch forecasting pipeline. This is a common scneario where Azure Databricks trains the AI/ML model and writes a batch of forecasts to a pre-defined table. Once again, Databricks workloads can be scheduled with Data Factory. The forecast table is consumed by a reporting tool, such as Microsoft Power BI.

Concluding Remarks

Although AI/ML development is business case driven, cloud environment for POCs and production solutions is also a strategic asset. Modern cloud-hosted solutions provide means to build production ready advanced analytics pipelines. They can also be extended with additional features stemming from business needs and technological landscape. Some of the early AI/ML adopters may have to shift from custom IaaS solutions towards end-to-end cloud platforms to ensure architecture viability in the long-term.


29.08.2019 / Ilpo Järvinen

Tämä kirjoitus keskittyy Databricksin käytettävyyteen erityisesti Microsoftin Azure-pilviympäristössä.

Moni Microsoft Azuren pilvipalveluja käyttänyt on saattanut törmätä Azure Databricksiin. Databricks onkin kovassa nosteessa. Yhtenä syynä tähän on juuri Databricksin integroituminen osaksi Azure-pilviympäristöä. Tässä kirjoituksessa selvennän, mikä rooli Databricksillä on AI- ja ETL-työkaluna. Lisäksi käyn läpi, mikä Databricks oikeastaan on ja mitä etuja sen integroituminen Azureen tuo tullessaan. Mainittakoon myös, että Databricksin Azure-laajennus on Microsoftin ”first-party service”, minkä vuoksi Databricksin käyttö Azure-ympäristössä on saumatonta ja vastaa yritysmaailman turvallisuusstandardeja.

Databricks pähkinänkuoressa

Databricks tuo käytännössä data science ja data engineering -työskentelyn samaan paikkaan. Kyseessä on siis toteutus, joka mahdollistaa AI-prosessien toteutuksen alusta loppuun. Datan voi ladata useista eri lähteistä, sille voi tehdä transformaatioita, rakentaa mallinnusputkia ja lopulta mallinnusputket voi julkaista tuotantoon useille eri alustoille. Näiden ominaisuuksien avulla Databricks kattaa kaikki AI/ML-toteutuksiin vaadittavat komponentit. Lisäksi se suoriutuu kaikesta tästä erittäin hyvin. Esimerkiksi, datan voi ladata suoraan Databricksiin, tehdä datatransformaatiot SQL-kielellä, opettaa ja tallentaa koneoppimismalleja Pythonilla, ja lopuksi ladata mallit tuotantoon Java tai Scala -formaatissa.

Databricksin ohjelmointiympäristönä toimivat web-pohjaiset Notebookit, jotka muistuttavat monelle datatieteilijälle tuttuja Jupyter Notebookeja. Databricks Notebookit kuitenkin sisältävät vielä lukuisia hyödyllisiä ominaisuuksia, jotka tekevät muun muassa versionhallinnasta sekä tulostaulujen ja diagrammien piirtämisestä erittäin helppoa. Samassa Notebookissa voi käyttää useaa eri ohjelmointikieltä ilman että käyttäjän tarvitsee tehdä minkäänlaista konfigurointia. Notebookit mahdollistavat myös useamman kehittäjän samanaikaisen työskentelyn.

Olennaista on myös, että Databricks on suunniteltu erityisesti big-datan kanssa työskentelyyn. Databricksin ydin on Apache Sparkissa, joka tiivistetysti on suuren datan prosessointiin tarkoitettu laskentamoottori, joka peittoaa muut nopeudellaan, käytettävyydellään ja sovelluskohteidensa laajuudella. Nopeudesta puhuminen veisi turhiin yksityiskohtaisuuksiin, mutta käytettävyyden puolesta vahvuus on Sparkin datataulujen selkeydessä ja siinä, että Spark tarjoaa rajapinnan useaan eri ohjelmointikieleen. Sovelluskohteista muutaman mainitakseni Spark soveltuu datan prosessoinnissa niin eräajoihin kuin striimaukseen eli virtaavan datan prosessointiin, tekoälytoteutuksien rakentamiseen ja SQL-operaatioihin.

Spark – Databricksin ydin

Spark on rinnakkaislaskennan mahdollistava laskentamoottori, jossa laskenta tapahtuu hajautetusti klusterissa. Tämä mahdollistaa laskentaoperaatiot sellaisissa tilanteissa, joissa yksittäisen koneen muisti ei kapasiteetiltaan riittäisi. Juuri tämä tekee Sparkista erinomaisen big-dataan liittyvässä laskennassa.

Käytännössä tämä tekee Sparkin datatauluista erilaisia kuin esimerkiksi Pythonin tai R:n perinteiset datataulut. Sparkin datataulut eivät lepää yhdessä paikassa, vaan ne ovat hajautettu klusterin ylitse. Ominaisuuksiltaan Sparkin datataulut muistuttavatkin pikemminkin tietokantojen tauluja tai Hadoopin hajautettuja tiedostoja.

Spark-tauluille on luotu rajapinta useaan eri kieleen: Pythoniin, Scalaan, R:ään ja SQL:ään. Näistä jonkin (tai useamman) kielen hallitseminen ei kuitenkaan tarkoita saumatonta liukumaa Sparkin käyttämiseen, vaan Sparkin käyttämän taulurakenteen ymmärtäminen ja tauluilla operoiminen vaatii omaa perehtymistä.

Mikään ei tietenkään estä suorittamasta Sparkin avulla operaatioita vaikkapa Pythonilla käyttäen Pandas-kirjaston datataulukoita, mikä voi joissain tilanteissa olla jopa järkevää. Tällöin data on kuitenkin tuomittu lepäämään vain yhdessä klusterin solmussa, jolloin klusterilaskennan hyödyt jäävät saamatta. Sparkin oma taulutyyppi onkin luotu juuri hajautettu laskenta silmällä pitäen. Perinteisiä (Python/R) datataulukoita ei ole suunniteltu tähän.

Spark on myös erittäin hyvä laskentaoperaatioiden optimoinnissa. Sparkin datataulukot tuovat käyttäjälleen sen mukavuuden, että pääasiallisesti laskennan optimointi tapahtuu automaattisesti ilman, että käyttäjän tarvitsee murehtia operaatioiden järjestyksestä tai laskentaresurssien jakamisesta. Toki pieni viilaus on käyttäjän puolesta välillä paikallaan.

Entä sitten Azure Databricks?

Databricks on Apache Sparkin tekijöiden luoma alusta, joka tekee Sparkin hyödyntämisestä helppoa datatieteilijöille ja -insinööreille. Databricks kokoaa kattavan määrän ominaisuuksia yhteen mahdollistaen tekoäly/koneoppimisratkaisujen tekemisen aina datan lataamisesta mallin tuotantovaiheeseen asti. Myös ETL-työt onnistuvat Databricksin avulla.

Sitten on Azure Databricks.

Azure Databricksiä voi ajatella Databricksin ”Azure-laajennuksena”, joka tarjoaa Databricksin integroituna Azure-ympäristöön. Integraation myötä Azure Databricks voi muun muassa hyödyntää Azuren data connectoreita sekä sen sisältämää dataa voi tarkastella Power BI:ssä.

Erityismaininnan arvoinen integraatio on Azure Databricksin soveltuvuus osana Azure Data Factoryn pipelineja eli ETL-putkia. Azure Databricksin notebookit voidaan saumattomasti yhdistää osaksi Azure Data Factoryn pipelinea. Tämä korostaa Azure Databricksin kykyä toimia ETL-työkaluna. Esimerkiksi datan voi pipelinessa koota useista lähteistä Blobiin, jonka jälkeen Azure Databricks tekee datalle halutut transformaatiot ja palauttaa takaisin Blobiin. Viimeisenä vaiheena voi olla esimerkiksi transformoidun datan siirtäminen Blobista SQL-tietovarastoon. Kaikki tämä tapahtuu näppärästi Azure Data Factoryn putkessa.

Ja mitä AI-toteutuksiin tulee, Azure Databricksissä luodut mallit voi rekisteröidä Azure Machine Learning servicen työtilaan, jonka kautta mallit voi julkaista verkkopalveluina. Azure Databricks on siis loistava komponentti osana Azure-pohjaisia ratkaisuja.


3.07.2019 / Esa Vanhanen-Varho

Vuotuinen Integrate-konferenssi pidettiin Lontoossa jo kuukausi sitten. Mukana oltiin tänäkin vuonna kuuntelemassa tuoreimpia uutisia Azuren integraatiopalveluiden ympäriltä, vaikka tiivistelmän kirjoitus piti jättää asiakasprojektien priorisoinnin takia vähän myöhemmäksi.

Avauspäivän työvaatetus oli lauantaisen Champions League -finaalin tuloksen mukaisesti punainen – en tosin syksyllä muistanut, että se ensimmäinen työpäivä pokaalin jälkeen saattoi olla Lontoossa, mutta riittävän tärähtäneenä (kuten kuvakin osoittaa) ja ääni käheänä toteutin sijainnista huolimatta lupaukseni – YNWA 🙂

Mitä itse tapahtumasta jäi käteen – etenkin hieman pidemmällä sulattelulla? Jos vertaa viime vuoden koosteeseeni, niin voisi sanoa, ettei kovin paljon mitään “mullistavaa” – mikä on itse asiassa erinomainen asia, ja kertoo siitä, että teknologiat ovat vakiintuneet ja elävät stabiilissa, vaikkakin nopeassa kehitysrytmissä – mutta ilman jättimäisiä (rikkovia) muutoksia. Kukin palvelu julkaisee uutisiaan ja ominaisuuksiaan vuoden mittaan jatkuvasti eikä enää kertarysäyksellä.

Ehkä tähän kehitysvauhtiin on jo turtunut, sillä jos käy vuoden ajan muutokset läpi blogeista ja videoista, niitä on hirvittävä määrä. Oletusarvo on nykyisin mieluumminkin se, että Microsoft julkaisee Azureen uusia ominaisuuksia kuin liukuhihnalta – ja niiden puuttuminen olisi se iso juttu. Ja suurin osa uusista jutuista on tietysti avointa lähdekoodia…maailma todellakin muuttuu…

Pääviesti on edelleen: uusia integraatioita kannattaa suunnitella “pilvi edellä”, vaikka se BizTalk hyrisisi nurkassa (tai pilvessä) – etenkin, jos uuden liittymän integraatio sisältää valmiin connectorin Logic Appsien puolella tai paljon logiikkaa. Tähän puoleen törmää usein, jos integraatiorajapintana on samat APIt, joita esim. webbisivusto käyttää sisäisestikin. Joskus (ja aika useinkin) tietojen nouto SaaS-järjestelmistä vaatii sellaista logiikkaa, jota en lähtisi missään nimessä muutenkaan implementoimaan BizTalkin sisälle, vaan helpommin ylläpidettävään erilliseen komponenttiin, jota on ketterämpi päivittää tarpeen vaatiessa.

Monitorointi

Tänä vuonna useissa puheenvuoroissa nousi esiin monitoroinnin järjestäminen hajautetussa pilvimaailmassa. Asia on varmasti noussut enemmän esiin käytännön toteutusten lisääntyessä, koska eri komponenttien kautta kulkevia sanomaketjuja voi olla hyvin haasteellista seurata päästä päähän. Sinänsä tuo seuranta on enemmän liiketoimintaongelma, joka pitää ottaa suunnittelussa huomioon: kuka tarvitsee mitäkin tietoa ja millä hetkellä & viiveellä se on hyväksyttävää saada. Jos “vain” operoidaan sanomaliikennettä, tilanne on aivan eri kuin jos liiketoiminnan edustajien tai asiakkaiden pitää päästä näkemään, missä tilassa heidän oma transaktionsa systeemeissä kulkee. Puhumattakaan reaaliaikaisen analytiikan ja koneoppimisen liittämistä integraatioiden välittämään dataan ja/tai niiden valvontaan…

Onneksi Azuren omien palveluiden päälle voi toteuttaa mitä vain. Toki räätälöinnin määrä nousee vaatimusten kasvaessa – mutta kannattaa pitää silmällä myös SaaS-pohjaisia tuotteita, joilla tätä valvontaa voi helpottaa. Konferenssin isäntä (kovai.co) , esitteli luonnollisesti omia tuotteitaan keskittyen etenkin Serverless360:iin, josta saatiin myös pitkän linjan MS-integraatiopuolen tekijöiden esimerkkitoteutuksia. Itseäni viehätti etenkin Serverless360:iin sisäänrakennettu BAM (Business Activity Monitoring) toiminto, johon on mahdollista kerätä tällaista päästä päähän tietoa käytännössä mistä vain ja avata pääsy dataan roolipohjaisesti. Muitakin ratkaisuja markkinoilta löytyy.

Logic Apps

Kehitys jatkuu tasaisen tappavalla vauhdilla monella sektorilla. Niin Logic Appsien connectorien määrä (38 uutta viimeisen puolen vuoden aikana), kuin tulossa olevat uudet ominaisuudet kehitysputkeen (mm. editorit, paremmat ARM-template exportit) sekä operointiin ja turvallisuuteen (salaisten tietojen peittäminen, managed identities, OAuth-pohjainen autentikointi Logic Appsien kutsuihin). SAP connectoriinkin on vihdoin tulossa tuki Commit/Rollback -operaatioille – mitä pikemmin, sen parempi.

Operointia helpottamaan tulee myös loistava uusi ominaisuus, eli virheellisen ajon voi piakkoin käynnistää uusiksi haluamastaan kohdasta (resubmit from action) – nykyisinhän uusiminen on tarkoittanut koko työnkulun uusintaa alusta asti, mikä on voinut tuottaa harmaita hiuksia, jos jokin epätodennäköisen virhetilanteen mahdollisuus on jäänyt aikanaan huomioimatta toteutuksessa.

Sanomajonokäyttöä ajatellen sisäänrakennettu tuki isojen aineistojen käsittelylle (siirretään jonoon tieto siitä, mistä vastaanottaja saa blob storageen tallennetun datan noudettua) on myös aivan loistava asia ja helpottaa jälleen Azuren Service Busin sisäänrakennettujen ominaisuuksien hyödyntämistä näissäkin tapauksissa, joissa mennään tuon suhteellisen pienen 256 kilotavun aineistokoon yli.

Pienen koodin käyttö mahdollistuu myös suoraan Logic Appsien sisällä ilman erillistä funktiota, esiversio tosin tukee vasta JavaScriptiä ja vaatii kk-maksullisen Integration Accountin käyttöä, mutta kielivalikoima on laajentumassa ja jälkimmäisestä riippuvuudesta yritetään päästä eroon ennen varsinaista julkaisua.

Myös oma eristetty ympäristö (ISE = integration service environment) kehittyy koko ajan – varteenotettava vaihtoehto, jos halutaan ennakoida kustannuksia paremmin (etenkin suurten volyymien kohdalla), ajaa integraatioita omien verkkojen sisällä ja vakioidulla suorituskyvyllä & varmasti eristetyllä datalla – muitakin pieniä lisäominaisuuksia on tätä kautta saatavilla. Skaalautuvuutta riittää, mutta listahinta toki lähtee noin 6 euron tuntitasolta (~4400 € / kk) eli ihan pikkutarpeisiin tämä ei toimi kustannustehokkaana ratkaisuna verrattuna “jaetun” puolen transaktiopohjaiseen hinnoitteluun. Kehityspuolen saa kuitenkin pystyyn huomattavasti edullisemmin (runsaat 700 € / kk).

API Management

Tälläkin puolella kehitys on ollut tasaista, mutta yksi ominaisuus oli yli muiden – APIM on ollut tähän asti puhtaasti pilvipohjainen palvelu, mutta nyt siihen on tulossa mahdollisuus ajaa API gatewaytä omassa infrassa. Sitä hallitaan edelleen pilvestä, mutta ajoympäristö voidaan nostaa docker-kontin päälle ilman, että liikennettä tarvitsee reitittää pilven kautta, jolloin esim. matkasta aiheutuvat viiveet saadaan minimoitua. Tämä on kieltämättä ollut suurin puute, jonka vuoksi se ei ole soveltunut kaikkiin asiakastarpeisiin.

Myös kehittäjäportaali uusiutuu modernimmaksi ja samalla varsin ketterän näköiseksi – ja jälleen avoimeen lähdekoodiin perustuvaksi. Portaalia voi kustomoida ja laajentaa todella helposti toisin kuin aiemmin – ja vaikka ohjata kehittäjäportaalin kutsut pienellä muokkauksella ei-tuotannollisiin rajapintoihin.

BizTalk 2020

Ehkä yhtenä isoimmista (mutta hyvin odotettuna) uutisista oli BizTalkin uusimman version tulo loppuvuodesta. Tärkeintä tässä on se, että BizTalk 2016 Enterprise -version Feature Pack -laajennusten pitäisi nyt tulla Standard versioon mukaan. Viime vuonnahan juuri tässä kohtaa tuli kylmä suihku standardin omistajille niskaan ja aikataulu oli täysin pimennossa. Nyt BizTalkin käyttömahdollisuudet helpottuvat näiltäkin osin hybridimallin kannalta. Toki samalla mahdollistuu tuoreimpien SQL & Windows alustojen käyttö.

Tiivistettynä nämä Enterprise-tason aiemmin julkaistut ominaisuudet alla:

  • CI/CD Azure DevOpsin kautta
  • SOAP-rajapintojen suora julkaisu Azuren API Managementtiin (suora tai SOAP-to-REST)
  • Uusia adaptereja: Azure Event Hubs, Office365 -adapterit (Email, Calendar, Contact)
  • BizTalkin hallinta APIen kautta
  • Application Insights / Event Hubs käyttö BizTalkin lokidatalle & Power BI -template lokidatan käsittelylle
  • Kehittyneemmät ajastusmahdollisuudet
  • Varmuuskopiointi Azuren Blob Storageen
  • TLS 1.2 -tuki
  • GDPR (ja FIPS) -muutoksia

Uutena adapterina mukaan olisi tulossa vielä Azuren Blob Storage, mikä on erinomainen lisä palettiin sen helpossa linkittämisessä muihin palveluihin esim. Event Gridin tai funktioiden kautta.

Ja muuta…

Toki kaikki muutkin integraatiopalvelut käytiin läpi – eli messaging-palvelut Service Bus, Event Hubs ja Event Grid. Ja käsiteltiin luonnollisesti myös Azure Functionsin hyödyntämistä näiden palvelujen yhteydessä, mikä on omien kokemusten perusteella erittäin kustannustehokas vaihtoehto.

Microsoft Flow:n roolia nostettiin myös esiin – se ei ole mikään “Logic Appsien pikkuveli” vaan sille löytyy erinomaisia käyttötapauksia, joita ei Logic Appsilla voi suoraan toteuttaa – ja päinvastoin. Oleellista on osata poimia omaan palettiin tarpeen mukaan parhaat palat molemmista työkaluista.

Kun kolmessa päivässä on liki 30 esitystä tuotekatsauksista ja case-esimerkeistä teknisiin detaljeihin, niin antia kyllä riittää. Isäntien omat tiivistelmät kaikista esityksistä (englanniksi) voi käydä lukemassa täältä:

PS. Keskustelen Azuren integraatiopalveluista mielelläni lisää naamatusten tai sähköisesti, jos kiinnostusta tai kysyttävää on. Ainakin loman jälkeen elokuussa – hyvää kesää kaikille!


20.06.2019 / Esa Vanhanen-Varho

Another good example that when using cloud, you must always follow the cost structure of your application. 

Yesterday after checking on one Logic App in development environment with simulated production load, we noticed that about 75 % of it’s cost was coming from history data retention – and no wonder, the default 90 days is a loooooong time for image binaries to be stored. Especially when after completion this binary data is absolutely not required for anything else.

The portal has (as a preview feature) a setting to control data retention time, so just what we needed…setting a smaller value and everything is fine.

…except after next time our release pipeline updated the Logic App, it was back to default setting of 90 days.

But if it gets overwritten, you’ll have to be able to set it somehow in ARM template, right? Unfortunately, a quick search and documentation didn’t help this time. There was only a short Stack Overflow answer on how to set the Hight throughput value above this one – also undocumented feature. But that meant that there is must be an answer.

Derek Li helpfully tipped me to right direction on Twitter:

And so I did press F12 on my browser, changed the value in portal and the answer was in the network trace on this line – just like Derek suggested.

Opening the JSON payload revealed the final answer:

And now I just had to copy-paste the runtimeConfiguration part to the ARM template, under Logic App resource’s properties. Valid setting is from 7 to 90 days like in portal, and you can’t set it smaller in template either – tried it 🙂

But why?

We calculated that this setting change – when it’s automated and not relying on someone to remember to update it manually – will actually save the customer a couple of hundred euros per month. Naturally, by using Azure Functions, we could almost completely eliminate this cost. But this customer prefers Logic App integration workflows, so at least we are now optimizing the costs. So – closing with the same words as I started:

This was another good example that when using cloud, you must always follow the cost structure of your application. 

PS. Thanks also to my ex-colleague Okko Oulasvirta (Twitter: @okkooulasvirta) who seemed to test this same functionality last night about the same time as I did and confirmed my findings on a Finnish Azure slack channel.


28.03.2019 / Esa Vanhanen-Varho

Logic Apps received the long waited response mocking a while ago (link to docs). This is a beginning (and hopefully not the end) where you can return one static response.

In most cases you would probably like to have a capability to dynamically choose which response you get from many, but at least I couldn’t use Logic App expressions to return a specific response based on received payload. The runtimeConfiguration.staticResult object’s properties don’t seem to like expressions…

Working with ARM template parameters

Anyway – a little bit of testing this feature allowed me to do something that may help in some automated or manual test scenarios with the use of ARM template parameters. So I created a parameter containing all possible results (pStaticResults) and one for which result to use (pStaticResultToUse).

    "parameters": {
        "pStaticResultToUse": {
           "type": "string",
           "metadata": {
                "description": "Name of static result to use"
            },
            "defaultValue": ""
        },
        "pStaticResults": {
           "type": "object",
           "metadata": {
                "description": "different static results"
            },
            "defaultValue": {
                "HTTP0": {
                    "outputs": {
                        "body": {
                            "code": "HTTP0"
                        },
                        "headers": {
                            "MyHeader": "MyValue0"
                        },
                        "statusCode": "OK"
                    },
                    "status": "Succeeded"
                },
                "HTTP1": {
                    "outputs": {
                        "body": {
                            "code": "HTTP1"
                        },
                        "headers": {
                            "MyHeader": "MyValue1"
                        },
                        "statusCode": "OK"
                    },
                    "status": "Succeeded"
                }
            }
        }
    }
In the deployment parameter I can now set which result is set active or should we disable the actual result – but disabling requires a bit of tweaking of the Logic App definition JSON because if you try to deploy static result with empty name, it will cause an error:
But if you set the staticResult to the template to point to a non-existing name and at the same time disable result, it will work – so some ARM template functions are needed:
Now I can change the pStaticResultToUse to the response I want deployed: HTTP0, HTTP1 or empty.
When I deploy with static response set to HTTP0 or HTTP1, workflow looks like this:
and with an empty value:
And when I run the requests to it, these are the responses for HTTP0…
…and for HTTP1 it also seems to give the correct response.
With the empty one we naturally get an error as the URL pointed to unknown address:
By doing separate deployments you could automate some mock responses for different tests with this approach. Not nice, but at least a workaround until we get a real dynamic model…

Changing response manually

What I also noticed is that you can manually edit and change the response you get – but only in the code view!

If you modify the response name there, it will save and keep your all your static results.

But if you happen to save your Logic App in designer view, it will delete the other than selected response from the definition.

 

Test templates can be downloaded from here.


21.03.2019 / Esa Vanhanen-Varho

Haven’t really needed to change Logic App parameters without doing a new deployment earlier, but now I had an interesting problem.

I tried to create my first recursive Logic App. Naturally at that point had forgotten that I can solve my problem also with do-while-loop, so recursion is not the main point here – the Logic App’s parameter setting without running ARM deployment is – if you’re interested more in recursion, here are a couple of good posts by Vincent-Philippe Lauzon and François Boucher.

I did my experiment with the latter post’s Method 2 – calling the same Logic App directly with HTTP action pointing to own request URL. You can manually add the URL easily, but how to deploy a new instance with ARM template where circular references are not allowed and listCallbackUrl function is not working…

So the workflow without correct URL is here – it would be easy to save and copy the value from request trigger, but that’s not a way to automate deployment. (Remember to make sure your recursion really works correctly before actually executing it…)

If I try to deploy this from an ARM template that would try get own CallbackUrl like this:

It would only fail miserably:

So, go with parameters…create a Logic App parameter with a placeholder value:

Logic App look now like this:

 

After deployment, Powershell solves the rest:

  1. Get original settings:

    $lapp = Get-AzureRmLogicApp -ResourceGroupName TempLA -Name RecursiveArmTest

  2. Get deployed Logic App’s callback url:

    $newurl = Get-AzureRmLogicAppTriggerCallbackUrl -ResourceGroupName TempLA -Name RecursiveArmTest -TriggerName request

  3. Set Logic App parameter value to deployed callback url from previous step:

    $lapp.Parameters[‘plaSelfUrl’].Value = $newUrl.Value

  4. Update Logic App:

    Set-AzureRmLogicApp -ResourceGroupName TempLA -Name RecursiveArmTest -Parameters $lapp.Parameters

And that’s it – easy to set in your pipeline too (you could actually get the callbackUrl as an output from deployment too without separate PS command). And seemed to work:

The best part of this is that you don’t have to run an ARM template deployment to change those Logic App parameters – which might be very useful for example in updating some API keys in multiple Logic Apps etc…Didn’t find any post around the topic, so maybe this helps someone else too.

ARM templates can be downloaded from this link.