Serverite ja teenuste jälgimiseks oleme juba pikka aega edukalt kasutanud Nagios ja Munin põhist kombineeritud lahendust. Siiski on sellel paar puudust, mistõttu kasutame aktiivselt, nagu paljusid teisedki, . Selles artiklis räägime, kuidas minimaalse vaeva korral saab lahendada tulemuslikkuse probleemi, kui jälgitavate mõõdikute arv ja MySQL andmebaasi mahud suurenevad.
Probleemid MySQL andmebaasi kasutamisega koos Zabbixiga
Kuni andmebaas oli väike ja seal salvestatud mõõdikute arv oli väike, oli kõik suurepärane. Zabbixi serveri automaatne protsess housekeeper kustutas edukalt aegunud kirjed andmebaasist, takistades selle kasvamist. Kuid niipea, kui jälgitavate mõõdikute arv kasvas ja andmebaasi maht saavutas teatud suuruse, hakkasid asjad halvenema. Housekeeper ei suutnud andmeid ettenähtud ajaraami jooksul eemaldada ja andmebaasi jäid vanad andmed. Housekeeperi töö ajal tekkis Zabbixi serverile suur koormus, mis võis kesta kaua. Selgeks sai, et olukorda tuleb kuidagi lahendada.
See on tuntud probleem, millega on silmitsi seisnud praktiliselt igaüks, kes on töötanud Zabbixi peal suurte jälgimismahtudega. Lahendusi oli paar: näiteks MySQL asendamine PostgreSQL või isegi Elasticsearchiga, kuid kõige lihtsam ja proovitud lahendus oli üleminek partitiseeritud tabelitele, mis salvestavad mõõdikute andmed MySQL andmebaasis. Otsustasime minna just selle tee.
Üleminek tavalistest MySQL tabelitest partitiseeritud tabelitele
Zabbix on korralikult dokumenteeritud ja tabelid, kus ta säilitab mõõdikud, on teada. Need tabelid on: konsolis, saate nimekirja käskudest, mis on varem teie kontoga täidetud., kus hoitakse float väärtusi, history_str, kus hoitakse lühikesi stringi väärtusi, history_text, kus hoitakse pikki tekstiväärtusi ja history_uint, kus hoitakse täisarve. On olemas ka tabel trends, mis salvestab muutuste dünaamikat, kuid me otsustasime seda mitte puutuda, kuna selle suurus on väike ja hiljem tuleme selle juurde tagasi.
Üldiselt oli selge, millised tabelid tuleb töödelda. Otsustasime teha jaotisi iga nädala jaoks, välja arvatud viimane, põhinedes kuu numbritel, st neli jaotust kuus: 1. kuni 7., 8. kuni 14., 15. kuni 21. ja 22. kuni 1. (järgmisel kuul). Raskuseks oli see, et vajalikud tabelid tuli muuta jaotistesse "lennu ajal", katkestamata Zabbix Serveri tööd ja andmete kogumist.
Kuidas imekombel, tuli meile appi tabelite andmestruktuur. Näiteks tabel konsolis, saate nimekirja käskudest, mis on varem teie kontoga täidetud. omab järgmist struktuuri:
`itemid` bigint(20) unsigned NOT NULL,
`clock` int(11) NOT NULL DEFAULT '0',
`value` double(16,4) NOT NULL DEFAULT '0.0000',
`ns` int(11) NOT NULL DEFAULT '0',samal ajal
KEY `history_1` (`itemid`,`clock`) Nagu näeme, kantakse iga meetrika lõpuks tabelisse, milles on kaks meie jaoks väga olulist ja mugavat välja itemid ja clock. Seega saame üsna hõlpsalt luua ajutise tabeli, näiteks nimega history_tmp, seadistada selle jaoks jaotuse ja seejärel kanda kõik andmed tabelist konsolis, saate nimekirja käskudest, mis on varem teie kontoga täidetud., seejärel nimetada tabel konsolis, saate nimekirja käskudest, mis on varem teie kontoga täidetud. ja history_old, ja tabel history_tmp ja konsolis, saate nimekirja käskudest, mis on varem teie kontoga täidetud., pärast mida saame lisada andmed, mis meil jäi kantamata tabelist history_old ja konsolis, saate nimekirja käskudest, mis on varem teie kontoga täidetud. ja kustutada history_old. Seda saab teha täiesti ohutult, me ei kaota mitte midagi, sest ülaltoodud väljad itemid ja clock tagavad konkreetse meetrika sidumise konkreetse ajaga, mitte mingi järjestikuse numbriga.
Ülemineku protseduur
Tähelepanu! Väga soovitatav on enne mingite tegevuste alustamist teha andmebaasi täielik varukoopia. Me kõik oleme elavad inimesed ja võime teha käsureas vigu, mis võivad viia andmete kadumiseni. Jah, varukoopia ei garanteeri maksimaalset ajakohasust, kuid parem on see kui mitte midagi.
Nii et, me ei lülita midagi välja ega peata. Peamine on, et MySQL serveris oleks piisavalt vaba ketta ruumi, st et iga ülaltoodud tabeli jaoks konsolis, saate nimekirja käskudest, mis on varem teie kontoga täidetud., history_text, history_str, history_uint, oleks vähemalt piisavalt ruumi tabeli loomiseks, mille sufiks on "_tmp", arvestades, et selle maht on sama kui algse tabeli maht.
Me ei kirjuta kõike mitmeid kordi iga ülaltoodud tabeli jaoks ja vaatame kõike vaid ühe näite põhjal — tabeli konsolis, saate nimekirja käskudest, mis on varem teie kontoga täidetud..
Nii et, loome tühja tabeli history_tmp tabeli struktuuri põhjal konsolis, saate nimekirja käskudest, mis on varem teie kontoga täidetud..
CREATE TABLE `history_tmp` LIKE `history`;Loome vajalikud partitsioonid. Näiteks teeme seda kuuks ajaks. Iga partitsioon luuakse partitsioneerimise reegli alusel, mis põhineb välja väärtusel clock, mida me võrreldame ajatempli puhul:
ALTER TABLE `history_tmp` PARTITION BY RANGE( clock ) (
PARTITION p20190201 VALUES LESS THAN (UNIX_TIMESTAMP("2019-02-01 00:00:00")),
PARTITION p20190207 VALUES LESS THAN (UNIX_TIMESTAMP("2019-02-07 00:00:00")),
PARTITION p20190214 VALUES LESS THAN (UNIX_TIMESTAMP("2019-02-14 00:00:00")),
PARTITION p20190221 VALUES LESS THAN (UNIX_TIMESTAMP("2019-02-21 00:00:00")),
PARTITION p20190301 VALUES LESS THAN (UNIX_TIMESTAMP("2019-03-01 00:00:00"))
); See käsk lisab partitsioneerimise meie loodud tabelile history_tmp. Täpsustame, et andmed, mille välja väärtus clock on väiksem kui «2019-02-01 00:00:00», satuvad partitsiooni p20190201, seejärel andmed, mille välja väärtus clock on suurem kui «2019-02-01 00:00:00», aga väiksem kui «2019-02-07 00:00:00», satuvad partitsiooni p20190207 ja nii edasi.
Oluline märkus: Mis juhtub, kui meie partitsioneeritud tabelis ilmnevad andmed, mille välja väärtus clock on suurem või võrdne «2019-03-01 00:00:00»? Kuna nendele andmetele ei ole sobivat partitsiooni, ei satu need tabelisse ja kaovad. Seetõttu peate meeles pidama, et luua õigeaegselt täiendavaid partitsioone, et vältida selliste andmete kadumist (millest räägitakse allpool).
Nii, ajutine tabel on valmis. Laeme andmed üles. Protsess võib võtta üsna kaua aega, kuid õnneks ei blokeeri see muid päringuid, seega peab lihtsalt kannatust varuma:
INSERT IGNORE INTO `history_tmp` SELECT * FROM history;Pöördvõti IGNORE ei ole algses laadimises kohustuslik, kuna tabelis andmeid ei ole, kuid see on vajalik andmete täiendavaks laadimiseks. Samuti võib see osutuda kasulikuks, kui pidite andmete laadimise protsessi katki jätma ja uuesti alustama.
Seega, pärast teatud aega (võib-olla isegi mitu tundi) on esimene andmete laadimine toimunud. Nagu arvata võib, sisaldab nüüd tabel history_tmp mitte kõiki andmeid tabelist konsolis, saate nimekirja käskudest, mis on varem teie kontoga täidetud., vaid ainult neid, mis olid selles hetkel, kui päring hakkas toimuma. Siin on teil valik: kas teha veel üks voor (kui laadimisprotsess kestis kaua), või minna kohe tabelite ümbernimetamise juurde, millest allpool räägiti. Räägime esmalt teisest voorust. Esiteks peame mõistma viimase sisestatud salvestuse aega history_tmp:
SELECT max(clock) FROM history_tmp;Oletame, et saite: 1551045645. Nüüd kasutame saadud väärtust teisel andmete laadimise läbimisel:
INSERT IGNORE INTO `history_tmp` SELECT * FROM history WHERE clock>=1551045645;See läbimine peaks lõppema oluliselt kiiremini. Kuid kui esimene läbimine kestis tunde, ja teine kestab samuti kaua, võib osutuda õigeks teha ka kolmas läbimine, mis toimub täiesti sarnaselt teisele.
Lõpus teeme jälle operatsiooni viimase sisestamise aega saamiseks history_tmp, tehes:
SELECT max(clock) FROM history_tmp;Oletame, et olete saanud 1551085645. Salvestage see väärtus — see on meile vajalik doseerimiseks.
Ja nüüd, kui esmane andmete laadimine history_tmp on lõppenud, alustame tabelite ümbernimetamisega:
BEGIN;
RENAME TABLE history TO history_old;
RENAME TABLE history_tmp TO history;
COMMIT; Oleme vormistanud selle ploki ühe tehinguna, et vältida andmete sisestamise hetke mittetäielikku tabelisse, sest pärast esimest RENAME'i ja enne teise RENAME'i täitmist, tabel konsolis, saate nimekirja käskudest, mis on varem teie kontoga täidetud. ei eksisteeri. Kuid isegi kui RENAME'i operatsioonide vahel saadakse mõningaid andmeid, ja tabelit endiselt ei ole (üleskutse tõttu), saame me väikse hulga sisestamisvigu, millega saab ignoreerida (meil on jälgimine, mitte pank). konsolis, saate nimekirja käskudest, mis on varem teie kontoga täidetud. Nüüd on meil uus tabel
partitsioneerimisega, kuid selles puuduvad andmed, mis saadi viimase andmete sisestamise käigus tabelisse konsolis, saate nimekirja käskudest, mis on varem teie kontoga täidetud. . Kuid need andmed on meil tabelis history_tmpja me täiendame need sealt. Selleks vajame eelnevalt salvestatud väärtust 1551085645. Miks me selle väärtuse salvestasime, mitte kasutasime maksimaalset laadimisaega juba praegusest tabelist history_old INSERT IGNORE INTO `history` SELECT * FROM history_old WHERE clock>=1551045645; konsolis, saate nimekirja käskudest, mis on varem teie kontoga täidetud.? Потому что новые данные уже в неё поступают и мы получим неверное время. Итак, дозаливаем данные:
Pärast selle operatsiooni lõppemist on meil uues, partitsioneeritud tabelis kõik andmed, mis olid vanas, pluss need, mis saabusid pärast tabeli ümbernimetamist. Tabel konsolis, saate nimekirja käskudest, mis on varem teie kontoga täidetud. ei ole meile enam vajalik. Saame selle kohe kustutada või enne kustutamist teha sellest varukoopia (kui teil on paranoia). history_old Kogu ülaltoodud protsess tuleb korrata tabelite jaoks
Mida on vaja Zabbix Serveri seadetes parandada. history_str, history_text ja history_uint.
Что нужно поправить в настройках Zabbix Server
Nüüd langeb andmebaasi hooldus, sealhulgas andmeajaloo osas, meie õlgadele. See tähendab, et Zabbix ei pea enam vanu andmeid kustutama — me tegeleme sellega ise. Selleks, et Zabbix Server ei püüaks andmeid ise puhastada, peate minema Zabbixi veebiliidesesse, valima menüüs 'Haldus', seejärel alammenüüs 'Üldine' ning seejärel paremal väljal allalaadimise nimekirjas valima 'Ajaloo puhastus'. Ilmuvatel lehtedel peate eemaldama kõik märgised rühmas 'Ajaloos' ja vajutama nuppu 'Ainult'. See takistab meil edasist vajadust tabelite puhastamise järele. ajalugu* koos housekeeperiga.
Pange tähele, et sama lehe peal on rühm 'Muutuste dünaamika'. See on just see tabel, trends, mille juurde me lubasime tagasi pöörduda. Kui sellel on liiga palju andmeid ja see vajab partitsioneerimist, eemaldage märgised ka sellest rühmast, ja siis töötlege seda tabelit täpselt samamoodi nagu eelnevalt tabelite puhul. ajalugu*.
Edasine andmebaasi hooldamine
Nagu varem öeldud, on partitsioneeritud tabelitel nõuetekohaseks tööks vajalik partitsioonide õigeaegne loomine. Seda saab teha järgmiselt:
ALTER TABLE `history` ADD PARTITION (PARTITION p20190307 VALUES LESS THAN (UNIX_TIMESTAMP("2019-03-07 00:00:00")));Lisaks, kuna oleme loonud partitsioneeritud tabelid ja keelanud Zabbix Serveril neid puhastada, on vanade andmete kustutamine nüüd meie mure. Õnneks ei ole siin mingeid probleeme. See toimub lihtsalt partitsiooni kustutamisega, mille andmed me enam ei vaja.
Näiteks:
ALTER TABLE history DROP PARTITION p20190201;Erinevalt DELETE FROM operaatoritest, kus on määratud kuupäevavahemik, täidetakse DROP PARTITION paari sekundi jooksul ja ei tekita ühtegi koormust, server ja töötab probleemideta ka juhul, kui kasutatakse MySQL replikatsiooni.
Kokkuvõte
Kirjeldatud lahendus on aja jooksul tõestatud. Andmemaht kasvab, kuid märkimisväärset jõudluse langust ei ole täheldatud.
Allikas: habr.com
