Difference between revisions of "Metrics and Monitoring in swarm"

From berki WIKI
Jump to: navigation, search
(Metrika a Prometheus-ban)
(Honnan jön a metrika)
Line 61: Line 61:
  
  
Java-ban nagyon egyszerűen szolgáltathatunk metrikákat az alkalmazásunkból a Prometheus client library-val. Van hozzá Maven dependency. Abba az osztályba, ami a dependenciát szolgáltatja, majd egy statikus konstruktorral inicializáljuk a Prometheus metrika gyűjtőt. Az alábbi példában inicializálnunk egy '''my_library_request_total''' metrikát, ami fölé a http metrika lekérdezésben egy #-val oda lesz írva a help szöveg: "Total request" (ezt nem veszi figyelembe a prometheus). A metrikához hozzáadtunk a '''method''' nevű címét.  
+
Java-ban nagyon egyszerűen szolgáltathatunk metrikákat az alkalmazásunkból a Prometheus client library-val. Van hozzá Maven dependency. Abba az osztályba, ami a metrikát szolgáltatja, egy statikus konstruktorral inicializáljuk a Prometheus metrika gyűjtőt. Az alábbi példában inicializálnunk egy '''my_library_request_total''' metrikát, ami fölé a http metrika listában egy #-val oda lesz írva a help szöveg: "Total request" (ezt nem veszi figyelembe a Prometheus). A metrikához hozzáadtuk a '''method''' nevű címét.  
 
<source lang="java">
 
<source lang="java">
 
class YourClass {
 
class YourClass {
Line 93: Line 93:
 
context.addServlet(new ServletHolder(new MetricsServlet()), "/metrics");
 
context.addServlet(new ServletHolder(new MetricsServlet()), "/metrics");
 
</source>
 
</source>
 
  
 
==Metrika típusok==
 
==Metrika típusok==

Revision as of 21:00, 14 August 2018

<< Back to Docker main


Mi az a metrika

A metrika egy fajta speciális loggolás, amit a metrikát szolgáltató rendszer nem egy log fájlba ír, hanem biztosít egy HTTP API-t, amin keresztül a metrikát feldolgozó szolgáltatás le tudja azt periodikusan kérdezni. A metrika név-érték párok listája, aminek a jelentése bármi lehet ami időben változik. A metrika listában minden egyes metrika jelentését a metrikát szolgáltató rendszernek kell definiálnia. Pl egy node-on lévő elérhető maradék memóriát jelképezheti a következő metrika:

node_memory_MemAvailable 210

A metrika értéke lehet szám, string vagy logikai érték is.


A metrikákat minden rendszerben, szervezetben vagy swarm cluster-ben egy központi egység kérdezi le és gyűjti össze a saját adatbázisában. A metrikát összegyűjtő rendszerben aztán lekérdezéseket írhatunk fel a metrikákra, aminek az eredménye alapján aztán automatizált folyamatokat indíthatunk be, mint pl a swarm cluster méretének megváltoztatása, alert küldése sms-ben, emailben. Tehát a metrikák a hagyományos log fájlokkal ellentétben a baj valós idejű detektálására, vagy sokkal inkább a baj elkerülésére szolgálnak. Ebből kifolyólag a logokkal ellentétben a metrikák élettartalma nagyon rövid, tipikusan olyan lekérdezéseket szoktunk írni, ahol a lekérdezett metrikák kora nem több mint 10 perc, de inkább pár perc, hiszen itt mindig valaminek az időben történő változására vagyunk kíváncsiak. Így nem olyan kritikus a metrikák elvesztése mint a hagyományos log fájloké, amik tipikusan offline elemzésre szolgálnak, ha a baj már bekövetkezett.


A metrikákat úgynevezett time-series (idősor) adatbázisban kell letárolni (TSDB), vagyis egy adott metrikához nyilván van tartva minden lekérdezéshez az akkor kapott érték. Ez a speciális struktúra ugyan letárolható lenne hagyományos adatbázis kezelőkben is, de nagyon nem lenne hatékony a bennük való keresés. Léteznek direkt erre a speciális adatmodellre készült adatbáziskezelők, amik rettentő hatékonyan tudnak keresni a time-series adatokban. Egy adott metrika tárolását egy listaként lehet elképzelni, ahol a lista elemek az időbélyegekkel vannak indexelve, és a listaelem tárolja az adott időpillanathoz (amikor a lekérdezés történt) a metrika értékét. A főbb time-series db-k:

  • InfluxDB:
  • Prometheus
  • Graphite
  • OpenTSDB
  • KairosDB

...

Fontos, hogy a time-series db számára a metrika csak egy név-érték pár (egy string amihez tartozik egy érték), tehát a TSDB nem értelmezi a kapott metrikát, a lekérdezéseket úgy kell megírni, hogy legyen értelme a háttérrendszerre vonatkozóan. Tehát mikor megtervezzük a lekérdezéseinket a TSDB-ben, akkor elsőként a metrikát szolgáltató rendszer specifikációját kell megnézni, hogy az milyen metrikákat szolgáltat magáról, és melyiknek pontosan mi a jelentése.


A time-series adatbáziskezelő (TSDB) folyamatosan gyűjti a különböző komponensek metrikáit, és minden egyes begyűjtés után ki fogja értékelni a különböző metrikákra felírt lekérdezéseket, amik általában abból állnak, hogy egy time-series lekérdezés eredményét összeveti egy értékkel vagy logika változóval, és a végeredmény vagy igaz vagy hamis. Ha a végeredmény igaz, akkor a time-series adatbáziskezelő riasztást fog generálni (beindít egy automatizált folyamatot), ha a kiértékelés hamis, akkor meg nem fog semmit csinálni. A riasztás hatására küldhetünk emial-t, végrehajthatunk egy bash script-et... stb.


TSDB használatával lehet a swarm cluster egészségét automatizált módon monitorozni vagy akár dinamikusan változtatni a worker node-ok mennyiségét. Pl felírhatunk különböző szabályokat a node-ok leterheltségére. Ha a node-ok valamilyen metrika mentén túlságosan leterheltek, akkor újabb node-okat állítunk automatikusan üzembe, ha meg a terhelés túl alacsony ugyan ezen metrika alapján, akkor meg bizonyos node-okat megszüntetünk.


Mi innentől kezdve csak a Prometheus-ra fogunk fókuszálni.

Prometheus felépítése

Címkék, plusz dimenziók

A Prometheus szabványú metrikában további dimenziókat lehet bevezetni minden metrikához úgynevezett metrika címkékkel, amiket a metrikát szolgáltató rendszer (pl egy apache) hozzáfűz a metrika nevéhez. A címkék tehát tovább specializálnak egy metrikát, pl egy http proxy a proxy_http_request_total nevű metrikával mondhatja meg, hogy a lekérdezési időpontjáig hány kérés érkezett a proxy-hoz. De ezt tovább specializálhatja címkék bevezetésével. Az alábbi példában a method és a status címéket használta a proxy a proxy_http_request_total metrika finomításához. Az alábbi példában tehát a metrika értéke nem az összes request-re vonatkozik, csak azokra amiket GET-el kértek le, és amiknek 200-as volt a státusza.

proxy_http_request_total{method="GET", status="200"} 13


A valóságban ez úgy nézne ki a metrikát szolgáltató rendszer által gyárott metrika listában, hogy sorba jönne az összes variáció egymás után, pl:

...
proxy_http_request_total{method="GET", status="200"} 13
proxy_http_request_total{method="GET", status="500"} 12
proxy_http_request_total{method="POST", status="200"} 30
proxy_http_request_total{method="POST", status="300"} 20
...


Fontos, hogy a címkének is a metrikát szolgáltató rendszer ad jelentést, a time-series adatbázis kezelő számra (a mi esetünkben Prometheus) a metrika és a benne lévő címkék is csak név érték párok. Azonban a címke és annak az értéke is részei a metrika nevének. Tehát a metrikát az összes címéjével együtt felfoghatjuk egy string-nek, aminek van egy értéke. A time-series adatbázisokban a címkék segítségével nagyon trükkös lekérdezéseket lehet felírni, amiket a time-series adatbázis nagyon hatékonyan meg tud keresni.


Honnan jön a metrika

Metrikát magáról nagyon sok rendszer tud szolgáltatni, pl a Traefik reverse proxy, vagy ahogy azt majd látni fogjuk, akár a docker daemon is képes metrikákat szolgáltatni saját magáról. Általában a metrika lekérdezésére egy http interfészt biztosít a metrikát adó rendszer, amit a /metrics URL-en lehet elérni. A http interfészek esetében PULL metrika begyűjtésről beszélünk, vagyis a Prometheus (vagy bármelyik másik TSDB) a konfigurációja alapján periodikusan (pár másodpercenként) meghívja a megfelelő URL-t, ahol visszakapja az aktuális metrika listát (név-érték párokat), amit beír az adatbázisba. Léteik PUSH alapú metrika gyújtés is.


A Prometheus 4 nyelven is ad API-t metrika szolgáltatás írására: Go, Java, Python, Ruby.
https://prometheus.io/docs/instrumenting/clientlibs/

Tehát továbbra sem a Prometheus szolgáltatja metrikát, a Prometheus csak összegyűjti azt, de a kezünkbe ad egy API-t, amivel a saját rendszerünkbe nagyon könnyen építhetünk metrika szolgáltató interfészt.


Java-ban nagyon egyszerűen szolgáltathatunk metrikákat az alkalmazásunkból a Prometheus client library-val. Van hozzá Maven dependency. Abba az osztályba, ami a metrikát szolgáltatja, egy statikus konstruktorral inicializáljuk a Prometheus metrika gyűjtőt. Az alábbi példában inicializálnunk egy my_library_request_total metrikát, ami fölé a http metrika listában egy #-val oda lesz írva a help szöveg: "Total request" (ezt nem veszi figyelembe a Prometheus). A metrikához hozzáadtuk a method nevű címét.

class YourClass {
  static final Counter requests = Counter.build()
     .name("my_library_requests_total").help("Total requests.")
     .labelNames("method").register();
  
  void processGetRequest() {
    requests.labels("get").inc();
    // Your code here.
  }
}

Ahányszor meghívjuk a processGetRequest() metódust, a fenti method="get" megcímkézett változatához hozzá fog adni egyet.


A lekérdezésben így nézne ki:

#Total requests.
my_library_requests_total{method="get"} 23


Aztán meg pl egy HTTP servlet-el tudjuk szolgáltatni a metrikát:

Server server = new Server(1234);
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
server.setHandler(context);

context.addServlet(new ServletHolder(new MetricsServlet()), "/metrics");

Metrika típusok

https://prometheus.io/docs/concepts/metric_types/
A Prometheus 4 féle metrika típust definál, de ezek csak az API szinten vannak megkülönböztetve, a Prometheus-ban már nincsenek, ott nekünk kell tudni, hogy értelmes e amit felírunk szabály az adott metrikára.

ImportantIcon.png

Note
Ugyan a Prométeusz adatbázis nem tesz különbséget a metrika típusok között, fontos megérteni a 4 alaptípus közötti különbséget, mert a Prometheus API igen is megkülönbözteti őket és egyedi név és formátum konvenciót alkalmaz rájuk. Így kapásból érthetjük hogy mit jelenthet egy bonyolultabb nevű metrika, amit egy adott rendszer szolgáltat a Prometheus-nak


Gauge (ɡeɪdʒ)

A Gauge (mérő) a legegyszerűbb metrika a Prometheus-ban, ez egy egyszerű mérőszám, aminek fel és le is mehet az értéke, pl memória használat.

Counter

A számláló a második legegyszerűbb metrika fajta. A számlálónak csak nőhet az értéke, vagy reset-kor visszavált 0-ra. Persze ennek betartását a Prometheus nem ellenőrzi, számára ugyan olyan név-érték pár a számláló típusú metrika is mint bármelyik másik. Ha a hivatalos Java API-t használjuk az alkalmazásunkban, akkor ez az API biztosítja ennek a betartását. Pl:

# TYPE builder_builds_failed_total counter
builder_builds_failed_total{reason="build_canceled"} 0


Histogram

http://linuxczar.net/blog/2017/06/15/prometheus-histogram-2/
https://statistics.laerd.com/statistical-guides/understanding-histograms.php
http://www.leanforum.hu/index.php/szocikkek/167-hisztogram-2
Fontos kifejezések:
distribution=eloszlás
latency=eltelt idő az input és az output között bármilyen rendszerben
frequency=gyakoriság


Mi az a Hisztogram: A Hisztogram a gyakoriság eloszlást mutatja meg a mintának, amivel sokszor sokkal többre lehet menni, mint a hagyományos pl érték-idő diagramokból. A hisztogram egy minta elemzését segítő egyszerű statisztikai eszköz, amely a gyűjtött adatok (minta) alapján következtetések levonására ad lehetőséget. A hisztogram tulajdonképpen egy oszlopdiagram, amely X-tengelyén a tulajdonság osztályok (egy változó különböző értékei), Y-tengelyén pedig az előfordulási gyakoriságok találhatók. A hisztogram megmutatja az eloszlás alakját, középértékét és terjedelmét.

Nézzünk egy példát, hogy hogyan készül a hisztogram. Ha van egy mintám, amiben emberek korai vannak benne:

 36	25	38	46	55	68	72	55	36	38
 67	45	22	48	91	46	52	61	58	55

Ahhoz hogy ebből hisztogramot tudjunk készíteni (gyakorisági eloszlást), a minta elemeit úgynevezett osztályokba kell sorolni (bins vagy buckets), ami azt jelenti, hogy a folyamatos minta értékkészletet felvágjuk (általában egyenlő méretű) sávokra (x tengely), és megnézzük, hogy egy sávba hány minta elem tartozik (y tengely). A fenti példában az értékkészlet az emberek kora, amiben egy osztály (bin, bucket), amibe be akarjuk sorolni a mintákat, legyen 10 év, és induljon 20-tól és menjen 100-ig. Fontos, hogy a Hisztogramban az osztályok (buckets) mindig összeérnek, nem lehetnek benne lukak (Az hogy 10-re vettük az osztály méretét, ez a mi egyéni döntésünk volt, bármilyen más felosztást is választhattunk volna). Most nézzük meg, hogy egy osztályba (bucket) hány elem kerül, vagyis hogy pl a 40-től 50-ig terjedő osztályba hány ember kerül bele. Tehát a 40-50 osztályban a gyakoriság = 4.

Bin	Frequency	Scores Included in Bin
20-30	    2	                 25,22
30-40	    4	              36,38,36,38
40-50	    4	              46,45,48,46
50-60	    5	             55,55,52,58,55
60-70	    3	                68,67,61
70-80	    1	                   72
80-90	    0	                   -
90-100	    1	                   91

Ábrázoljuk a kapott eredményeket:

ClipCapIt-180812-233231.PNG


Osztályok (vödrök, bucket) meghatározása: Azt hogy egy osztály (vödör, bucket, bin) mérete mekkora legyen arra nincs ökölszabály. Ne legyen túl kicsi, mert akkor túl sok oszlop lesz a grafikonon, de ne is legyen túl nagy, mert akkor meg túl kevés, és az eloszlási görbét nem lehet majd jól látni. Ezt pl kísérleti úton lehet meghatározni.


Hisztogram fajták:

  • Normál Hisztogram: Ezt láthattuk a fenti példában. Minden egyes osztályhoz tartozó oszlop azt mutatja meg, hogy a mintából hány darab tartozik az adott osztályba (a példában hány ember tartozik egy adott idősávba)
  • Cumulative Histogram: itt az a különbség, hogy egy osztályhoz tatozó oszlop nem csak azt mutatja meg, hogy hány elem tartozik oda a mintából. A Cumulative Histogram-ban minden oszlop az összes előző oszlop összege (összes előző gyakoriság összege) + az adott osztályhoz tartozó gyakoriság
ClipCapIt-180812-234346.PNG
ImportantIcon.png

Note
A Prometheus cumulative Histogram-ot használ


Histogram metrikák a Prometheus-ban:


Summary

Prometheus architektúra