Volám sa Igor Sidorenko, som technický líder v tíme adminov, ktorí spravujú celú infraštruktúru Domclick.
Chcem sa podeliť o svoje skúsenosti s nastavením distribuovaného úložiska dát v Elasticsearch. Pozrieme sa na to, aké nastavenia na uzloch sú zodpovedné za distribúciu shardov, ako funguje a funguje ILM.
Tí, ktorí pracujú s protokolmi tak či onak, čelia problému dlhodobého skladovania na neskoršiu analýzu. V Elasticsearch to platí obzvlášť, pretože všetko bolo nešťastné s funkčnosťou kurátora. Verzia 6.6 zaviedla funkčnosť ILM. Pozostáva zo 4 fáz:
Hot - Index sa aktívne aktualizuje a dopytuje sa.
Teplý – Index už nie je aktualizovaný, ale stále sa naňho dopytuje.
Studené – Index sa už neaktualizuje a dopytuje sa len zriedka. Informácie musia byť stále vyhľadateľné, ale dopyty môžu byť pomalšie.
Odstrániť – Index už nie je potrebný a možno ho bezpečne odstrániť.
Tieto nastavenia sú individuálne, všetko závisí od miesta na uzloch, počtu indexov, logov atď. Denne máme 2-3 TB dát.
5 dní - Horúca fáza (8 hlavných / 1 replika).
20 dní - Teplá fáza (shrink-index 4 hlavné / 1 replika).
90 dní – studená fáza (freeze-index 4 hlavné / 1 replika).
120 dní - Odstrániť fázu.
Nastavenie Elasticsearch
Ak chcete distribuovať zlomok medzi uzlami, potrebujete iba jeden parameter:
horúco- uzly:
~]# cat /etc/elasticsearch/elasticsearch.yml | grep attr
# Add custom attributes to the node:
node.attr.box_type: hot
Teplý- uzly:
~]# cat /etc/elasticsearch/elasticsearch.yml | grep attr
# Add custom attributes to the node:
node.attr.box_type: warm
Studený- uzly:
~]# cat /etc/elasticsearch/elasticsearch.yml | grep attr
# Add custom attributes to the node:
node.attr.box_type: cold
Nastavenie Logstash
Ako to celé funguje a ako sme túto funkciu implementovali? Začnime získaním prihlásení do Elasticsearch. Existujú dva spôsoby:
Logstash získava polená od Kafku. Môže vyzdvihnúť čisté alebo previesť na vašej strane.
Niečo samo zapisuje do Elasticsearch, napríklad server APM.
Zvážte príklad správy indexov prostredníctvom Logstash. Vytvorí index a použije sa naň indexový vzor a zodpovedajúce ILM.
k8s-ingress.conf
input {
kafka {
bootstrap_servers => "node01, node02, node03"
topics => ["ingress-k8s"]
decorate_events => false
codec => "json"
}
}
filter {
ruby {
path => "/etc/logstash/conf.d/k8s-normalize.rb"
}
if [log] =~ "[warn]" or [log] =~ "[error]" or [log] =~ "[notice]" or [log] =~ "[alert]" {
grok {
match => { "log" => "%{DATA:[nginx][error][time]} [%{DATA:[nginx][error][level]}] %{NUMBER:[nginx][error][pid]}#%{NUMBER:[nginx][error][tid]}: *%{NUMBER:[nginx][error][connection_id]} %{DATA:[nginx][error][message]}, client: %{IPORHOST:[nginx][error][remote_ip]}, server: %{DATA:[nginx][error][server]}, request: "%{WORD:[nginx][error][method]} %{DATA:[nginx][error][url]} HTTP/%{NUMBER:[nginx][error][http_version]}", (?:upstream: "%{DATA:[nginx][error][upstream][proto]}://%{DATA:[nginx][error][upstream][host]}:%{DATA:[nginx][error][upstream][port]}/%{DATA:[nginx][error][upstream][url]}", )?host: "%{DATA:[nginx][error][host]}"(?:, referrer: "%{DATA:[nginx][error][referrer]}")?" }
remove_field => "log"
}
}
else {
grok {
match => { "log" => "%{IPORHOST:[nginx][access][host]} - [%{IPORHOST:[nginx][access][remote_ip]}] - %{DATA:[nginx][access][remote_user]} [%{HTTPDATE:[nginx][access][time]}] "%{WORD:[nginx][access][method]} %{DATA:[nginx][access][url]} HTTP/%{NUMBER:[nginx][access][http_version]}" %{NUMBER:[nginx][access][response_code]} %{NUMBER:[nginx][access][bytes_sent]} "%{DATA:[nginx][access][referrer]}" "%{DATA:[nginx][access][agent]}" %{NUMBER:[nginx][access][request_lenght]} %{NUMBER:[nginx][access][request_time]} [%{DATA:[nginx][access][upstream][name]}] (?:-|%{IPORHOST:[nginx][access][upstream][addr]}:%{NUMBER:[nginx][access][upstream][port]}) (?:-|%{NUMBER:[nginx][access][upstream][response_lenght]}) %{DATA:[nginx][access][upstream][response_time]} %{DATA:[nginx][access][upstream][status]} %{DATA:[nginx][access][request_id]}" }
remove_field => "log"
}
}
}
output {
elasticsearch {
id => "k8s-ingress"
hosts => ["node01", "node02", "node03", "node04", "node05", "node06", "node07", "node08"]
manage_template => true # включаем управление шаблонами
template_name => "k8s-ingress" # имя применяемого шаблона
ilm_enabled => true # включаем управление ILM
ilm_rollover_alias => "k8s-ingress" # alias для записи в индексы, должен быть уникальным
ilm_pattern => "{now/d}-000001" # шаблон для создания индексов, может быть как "{now/d}-000001" так и "000001"
ilm_policy => "k8s-ingress" # политика прикрепляемая к индексу
index => "k8s-ingress-%{+YYYY.MM.dd}" # название создаваемого индекса, может содержать %{+YYYY.MM.dd}, зависит от ilm_pattern
}
}
Nastavenie Kibana
Existuje základný vzor, ktorý sa vzťahuje na všetky nové indexy. Nastavuje rozloženie horúcich indexov, počet úlomkov, replík atď. Hmotnosť šablóny je určená voľbou order. Šablóny s vyššou váhou prepíšu existujúce parametre šablóny alebo pridajú nové.
GET_template/default
{
"default" : {
"order" : -1, # вес шаблона
"version" : 1,
"index_patterns" : [
"*" # применяем ко всем индексам
],
"settings" : {
"index" : {
"codec" : "best_compression", # уровень сжатия
"routing" : {
"allocation" : {
"require" : {
"box_type" : "hot" # распределяем только по горячим нодам
},
"total_shards_per_node" : "8" # максимальное количество шардов на ноду от одного индекса
}
},
"refresh_interval" : "5s", # интервал обновления индекса
"number_of_shards" : "8", # количество шардов
"auto_expand_replicas" : "0-1", # количество реплик на ноду от одного индекса
"number_of_replicas" : "1" # количество реплик
}
},
"mappings" : {
"_meta" : { },
"_source" : { },
"properties" : { }
},
"aliases" : { }
}
}
Potom použite mapovanie na indexy k8s-ingress-* pomocou šablóny s vyššou hmotnosťou.
Po aplikácii všetkých šablón aplikujeme politiku ILM a začneme monitorovať životnosť indexov.
ZÍSKAJTE _ilm/policy/k8s-ingress
{
"k8s-ingress" : {
"version" : 14,
"modified_date" : "2020-06-11T10:27:01.448Z",
"policy" : {
"phases" : {
"warm" : { # теплая фаза
"min_age" : "5d", # срок жизни индекса после ротации до наступления теплой фазы
"actions" : {
"allocate" : {
"include" : { },
"exclude" : { },
"require" : {
"box_type" : "warm" # куда перемещаем индекс
}
},
"shrink" : {
"number_of_shards" : 4 # обрезание индексов, т.к. у нас 4 ноды
}
}
},
"cold" : { # холодная фаза
"min_age" : "25d", # срок жизни индекса после ротации до наступления холодной фазы
"actions" : {
"allocate" : {
"include" : { },
"exclude" : { },
"require" : {
"box_type" : "cold" # куда перемещаем индекс
}
},
"freeze" : { } # замораживаем для оптимизации
}
},
"hot" : { # горячая фаза
"min_age" : "0ms",
"actions" : {
"rollover" : {
"max_size" : "50gb", # максимальный размер индекса до ротации (будет х2, т.к. есть 1 реплика)
"max_age" : "1d" # максимальный срок жизни индекса до ротации
},
"set_priority" : {
"priority" : 100
}
}
},
"delete" : { # фаза удаления
"min_age" : "120d", # максимальный срок жизни после ротации перед удалением
"actions" : {
"delete" : { }
}
}
}
}
}
}
Problémy
Vyskytli sa problémy vo fáze nastavenia a ladenia.
Horúca fáza
Pre správnu rotáciu indexov je kritická prítomnosť na konci index_name-date-000026 formátovať čísla 000001. V kóde sú riadky, ktoré kontrolujú indexy pomocou regulárneho výrazu na prítomnosť čísel na konci. V opačnom prípade dôjde k chybe, na index sa nepoužijú žiadne politiky a index bude vždy v horúcej fáze.
Teplá fáza
zmenšiť (cutoff) — zníženie počtu úlomkov, pretože v teplej a studenej fáze máme 4 uzly Dokumentácia obsahuje nasledujúce riadky:
Index musí byť len na čítanie.
Kópia každého zlomku v indexe sa musí nachádzať v rovnakom uzle.
Zdravotný stav klastra musí byť zelený.
Ak chcete orezať index, Elasticsearch presunie všetky primárne zlomky do jedného uzla, duplikuje skrátený index s potrebnými parametrami a potom odstráni starý. Parameter total_shards_per_node musí byť rovnaký alebo väčší ako počet hlavných črepov, ktoré sa zmestia na jeden uzol. V opačnom prípade budú upozornenia a zlomky sa nepresunú do správnych uzlov.
GET /shrink-k8s-ingress-2020.06.06-000025/_settings
Zmraziť (freeze) – Zmrazíme index, aby sme optimalizovali dopyty na historické údaje.
Vyhľadávania uskutočnené na zmrazených indexoch používajú malý, vyhradený fond vlákien search_throttled na riadenie počtu súbežných vyhľadávaní, ktoré zasiahli zmrazené zlomky v každom uzle. To obmedzuje množstvo dodatočnej pamäte potrebnej pre prechodné dátové štruktúry zodpovedajúce zmrazeným zlomkom, čo následne chráni uzly pred nadmernou spotrebou pamäte.
Zmrazené indexy sú len na čítanie: nemôžete do nich indexovať.
Očakáva sa, že vyhľadávania na zmrazených indexoch budú prebiehať pomaly. Zmrazené indexy nie sú určené na vysoké vyhľadávanie. Je možné, že dokončenie vyhľadávania v zmrazenom indexe môže trvať niekoľko sekúnd alebo minút, aj keď sa rovnaké vyhľadávania dokončili v milisekundách, keď indexy neboli zmrazené.
Výsledky
Naučili sme sa pripraviť uzly na prácu s ILM, nastaviť šablónu na distribúciu zlomkov medzi horúce uzly a nastaviť ILM pre index so všetkými fázami života.