نام من ایگور سیدورنکو است، من یک رهبر فنی در تیم مدیران هستم که کل زیرساخت Domclick را حفظ می کنند.
من می خواهم تجربه خود را در راه اندازی ذخیره سازی داده های توزیع شده در Elasticsearch به اشتراک بگذارم. ما بررسی خواهیم کرد که چه تنظیماتی بر روی گره ها مسئول توزیع خرده ها هستند، چگونه ILM کار می کند و کار می کند.
کسانی که با لاگ کار می کنند، به هر طریقی، با مشکل ذخیره سازی طولانی مدت برای تجزیه و تحلیل بعدی روبرو هستند. در Elasticsearch، این امر به ویژه صادق است، زیرا همه چیز با عملکرد متصدی ناخوشایند بود. نسخه 6.6 عملکرد ILM را معرفی کرد. از 4 فاز تشکیل شده است:
داغ - نمایه به طور فعال در حال به روز رسانی و پرس و جو است.
گرم - نمایه دیگر به روز نمی شود، اما هنوز در حال پرس و جو است.
سرد - ایندکس دیگر به روز نمی شود و به ندرت مورد پرسش قرار می گیرد. اطلاعات باید همچنان قابل جستجو باشد، اما درخواستها ممکن است کندتر باشند.
حذف - نمایه دیگر مورد نیاز نیست و می توان با خیال راحت آن را حذف کرد.
برای توزیع خردهها در گرهها، فقط به یک پارامتر نیاز دارید:
داغ-گره ها:
~]# cat /etc/elasticsearch/elasticsearch.yml | grep attr
# Add custom attributes to the node:
node.attr.box_type: hot
گرم-گره ها:
~]# cat /etc/elasticsearch/elasticsearch.yml | grep attr
# Add custom attributes to the node:
node.attr.box_type: warm
سرد-گره ها:
~]# cat /etc/elasticsearch/elasticsearch.yml | grep attr
# Add custom attributes to the node:
node.attr.box_type: cold
راه اندازی Logstash
همه اینها چگونه کار می کند و چگونه این ویژگی را پیاده سازی کردیم؟ بیایید با وارد کردن گزارشها به Elasticsearch شروع کنیم. دو راه وجود دارد:
Logstash از کافکا سیاههها را می آورد. می تواند تمیز یا تبدیل را در سمت شما انتخاب کند.
خود چیزی برای Elasticsearch می نویسد، به عنوان مثال، یک سرور APM.
مثالی از مدیریت ایندکس ها از طریق Logstash را در نظر بگیرید. ایندکس ایجاد می کند و روی آن اعمال می شود الگوی شاخص و مربوطه پسوند 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
}
}
راه اندازی کیبانا
یک الگوی پایه وجود دارد که برای همه شاخص های جدید اعمال می شود. توزیع شاخص های داغ، تعداد خرده ها، کپی ها و غیره را تنظیم می کند. وزن قالب توسط گزینه تعیین می شود order. الگوهایی با وزن بالاتر پارامترهای قالب موجود را نادیده می گیرند یا موارد جدیدی را اضافه می کنند.
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" : { }
}
}
سپس نقشه برداری را روی ایندکس ها اعمال کنید k8s-ingress-* با استفاده از قالبی با وزن بالاتر
پس از اعمال تمام قالب ها، سیاست ILM را اعمال می کنیم و شروع به نظارت بر عمر ایندکس ها می کنیم.
GET _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" : { }
}
}
}
}
}
}
مشکلات
در مرحله راه اندازی و اشکال زدایی مشکلاتی وجود داشت.
فاز داغ
برای چرخش صحیح شاخص ها، حضور در انتها حیاتی است index_name-date-000026 فرمت اعداد 000001. خطوطی در کد وجود دارد که نمایه ها را با استفاده از یک عبارت منظم برای وجود اعداد در انتها بررسی می کند. در غیر این صورت خطایی رخ می دهد و هیچ سیاستی روی شاخص اعمال نمی شود و همیشه در فاز داغ خواهد بود.
فاز گرم
کوچک شدن (قطع) - کاهش تعداد خرده ها، زیرا ما 4 گره در فازهای گرم و سرد داریم. مستندات شامل خطوط زیر است:
ایندکس باید فقط خواندنی باشد.
یک کپی از هر خرده در ایندکس باید در همان گره باشد.
وضعیت سلامت خوشه باید سبز باشد.
برای هرس کردن یک ایندکس، Elasticsearch همه خردههای اولیه را به یک گره منتقل میکند، شاخص کوتاهشده را با پارامترهای لازم کپی میکند، و سپس نمونه قدیمی را حذف میکند. پارامتر total_shards_per_node باید مساوی یا بیشتر از تعداد خرده های اصلی برای قرار گرفتن در یک گره باشد. در غیر این صورت، نوتیفیکیشن هایی وجود خواهد داشت و خرده ها به گره های صحیح منتقل نمی شوند.
GET /shrink-k8s-ingress-2020.06.06-000025/_settings
منجمد (تجمیع) - برای بهینه سازی پرس و جوها در داده های تاریخی، ایندکس را منجمد می کنیم.
جستجوهای انجام شده بر روی شاخصهای منجمد شده از Threadpool کوچک اختصاصی search_throttled برای کنترل تعداد جستجوهای همزمانی که بر روی هر گره به تکههای منجمد برخورد میکنند، استفاده میکنند. این مقدار حافظه اضافی مورد نیاز برای ساختارهای داده گذرا مربوط به خرده های منجمد را محدود می کند، که در نتیجه از گره ها در برابر مصرف بیش از حد حافظه محافظت می کند.
شاخصهای منجمد فقط خواندنی هستند: شما نمیتوانید در آنها فهرست کنید.
انتظار می رود جستجوها در شاخص های منجمد به کندی انجام شود. شاخص های منجمد برای بار جستجوی بالا در نظر گرفته نشده اند. این امکان وجود دارد که جستجوی یک فهرست ثابت چند ثانیه یا چند دقیقه طول بکشد، حتی اگر جستجوهای مشابه در زمانی که شاخصها ثابت نشده بودند، در میلیثانیه کامل شوند.
نمایش نتایج: از
ما یاد گرفتیم که چگونه گرهها را برای کار با ILM آماده کنیم، یک الگو برای توزیع خردهها در میان گرههای داغ راهاندازی کنیم و ILM را برای یک فهرست با تمام مراحل زندگی راهاندازی کنیم.