coRona data #3: automatizace na Google cloud platform

Jiri Stepan
Etnetera Activate
Published in
4 min readDec 15, 2020

V přechozím článku jsme si ukázali, jak se dají snadno zpracovat v Rku data. Například o covidu. To je sice pěkné, ale co když chci mít tato data k dispozici každé ráno? A zcela automatizovaně? Spouštět si na počítači RStudio není zase tak zábavné.

Jak zařídit, aby data byla aktualizována a přístupná, třeba v Google Data Studio?

Ukázka z datastudia — vyvoj potvrzených nakažených po dnech v týdnu

Podíváme se, jaké možnosti nám v tomto ohledu nabízí Google Cloud Platform.

Varianta 1: Google cloud engine

Přímočarou metodou je spustit si reálně malou virtuální mašinu s linuxem. Na ní nainstalujeme Rko. A pak nám stačí jednoduchý cron task, který každé ráno spustí skript vytvořený v minulém díle, který data stáhne a uloží do CSV souboru. A pak je spustíme. Skript bude vypadat takto.

Rscript "./prepareData.R"bq --location=EU load --autodetect --replace --source_format="CSV" "activate-data:covid.agregated" ./data.csv

Pro podobný projektík nám stačí i velmi malá virtuální mašinka se shared CPU, která bude stát třeba 10USD měsíčně. To není mnoho, ale pokud bychom podobných datapump dělali více, tak to bude naskakovat. A také nám někde běží server, který je dobré nějak sledovat, aktualizovat atd. Tedy práce.

Varianta 2: Google cloud functions

Google cloud funkce jsou serverless aplikace napsané v Nodejs, Go nebo Pythonu, které škálují dle potřeby. A to dokonce i na nulu pokud je zájem malý. Problémem je, že nepodporují Rko. Takže bychom museli:

  1. Přepsat Rkový skript do pythonu a doplnit nahrání do bigquery. To není těžké, ale je to zbytečná práce.
  2. Obalit jej malým python kódem, který umožní volat funkci jako HTTP trigger.
  3. Nastavit Google Cloud Scheduler, který bude funkci jednou denně volat.

Tato varianta je výhodnější, protože za podobnou cloud funkci spouštěnou jednou denně nezaplatíte nic. Stejně tak se nemusíte starat o provoz, updates apod. Nevýhodou však je nutnost vejít se do podporovaných jazyků a také do timeoutu 540sec, který může být omezující.

Varianta 3: Google cloud run

Google cloud run je relativně nové řešení, které umožňuje spustit Docker kontainer podobným způsobem jako se spouští cloud funkce. Tedy něco mezi variantou jedna a dvě.

Jedná se o plně serverless platformu, která automaticky škáluje. A to až na nulu, pokud nejsou požadavky. Kontejner je možné podobně jako cloud funkce triggerovat pomocí HTTP requestu, pomocí PubSub zprávy či událostí na cloud storage.

Oproti cloud funkci je to ale plnohodnotný Docker container se vším všudy. Tedy včetně třeba toho kýženého Rka. Co je tedy potřeba?

Pokud už máme napsaný bash skript, tak nejprve připravíme Dockerfile. Můj vypadá asi takto:

# Use the Google Cloud SDK image.
FROM google/cloud-sdk
# install Python and
RUN apt-get update && apt-get install -y python3-pip python3
# Install production dependencies.
RUN pip3 install Flask gunicorn
# Install RRUN apt-get install -y dirmngr apt-transport-https ca-certificates software-properties-common gnupg2
RUN apt-get install -y libcurl4-openssl-dev libssl-dev libxml2-dev
RUN apt-get install -y r-base r-base-dev
# Install R packages
RUN R -e "install.packages('dplyr',repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('zoo', repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('jsonlite',repos='http://cran.rstudio.com/')"
RUN R -e "install.packages('rvest',repos='http://cran.rstudio.com/')"
# Copy local code to the container image.ENV APP_HOME /app
WORKDIR $APP_HOME
COPY ./script.sh ./
COPY ./prepareData.R ./
COPY ./app.py ./
# Run the web service on container startup
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 app:app

Jak je vidět, využíváme Google docker image obsahující již všechny cloud SDK. Takže server má nainstalovaný gcloud, bq, gsutils apod. K němu doinstalujeme python a Rko včetně balíčků.

Na konci spouštíme jednoduchý python server s jedinou metodou, která zavolá náš bash skript.

Tento server server App.py je skutečně jednoduchý. Využívá Flask k tomu, aby na portu 8080 vystavil jednoduchou metodu, která spustí bash skript.

import os, subprocess from flask import Flask, request, abortapp = Flask(__name__)@app.route("/", methods=["GET"])
def main():
o = subprocess.run("./script.sh",
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True)
return {"results": o.stdout}
if __name__ == "__main__":
app.run(
debug=True,
host="0.0.0.0",
port=int(os.environ.get("PORT", 8080))
)

A to je vše. Třetím prvkem do skládačky je pochopitelně ten již známý script.sh :

Rscript "./prepareData.R"
bq --location=EU load --autodetect --replace --source_format="CSV" "activate-data:covid.agregated" ./data.csv

A to je vše. Uvedený kontejner sestavíme pomocí:

gcloud builds submit \
--tag eu.gcr.io/$projectid/rcovid \
--disk-size=100GB

Tím v cloud artifactory vznikne Docker image. A následně tento deployneme do služby Cloud run:

gcloud run deploy covidr \
--image eu.gcr.io/$projectid/rcovid \
--platform managed \
--no-allow-unauthenticated \
--region europe-west1

Uvedený příkaz vytvoří službu, která na nějaké adrese čeká na HTTP(S) trigger. Tu si vytvoříme pomocí cloud scheduleru.

Jakmile je služba zavolána, tak kontainer v řádu sekund naskočí, a pokud nedostane další požadavky, opět se po několika minutách uspí. S velkou pravděpodobností se tak vejdete do free tieru služby.

Data vizualizace

Uvedená služba nám každé ráno naplní bigquery tabulku. Takže není nic snazšího, než ji pomocí Data Studia zobrazit a nasdílet celému světu. Třeba jako embedded objekty na medium.com.

Celé Google Data Studio s naším Covid-19 reportem

Odkaz je pak zde: https://datastudio.google.com/s/tnSu0dzTZ24

PS:

Ještě máme jednu variantu — použít místo pythonu webserver přímo v Rku. Dokonce existuje R library, která je určená právě pro podporu běhu Rka nad Cloud Runem.

Bohužel jsem na ni narazil pozdě, takže ji vyzkouším někdy příště.

PPS:

Výše uvedené berte jako demo. Pro produkční prostředí by bylo dobré přidat trochu logování a proces lépe ošetřit. I takto to však krásně funguje.

--

--

Jiri Stepan
Etnetera Activate

Vedu tým skvělých lidí ve firmě Etnetera. A zajímá mne ebusiness, cestování, sci-fi, divadlo, triatlon, ...