Aleksey Lizunov, MKB හි තොරතුරු තාක්ෂණ අධ්යක්ෂ මණ්ඩලයේ දුරස්ථ සේවා නාලිකා සඳහා නිපුණතා මධ්යස්ථානයේ ප්රධානියා
ELK ස්ටැක් (ElasticSearch, Logstash, Kibana) සඳහා විකල්පයක් ලෙස, අපි ClickHouse දත්ත ගබඩාව ලඝු-සටහන් සඳහා දත්ත ගබඩාවක් ලෙස භාවිතා කිරීම පිළිබඳව පර්යේෂණ කරමින් සිටිමු.
මෙම ලිපියෙන් අපි ClickHouse දත්ත සමුදාය භාවිතා කිරීමේ අපගේ අත්දැකීම් සහ නියමු මෙහෙයුමේ මූලික ප්රතිඵල ගැන කතා කිරීමට කැමැත්තෙමු. ප්රතිඵල විශ්මයජනක බව වහාම සටහන් කළ යුතුය.
ඊළඟට, අපගේ පද්ධතිය වින්යාස කර ඇති ආකාරය සහ එය සමන්විත වන්නේ කුමන සංරචක වලින්ද යන්න අපි වඩාත් විස්තරාත්මකව විස්තර කරමු. නමුත් දැන් මම සමස්තයක් ලෙස මෙම දත්ත සමුදාය ගැන ටිකක් කතා කිරීමට කැමැත්තෙමි, සහ එය අවධානය යොමු කිරීම වටී. ClickHouse දත්ත සමුදාය Yandex වෙතින් ඉහළ කාර්යසාධනයක් සහිත විශ්ලේෂණ තීරු දත්ත ගබඩාවකි. එය Yandex සේවාවන්හි භාවිතා වේ, මුලදී එය Yandex.Metrica සඳහා ප්රධාන දත්ත ගබඩාව වේ. විවෘත මූලාශ්ර පද්ධතිය, නොමිලේ. සංවර්ධකයෙකුගේ දෘෂ්ටි කෝණයෙන්, ඔවුන් එය ක්රියාත්මක කළේ කෙසේදැයි මම නිතරම කල්පනා කර ඇත්තෙමි, මන්ද අතිශයින් විශාල දත්ත තිබේ. තවද Metrica හි පරිශීලක අතුරුමුහුණත ඉතා නම්යශීලී සහ වේගවත් වේ. මෙම දත්ත සමුදාය සමඟ පළමු දැන හඳුනා ගැනීමේදී, හැඟීම: “හොඳයි, අවසාන වශයෙන්! ජනතාව වෙනුවෙන් හැදුවා! ස්ථාපන ක්රියාවලියෙන් පටන් ගෙන ඉල්ලීම් යැවීමෙන් අවසන් වේ.
මෙම දත්ත සමුදාය ඉතා අඩු ඇතුල්වීමේ සීමාවක් ඇත. සාමාන්ය කුසලතා ඇති සංවර්ධකයෙකුට පවා මෙම දත්ත සමුදාය මිනිත්තු කිහිපයකින් ස්ථාපනය කර එය භාවිතා කිරීම ආරම්භ කළ හැකිය. සෑම දෙයක්ම පැහැදිලිව ක්රියා කරයි. ලිනක්ස් වලට අලුත් අය පවා ඉක්මනින් ස්ථාපනය හැසිරවිය හැකි අතර සරලම මෙහෙයුම් සිදු කරයි. මීට පෙර, Big Data, Hadoop, Google BigTable, HDFS යන වචන සමඟ සාමාන්ය සංවර්ධකයෙකුට අදහසක් තිබුනේ සමහර ටෙරාබයිට්, පෙටාබයිට් ගැන, සමහර අධිමානුෂිකයින් මෙම පද්ධති සඳහා සැකසුම් සහ සංවර්ධන කටයුතුවල නියැලී සිටින බවයි, පසුව ClickHouse පැමිණීමත් සමඟ දත්ත සමුදාය, ඔබට කලින් අත් කරගත නොහැකි වූ කාර්යයන් පරාසයක් විසඳා ගත හැකි සරල, තේරුම්ගත හැකි මෙවලමක් අප සතුව ඇත. එය ස්ථාපනය කිරීමට ගත වන්නේ තරමක් සාමාන්ය යන්ත්රයක් සහ මිනිත්තු පහක් පමණි. එනම්, අපට එවැනි දත්ත සමුදායක් ලැබුණි, උදාහරණයක් ලෙස, MySql, නමුත් වාර්තා බිලියන ගණනක් ගබඩා කිරීම සඳහා පමණි! SQL භාෂාව සමඟ යම් සුපිරි ලේඛනාගාරයක්. පිටසක්වල ජීවීන්ගේ ආයුධ මිනිසුන්ට භාර දුන්නා වගේ.
අපගේ ලොග් පද්ධතිය ගැන
තොරතුරු රැස් කිරීම සඳහා, සම්මත ආකෘති වෙබ් යෙදුම්වල IIS ලොග් ගොනු භාවිතා කරනු ලැබේ (අපි දැනට යෙදුම් ලොග් විග්රහ කරමින් සිටිමු, නමුත් නියමු අදියරේ ප්රධාන ඉලක්කය වන්නේ IIS ලොග් එකතු කිරීමයි).
විවිධ හේතූන් මත අපට ELK තොගය සම්පූර්ණයෙන්ම අත්හැරීමට නොහැකි වූ අතර, අපි හොඳින් ඔප්පු කර ඇති සහ තරමක් විශ්වාසදායක සහ පුරෝකථනය කළ හැකි ලෙස ක්රියා කරන LogStash සහ Filebeat සංරචක දිගටම භාවිතා කරන්නෙමු.
සාමාන්ය ලොග් කිරීමේ යෝජනා ක්රමය පහත රූපයේ දැක්වේ:
ClickHouse දත්ත සමුදායට දත්ත ලිවීමේ ලක්ෂණයක් වන්නේ කලාතුරකින් (තත්පරයකට වරක්) විශාල කාණ්ඩවල වාර්තා ඇතුළත් කිරීමයි. පෙනෙන විදිහට, ඔබ ClickHouse දත්ත සමුදාය සමඟ පළමු වරට වැඩ කරන විට ඔබට හමුවන වඩාත්ම "ගැටළු" කොටස මෙයයි: යෝජනා ක්රමය ටිකක් සංකීර්ණ වේ.
ClickHouse වෙත සෘජුවම දත්ත ඇතුලත් කරන LogStash සඳහා වන ප්ලගිනය මෙහිදී බොහෝ සෙයින් උපකාරී විය. මෙම සංරචකය දත්ත සමුදාය ලෙස එකම සේවාදායකයේ යොදවා ඇත. එබැවින්, සාමාන්යයෙන් කථා කිරීම, එය සිදු කිරීම නිර්දේශ නොකරයි, නමුත් ප්රායෝගික දෘෂ්ටි කෝණයකින්, එය එකම සේවාදායකයේ යොදවා ඇති විට වෙනම සේවාදායකයන් නිෂ්පාදනය නොකිරීමට. දත්ත සමුදාය සමඟ කිසිදු අසාර්ථක වීමක් හෝ සම්පත් ගැටුම් අපි නිරීක්ෂණය නොකළෙමු. ඊට අමතරව, ප්ලගිනයට දෝෂ ඇති විට නැවත උත්සාහ කිරීමේ යාන්ත්රණයක් ඇති බව සැලකිල්ලට ගත යුතුය. දෝෂ ඇති විට, ප්ලගිනය ඇතුළත් කළ නොහැකි දත්ත සමූහයක් තැටියට ලියයි (ගොනු ආකෘතිය පහසුය: සංස්කරණය කිරීමෙන් පසු, ඔබට ක්ලික්හවුස්-සේවාදායකය භාවිතයෙන් නිවැරදි කළ කණ්ඩායම පහසුවෙන් ඇතුළු කළ හැකිය).
යෝජනා ක්රමයේ භාවිතා කරන මෘදුකාංග සම්පූර්ණ ලැයිස්තුවක් වගුවේ දක්වා ඇත:
භාවිතා කරන මෘදුකාංග ලැයිස්තුව
මාතෘකාව
විස්තර
බෙදා හැරීමේ සබැඳිය
NGINX
වරායන් මගින් ප්රවේශය සීමා කිරීමට සහ අවසරය සංවිධානය කිරීමට ප්රතිලෝම-ප්රොක්සි
දැනට යෝජනා ක්රමය තුළ භාවිතා නොවේ
FileBeat
ගොනු ලඝු-සටහන් මාරු කිරීම.
logstash
ලොග් එකතු කරන්නා.
FileBeat වෙතින් ලඝු එකතු කිරීමට මෙන්ම RabbitMQ පෝලිමෙන් ලඝු එකතු කිරීමට භාවිතා කරයි (DMZ හි ඇති සේවාදායකයන් සඳහා.)
ලොග්ස්ටාෂ්-ප්රතිදාන-ක්ලික්හවුස්
කණ්ඩායම් වශයෙන් ClickHouse දත්ත ගබඩාවට ලොග් මාරු කිරීම සඳහා Loagstash ප්ලගිනය
/usr/share/logstash/bin/logstash-plugin ස්ථාපනය logstash-output-clickhouse
/usr/share/logstash/bin/logstash-plugin ස්ථාපනය logstash-filter-prune
/usr/share/logstash/bin/logstash-plugin ස්ථාපනය logstash-filter-multiline
නිවස ක්ලික් කරන්න
ලොග් ගබඩාව
සටහන. 2018 අගෝස්තු මාසයේ සිට, RHEL සඳහා “සාමාන්ය” rpm ගොඩනැගීම් Yandex ගබඩාවේ දර්ශනය විය, එබැවින් ඔබට ඒවා භාවිතා කිරීමට උත්සාහ කළ හැකිය. ස්ථාපනය කරන අවස්ථාවේදී, අපි Altinity විසින් ගොඩනගා ඇති පැකේජ භාවිතා කළෙමු.
ග්රැෆනා
ලොග් දෘශ්යකරණය. උපකරණ පුවරු සැකසීම
Redhat සහ Centos(64 Bit) - නවතම අනුවාදය
Grafana 4.6+ සඳහා ClickHouse දත්ත මූලාශ්රය
ClickHouse දත්ත මූලාශ්රය සමඟ Grafana සඳහා ප්ලගිනය
logstash
FileBeat සිට RabbitMQ පෝලිම දක්වා රවුටරය ලොග් කරන්න.
සටහන. අවාසනාවන්ත ලෙස FileBeat RabbitMQ වෙත කෙලින්ම ප්රතිදානය නොකරයි, එබැවින් Logstash ආකාරයෙන් අතරමැදි සබැඳියක් අවශ්ය වේ
හාවා එම්.කේ.
පණිවිඩ පෝලිම. මෙය DMZ හි ලොග් බෆරයයි
Erlang ධාවන කාලය (RabbitMQ සඳහා අවශ්යයි)
Erlang ධාවන කාලය. RabbitMQ සඳහා වැඩ කිරීමට අවශ්ය වේ
ClickHouse දත්ත සමුදාය සමඟ සේවාදායක වින්යාසය පහත වගුවේ දක්වා ඇත:
මාතෘකාව
අගය
අදහස් දැක්වීම්
වින්යාසය
HDD: 40GB
RAM: 8GB
සකසනය: Core 2 2Ghz
ClickHouse දත්ත ගබඩාව ක්රියාත්මක කිරීම සඳහා වන ඉඟි කෙරෙහි අවධානය යොමු කිරීම අවශ්ය වේ (
සාමාන්ය පද්ධති මෘදුකාංග
OS: Red Hat Enterprise Linux සේවාදායකය (Maipo)
JRE (Java 8)
ඔබට පෙනෙන පරිදි, මෙය සාමාන්ය වැඩපොළකි.
ලඝු-සටහන් ගබඩා කිරීම සඳහා වගුවේ ව්යුහය පහත පරිදි වේ:
log_web.sql
CREATE TABLE log_web (
logdate Date,
logdatetime DateTime CODEC(Delta, LZ4HC),
fld_log_file_name LowCardinality( String ),
fld_server_name LowCardinality( String ),
fld_app_name LowCardinality( String ),
fld_app_module LowCardinality( String ),
fld_website_name LowCardinality( String ),
serverIP LowCardinality( String ),
method LowCardinality( String ),
uriStem String,
uriQuery String,
port UInt32,
username LowCardinality( String ),
clientIP String,
clientRealIP String,
userAgent String,
referer String,
response String,
subresponse String,
win32response String,
timetaken UInt64
, uriQuery__utm_medium String
, uriQuery__utm_source String
, uriQuery__utm_campaign String
, uriQuery__utm_term String
, uriQuery__utm_content String
, uriQuery__yclid String
, uriQuery__region String
) Engine = MergeTree()
PARTITION BY toYYYYMM(logdate)
ORDER BY (fld_app_name, fld_app_module, logdatetime)
SETTINGS index_granularity = 8192;
අපි පෙරනිමි කොටස් කිරීම (මාසයෙන්) සහ දර්ශක කැටිති භාවිතා කරමු. සියලුම ක්ෂේත්ර ප්රායෝගිකව http ඉල්ලීම් ලොග් කිරීම සඳහා IIS ලොග් සටහන් වලට අනුරූප වේ. වෙනමම, utm-tags ගබඩා කිරීම සඳහා වෙනම ක්ෂේත්ර ඇති බව අපි සටහන් කරමු (ඒවා විමසුම් නූල් ක්ෂේත්රයෙන් වගුවට ඇතුළු කිරීමේ අදියරේදී විග්රහ කර ඇත).
එසේම, පද්ධති, සංරචක, සේවාදායකයන් පිළිබඳ තොරතුරු ගබඩා කිරීම සඳහා පද්ධති ක්ෂේත්ර කිහිපයක් වගුව වෙත එකතු කර ඇත. මෙම ක්ෂේත්ර පිළිබඳ විස්තරයක් සඳහා පහත වගුව බලන්න. එක් වගුවක, අපි පද්ධති කිහිපයක් සඳහා ලොග් ගබඩා කරමු.
මාතෘකාව
විස්තර
උදාහරණ:
fld_app_name
යෙදුම/පද්ධතියේ නම
වලංගු අගයන්:
- site1.domain.com බාහිර වෙබ් අඩවිය 1
- site2.domain.com බාහිර වෙබ් අඩවිය 2
- අභ්යන්තර-site1.domain.local අභ්යන්තර වෙබ් අඩවිය 1
site1.domain.com
fld_app_module
පද්ධති මොඩියුලය
වලංගු අගයන්:
- වෙබ් - වෙබ් අඩවිය
- svc - වෙබ් අඩවි සේවාව
- intgr - Integration Web Service
- bo - පරිපාලක (BackOffice)
වෙබ්
fld_වෙබ් අඩවිය_නම
IIS හි අඩවියේ නම
එක් සේවාදායකයක් මත පද්ධති කිහිපයක් යෙදවිය හැකිය, නැතහොත් එක් පද්ධති මොඩියුලයක අවස්ථා කිහිපයක් වුවද
වෙබ් ප්රධාන
fld_server_name
සේවාදායක නම
web1.domain.com
fld_log_file_name
සේවාදායකයේ ලොග් ගොනුව වෙත මාර්ගය
C:inetpublogsLogFiles
W3SVC1u_ex190711.log
මෙය ඔබට Grafana හි ප්රස්ථාර කාර්යක්ෂමව ගොඩනගා ගැනීමට ඉඩ සලසයි. උදාහරණයක් ලෙස, යම් පද්ධතියක ඉදිරිපස සිට ඉල්ලීම් බලන්න. මෙය Yandex.Metrica හි අඩවි කවුන්ටරයට සමාන වේ.
මාස දෙකක් සඳහා දත්ත සමුදාය භාවිතා කිරීම පිළිබඳ සංඛ්යා ලේඛන කිහිපයක් මෙහි දැක්වේ.
පද්ධති සහ ඒවායේ සංරචක මගින් බිඳ දැමූ වාර්තා ගණන
SELECT
fld_app_name,
fld_app_module,
count(fld_app_name) AS rows_count
FROM log_web
GROUP BY
fld_app_name,
fld_app_module
WITH TOTALS
ORDER BY
fld_app_name ASC,
rows_count DESC
┌─fld_app_name─────┬─fld_app_module─┬─rows_count─┐
│ site1.domain.ru │ web │ 131441 │
│ site2.domain.ru │ web │ 1751081 │
│ site3.domain.ru │ web │ 106887543 │
│ site3.domain.ru │ svc │ 44908603 │
│ site3.domain.ru │ intgr │ 9813911 │
│ site4.domain.ru │ web │ 772095 │
│ site5.domain.ru │ web │ 17037221 │
│ site5.domain.ru │ intgr │ 838559 │
│ site5.domain.ru │ bo │ 7404 │
│ site6.domain.ru │ web │ 595877 │
│ site7.domain.ru │ web │ 27778858 │
└──────────────────┴────────────────┴────────────┘
Totals:
┌─fld_app_name─┬─fld_app_module─┬─rows_count─┐
│ │ │ 210522593 │
└──────────────┴────────────────┴────────────┘
11 rows in set. Elapsed: 4.874 sec. Processed 210.52 million rows, 421.67 MB (43.19 million rows/s., 86.51 MB/s.)
තැටියේ ඇති දත්ත ප්රමාණය
SELECT
formatReadableSize(sum(data_uncompressed_bytes)) AS uncompressed,
formatReadableSize(sum(data_compressed_bytes)) AS compressed,
sum(rows) AS total_rows
FROM system.parts
WHERE table = 'log_web'
┌─uncompressed─┬─compressed─┬─total_rows─┐
│ 54.50 GiB │ 4.86 GiB │ 211427094 │
└──────────────┴────────────┴────────────┘
1 rows in set. Elapsed: 0.035 sec.
තීරු වල දත්ත සම්පීඩන උපාධිය
SELECT
name,
formatReadableSize(data_uncompressed_bytes) AS uncompressed,
formatReadableSize(data_compressed_bytes) AS compressed,
data_uncompressed_bytes / data_compressed_bytes AS compress_ratio
FROM system.columns
WHERE table = 'log_web'
┌─name───────────────────┬─uncompressed─┬─compressed─┬─────compress_ratio─┐
│ logdate │ 401.53 MiB │ 1.80 MiB │ 223.16665968777315 │
│ logdatetime │ 803.06 MiB │ 35.91 MiB │ 22.363966401202305 │
│ fld_log_file_name │ 220.66 MiB │ 2.60 MiB │ 84.99905736932571 │
│ fld_server_name │ 201.54 MiB │ 50.63 MiB │ 3.980924816977078 │
│ fld_app_name │ 201.17 MiB │ 969.17 KiB │ 212.55518183686877 │
│ fld_app_module │ 201.17 MiB │ 968.60 KiB │ 212.67805817411906 │
│ fld_website_name │ 201.54 MiB │ 1.24 MiB │ 162.7204926761546 │
│ serverIP │ 201.54 MiB │ 50.25 MiB │ 4.010824061219731 │
│ method │ 201.53 MiB │ 43.64 MiB │ 4.617721053304486 │
│ uriStem │ 5.13 GiB │ 832.51 MiB │ 6.311522291936919 │
│ uriQuery │ 2.58 GiB │ 501.06 MiB │ 5.269731450124478 │
│ port │ 803.06 MiB │ 3.98 MiB │ 201.91673864241824 │
│ username │ 318.08 MiB │ 26.93 MiB │ 11.812513794583598 │
│ clientIP │ 2.35 GiB │ 82.59 MiB │ 29.132328640073343 │
│ clientRealIP │ 2.49 GiB │ 465.05 MiB │ 5.478382297052563 │
│ userAgent │ 18.34 GiB │ 764.08 MiB │ 24.57905114484208 │
│ referer │ 14.71 GiB │ 1.37 GiB │ 10.736792723669906 │
│ response │ 803.06 MiB │ 83.81 MiB │ 9.582334090987247 │
│ subresponse │ 399.87 MiB │ 1.83 MiB │ 218.4831068635027 │
│ win32response │ 407.86 MiB │ 7.41 MiB │ 55.050315514606815 │
│ timetaken │ 1.57 GiB │ 402.06 MiB │ 3.9947395692010637 │
│ uriQuery__utm_medium │ 208.17 MiB │ 12.29 MiB │ 16.936148912472955 │
│ uriQuery__utm_source │ 215.18 MiB │ 13.00 MiB │ 16.548367623199912 │
│ uriQuery__utm_campaign │ 381.46 MiB │ 37.94 MiB │ 10.055156353418509 │
│ uriQuery__utm_term │ 231.82 MiB │ 10.78 MiB │ 21.502540454070672 │
│ uriQuery__utm_content │ 441.34 MiB │ 87.60 MiB │ 5.038260760449327 │
│ uriQuery__yclid │ 216.88 MiB │ 16.58 MiB │ 13.07721335008116 │
│ uriQuery__region │ 204.35 MiB │ 9.49 MiB │ 21.52661903446796 │
└────────────────────────┴──────────────┴────────────┴────────────────────┘
28 rows in set. Elapsed: 0.005 sec.
භාවිතා කරන ලද සංරචක පිළිබඳ විස්තරය
FileBeat. ගොනු ලොග මාරු කිරීම
මෙම සංරචකය තැටියේ ගොනු ලොග් කිරීමට සිදුවන වෙනස්කම් නිරීක්ෂණය කරන අතර තොරතුරු LogStash වෙත යවයි. ලොග් ගොනු ලියා ඇති සියලුම සේවාදායකයන් මත ස්ථාපනය කර ඇත (සාමාන්යයෙන් IIS). වලිග මාදිලියේ ක්රියා කරයි (එනම්, එය ගොනුවට එකතු කරන ලද වාර්තා පමණක් මාරු කරයි). නමුත් සම්පූර්ණ ගොනු මාරු කිරීම සඳහා ඔබට එය වෙන වෙනම වින්යාසගත කළ හැකිය. ඔබට පෙර මාස සඳහා දත්ත බාගත කිරීමට අවශ්ය වූ විට මෙය පහසු වේ. ලොග් ගොනුව ෆෝල්ඩරයකට දමන්න, එවිට එය සම්පූර්ණයෙන්ම කියවනු ඇත.
සේවාව නැවැත්වූ විට, දත්ත තවදුරටත් ගබඩාවට මාරු නොකෙරේ.
උදාහරණ වින්යාසය මේ වගේ ය:
filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- C:/inetpub/logs/LogFiles/W3SVC1/*.log
exclude_files: ['.gz$','.zip$']
tail_files: true
ignore_older: 24h
fields:
fld_server_name: "site1.domain.ru"
fld_app_name: "site1.domain.ru"
fld_app_module: "web"
fld_website_name: "web-main"
- type: log
enabled: true
paths:
- C:/inetpub/logs/LogFiles/__Import/access_log-*
exclude_files: ['.gz$','.zip$']
tail_files: false
fields:
fld_server_name: "site2.domain.ru"
fld_app_name: "site2.domain.ru"
fld_app_module: "web"
fld_website_name: "web-main"
fld_logformat: "logformat__apache"
filebeat.config.modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: false
reload.period: 2s
output.logstash:
hosts: ["log.domain.com:5044"]
ssl.enabled: true
ssl.certificate_authorities: ["C:/filebeat/certs/ca.pem", "C:/filebeat/certs/ca-issuing.pem"]
ssl.certificate: "C:/filebeat/certs/site1.domain.ru.cer"
ssl.key: "C:/filebeat/certs/site1.domain.ru.key"
#================================ Processors =====================================
processors:
- add_host_metadata: ~
- add_cloud_metadata: ~
logstash. ලොග් එකතු කරන්නා
මෙම සංරචකය නිර්මාණය කර ඇත්තේ FileBeat වෙතින් (හෝ RabbitMQ පෝලිම හරහා), ClickHouse දත්ත ගබඩාවට කණ්ඩායම් විග්රහ කිරීම සහ ඇතුළු කිරීම සඳහා ලොග් සටහන් ලබා ගැනීමටය.
ClickHouse වෙත ඇතුළු කිරීම සඳහා, Logstash-output-clickhouse ප්ලගිනය භාවිතා වේ. Logstash ප්ලගිනයට ඉල්ලීම් නැවත උත්සාහ කිරීමේ යාන්ත්රණයක් ඇත, නමුත් නිතිපතා වසා දැමීමක් සමඟ, සේවාවම නැවැත්වීම වඩා හොඳය. නැවැත්වූ විට, RabbitMQ පෝලිමේ පණිවිඩ එකතු වනු ඇත, එබැවින් නැවතුම දිගු වේලාවක් නම්, සේවාදායකයේ Filebeats නැවැත්වීම වඩා හොඳය. RabbitMQ භාවිතා නොකරන යෝජනා ක්රමයක (දේශීය ජාලයේ, Filebeat කෙලින්ම Logstash වෙත ලොග් යවයි), Filebeats තරමක් පිළිගත හැකි සහ ආරක්ෂිතව ක්රියා කරයි, එබැවින් ඔවුන්ට ප්රතිදානයේ නොමැතිකම ප්රතිවිපාක නොමැතිව සමත් වේ.
උදාහරණ වින්යාසය මේ වගේ ය:
log_web__filebeat_clickhouse.conf
input {
beats {
port => 5044
type => 'iis'
ssl => true
ssl_certificate_authorities => ["/etc/logstash/certs/ca.cer", "/etc/logstash/certs/ca-issuing.cer"]
ssl_certificate => "/etc/logstash/certs/server.cer"
ssl_key => "/etc/logstash/certs/server-pkcs8.key"
ssl_verify_mode => "peer"
add_field => {
"fld_server_name" => "%{[fields][fld_server_name]}"
"fld_app_name" => "%{[fields][fld_app_name]}"
"fld_app_module" => "%{[fields][fld_app_module]}"
"fld_website_name" => "%{[fields][fld_website_name]}"
"fld_log_file_name" => "%{source}"
"fld_logformat" => "%{[fields][fld_logformat]}"
}
}
rabbitmq {
host => "queue.domain.com"
port => 5671
user => "q-reader"
password => "password"
queue => "web_log"
heartbeat => 30
durable => true
ssl => true
#ssl_certificate_path => "/etc/logstash/certs/server.p12"
#ssl_certificate_password => "password"
add_field => {
"fld_server_name" => "%{[fields][fld_server_name]}"
"fld_app_name" => "%{[fields][fld_app_name]}"
"fld_app_module" => "%{[fields][fld_app_module]}"
"fld_website_name" => "%{[fields][fld_website_name]}"
"fld_log_file_name" => "%{source}"
"fld_logformat" => "%{[fields][fld_logformat]}"
}
}
}
filter {
if [message] =~ "^#" {
drop {}
}
if [fld_logformat] == "logformat__iis_with_xrealip" {
grok {
match => ["message", "%{TIMESTAMP_ISO8601:log_timestamp} %{IP:serverIP} %{WORD:method} %{NOTSPACE:uriStem} %{NOTSPACE:uriQuery} %{NUMBER:port} %{NOTSPACE:username} %{IPORHOST:clientIP} %{NOTSPACE:userAgent} %{NOTSPACE:referer} %{NUMBER:response} %{NUMBER:subresponse} %{NUMBER:win32response} %{NUMBER:timetaken} %{NOTSPACE:xrealIP} %{NOTSPACE:xforwarderfor}"]
}
} else {
grok {
match => ["message", "%{TIMESTAMP_ISO8601:log_timestamp} %{IP:serverIP} %{WORD:method} %{NOTSPACE:uriStem} %{NOTSPACE:uriQuery} %{NUMBER:port} %{NOTSPACE:username} %{IPORHOST:clientIP} %{NOTSPACE:userAgent} %{NOTSPACE:referer} %{NUMBER:response} %{NUMBER:subresponse} %{NUMBER:win32response} %{NUMBER:timetaken}"]
}
}
date {
match => [ "log_timestamp", "YYYY-MM-dd HH:mm:ss" ]
timezone => "Etc/UTC"
remove_field => [ "log_timestamp", "@timestamp" ]
target => [ "log_timestamp2" ]
}
ruby {
code => "tstamp = event.get('log_timestamp2').to_i
event.set('logdatetime', Time.at(tstamp).strftime('%Y-%m-%d %H:%M:%S'))
event.set('logdate', Time.at(tstamp).strftime('%Y-%m-%d'))"
}
if [bytesSent] {
ruby {
code => "event['kilobytesSent'] = event['bytesSent'].to_i / 1024.0"
}
}
if [bytesReceived] {
ruby {
code => "event['kilobytesReceived'] = event['bytesReceived'].to_i / 1024.0"
}
}
ruby {
code => "event.set('clientRealIP', event.get('clientIP'))"
}
if [xrealIP] {
ruby {
code => "event.set('clientRealIP', event.get('xrealIP'))"
}
}
if [xforwarderfor] {
ruby {
code => "event.set('clientRealIP', event.get('xforwarderfor'))"
}
}
mutate {
convert => ["bytesSent", "integer"]
convert => ["bytesReceived", "integer"]
convert => ["timetaken", "integer"]
convert => ["port", "integer"]
add_field => {
"clientHostname" => "%{clientIP}"
}
}
useragent {
source=> "useragent"
prefix=> "browser"
}
kv {
source => "uriQuery"
prefix => "uriQuery__"
allow_duplicate_values => false
field_split => "&"
include_keys => [ "utm_medium", "utm_source", "utm_campaign", "utm_term", "utm_content", "yclid", "region" ]
}
mutate {
join => { "uriQuery__utm_source" => "," }
join => { "uriQuery__utm_medium" => "," }
join => { "uriQuery__utm_campaign" => "," }
join => { "uriQuery__utm_term" => "," }
join => { "uriQuery__utm_content" => "," }
join => { "uriQuery__yclid" => "," }
join => { "uriQuery__region" => "," }
}
}
output {
#stdout {codec => rubydebug}
clickhouse {
headers => ["Authorization", "Basic abcdsfks..."]
http_hosts => ["http://127.0.0.1:8123"]
save_dir => "/etc/logstash/tmp"
table => "log_web"
request_tolerance => 1
flush_size => 10000
idle_flush_time => 1
mutations => {
"fld_log_file_name" => "fld_log_file_name"
"fld_server_name" => "fld_server_name"
"fld_app_name" => "fld_app_name"
"fld_app_module" => "fld_app_module"
"fld_website_name" => "fld_website_name"
"logdatetime" => "logdatetime"
"logdate" => "logdate"
"serverIP" => "serverIP"
"method" => "method"
"uriStem" => "uriStem"
"uriQuery" => "uriQuery"
"port" => "port"
"username" => "username"
"clientIP" => "clientIP"
"clientRealIP" => "clientRealIP"
"userAgent" => "userAgent"
"referer" => "referer"
"response" => "response"
"subresponse" => "subresponse"
"win32response" => "win32response"
"timetaken" => "timetaken"
"uriQuery__utm_medium" => "uriQuery__utm_medium"
"uriQuery__utm_source" => "uriQuery__utm_source"
"uriQuery__utm_campaign" => "uriQuery__utm_campaign"
"uriQuery__utm_term" => "uriQuery__utm_term"
"uriQuery__utm_content" => "uriQuery__utm_content"
"uriQuery__yclid" => "uriQuery__yclid"
"uriQuery__region" => "uriQuery__region"
}
}
}
නල මාර්ග.yml
# This file is where you define your pipelines. You can define multiple.
# For more information on multiple pipelines, see the documentation:
# https://www.elastic.co/guide/en/logstash/current/multiple-pipelines.html
- pipeline.id: log_web__filebeat_clickhouse
path.config: "/etc/logstash/log_web__filebeat_clickhouse.conf"
clickhouse. ලොග් ගබඩාව
සියලුම පද්ධති සඳහා ලඝු-සටහන් එක් වගුවක ගබඩා කර ඇත (ලිපියේ ආරම්භයේ බලන්න). එය ඉල්ලීම් පිළිබඳ තොරතුරු ගබඩා කිරීමට අදහස් කරයි: IIS ලොග, apache සහ nginx ලොග වැනි විවිධ ආකෘති සඳහා සියලු පරාමිති සමාන වේ. යෙදුම් ලොග සඳහා, උදාහරණයක් ලෙස, දෝෂ, තොරතුරු පණිවිඩ, අනතුරු ඇඟවීම් සටහන් කර ඇති අතර, සුදුසු ව්යුහයක් සහිත වෙනම වගුවක් සපයනු ලැබේ (දැනට සැලසුම් කිරීමේ අදියරේදී).
වගුවක් සැලසුම් කිරීමේදී, මූලික යතුර තීරණය කිරීම ඉතා වැදගත් වේ (ගබඩා කිරීමේදී දත්ත වර්ග කරනු ලැබේ). දත්ත සම්පීඩනය සහ විමසුම් වේගය මේ මත රඳා පවතී. අපගේ උදාහරණයේ දී, ප්රධාන ය
ඇණවුම් කරන්න (fld_app_name, fld_app_module, logdatetime)
එනම්, පද්ධතියේ නම, පද්ධති සංරචකයේ නම සහ සිදුවීමේ දිනය. මුලදී, උත්සවයේ දිනය මුලින්ම පැමිණියේය. එය අවසන් ස්ථානයට ගෙන ගිය පසු, විමසුම් දෙගුණයක් පමණ වේගයෙන් වැඩ කිරීමට පටන් ගත්තේය. ප්රාථමික යතුර වෙනස් කිරීම සඳහා වගුව ප්රතිනිර්මාණය කිරීම සහ දත්ත නැවත පූරණය කිරීම අවශ්ය වනු ඇත, එවිට ClickHouse තැටියේ දත්ත නැවත අනුපිළිවෙළට සකස් කරයි. මෙය බර මෙහෙයුමක්, එබැවින් වර්ග කිරීමේ යතුරට ඇතුළත් කළ යුතු දේ ගැන බොහෝ දේ සිතීම හොඳ අදහසකි.
LowCardinality දත්ත වර්ගය සාපේක්ෂව මෑත කාලීන අනුවාද වල පෙනී සිටි බව ද සටහන් කළ යුතුය. එය භාවිතා කරන විට, අඩු කාර්ඩිනලිටි (විකල්ප කිහිපයක්) ඇති එම ක්ෂේත්ර සඳහා සම්පීඩිත දත්ත ප්රමාණය තියුනු ලෙස අඩු වේ.
19.6 අනුවාදය දැනට භාවිතයේ පවතින අතර නවතම අනුවාදයට යාවත්කාලීන කිරීමට උත්සාහ කිරීමට අපි සැලසුම් කරමු. ඒවාට අනුවර්තී ග්රැනුලාරිටි, ස්කිපිං දර්ශක සහ ඩබල් ඩෙල්ටා කෝඩෙක් වැනි අපූරු විශේෂාංග ඇත.
පෙරනිමියෙන්, ස්ථාපනය අතරතුර, වින්යාසය තුළ ලුහුබැඳීමේ මට්ටම සකසා ඇත. ලඝු-සටහන් භ්රමණය කර සංරක්ෂණය කර ඇත, නමුත් ඒ සමඟම ඔවුන් ගිගාබයිට් දක්වා පුළුල් වේ. අවශ්යතාවයක් නොමැති නම්, ඔබට අනතුරු ඇඟවීමේ මට්ටම සැකසිය හැකිය, එවිට ලොගයේ ප්රමාණය විශාල ලෙස අඩු වේ. ලොග් කිරීමේ සැකසුම config.xml ගොනුව තුළ සකසා ඇත:
<!-- Possible levels: https://github.com/pocoproject/poco/blob/develop/Foundation/include/Poco/Logger. h#L105 -->
<level>warning</level>
ප්රයෝජනවත් විධාන කිහිපයක්
Поскольку оригинальные пакеты установки собираются по Debian, то для других версий Linux необходимо использовать пакеты собранные компанией Altinity.
Вот по этой ссылке есть инструкции с ссылками на их репозиторий: https://www.altinity.com/blog/2017/12/18/logstash-with-clickhouse
sudo yum search clickhouse-server
sudo yum install clickhouse-server.noarch
1. проверка статуса
sudo systemctl status clickhouse-server
2. остановка сервера
sudo systemctl stop clickhouse-server
3. запуск сервера
sudo systemctl start clickhouse-server
Запуск для выполнения запросов в многострочном режиме (выполнение после знака ";")
clickhouse-client --multiline
clickhouse-client --multiline --host 127.0.0.1 --password pa55w0rd
clickhouse-client --multiline --host 127.0.0.1 --port 9440 --secure --user default --password pa55w0rd
Плагин кликлауза для логстеш в случае ошибки в одной строке сохраняет всю пачку в файл /tmp/log_web_failed.json
Можно вручную исправить этот файл и попробовать залить его в БД вручную:
clickhouse-client --host 127.0.0.1 --password password --query="INSERT INTO log_web FORMAT JSONEachRow" < /tmp/log_web_failed__fixed.json
sudo mv /etc/logstash/tmp/log_web_failed.json /etc/logstash/tmp/log_web_failed__fixed.json
sudo chown user_dev /etc/logstash/tmp/log_web_failed__fixed.json
sudo clickhouse-client --host 127.0.0.1 --password password --query="INSERT INTO log_web FORMAT JSONEachRow" < /etc/logstash/tmp/log_web_failed__fixed.json
sudo mv /etc/logstash/tmp/log_web_failed__fixed.json /etc/logstash/tmp/log_web_failed__fixed_.json
выход из командной строки
quit;
## Настройка TLS
https://www.altinity.com/blog/2019/3/5/clickhouse-networking-part-2
openssl s_client -connect log.domain.com:9440 < /dev/null
logstash. FileBeat සිට RabbitMQ පෝලිම දක්වා රවුටරය ලොග් කරන්න
මෙම සංරචකය FileBeat සිට RabbitMQ පෝලිම වෙත පැමිණෙන ලඝු-සටහන් සඳහා භාවිතා කරයි. මෙහි කරුණු දෙකක් තිබේ:
- අවාසනාවකට, FileBeat හට RabbitMQ වෙත කෙලින්ම ලිවීමට ප්රතිදාන ප්ලගිනයක් නොමැත. තවද එවැනි ක්රියාකාරිත්වය, ඔවුන්ගේ github හි ගැටලුව අනුව විනිශ්චය කිරීම, ක්රියාත්මක කිරීමට සැලසුම් කර නැත. Kafka සඳහා ප්ලගිනයක් ඇත, නමුත් කිසියම් හේතුවක් නිසා අපට එය නිවසේදී භාවිතා කළ නොහැක.
- DMZ හි ලඝු-සටහන් එකතු කිරීම සඳහා අවශ්යතා තිබේ. ඒවා මත පදනම්ව, ලඝු-සටහන් මුලින්ම පෝලිමට එකතු කළ යුතු අතර පසුව LogStash පිටත සිට පෝලිමේ සිට ඇතුළත් කිරීම් කියවයි.
එබැවින්, DMZ හි සේවාදායකයන් පිහිටා ඇති අවස්ථාව සඳහා එවැනි තරමක් සංකීර්ණ යෝජනා ක්රමයක් භාවිතා කිරීමට සිදු වේ. උදාහරණ වින්යාසයක් මේ වගේ ය:
iis_w3c_logs__filebeat_rabbitmq.conf
input {
beats {
port => 5044
type => 'iis'
ssl => true
ssl_certificate_authorities => ["/etc/pki/tls/certs/app/ca.pem", "/etc/pki/tls/certs/app/ca-issuing.pem"]
ssl_certificate => "/etc/pki/tls/certs/app/queue.domain.com.cer"
ssl_key => "/etc/pki/tls/certs/app/queue.domain.com-pkcs8.key"
ssl_verify_mode => "peer"
}
}
output {
#stdout {codec => rubydebug}
rabbitmq {
host => "127.0.0.1"
port => 5672
exchange => "monitor.direct"
exchange_type => "direct"
key => "%{[fields][fld_app_name]}"
user => "q-writer"
password => "password"
ssl => false
}
}
RabbitMQ. පණිවිඩ පෝලිම
මෙම සංරචකය DMZ හි ලොග් ඇතුළත් කිරීම් බෆර් කිරීමට භාවිතා කරයි. පටිගත කිරීම Filebeat → LogStash පොකුරක් හරහා සිදු කෙරේ. LogStash හරහා DMZ පිටත සිට කියවීම සිදු කෙරේ. RabboitMQ හරහා ක්රියා කරන විට, තත්පරයකට පණිවිඩ 4 ක් පමණ සකසනු ලැබේ.
පණිවිඩ මාර්ගගත කිරීම පද්ධති නාමයෙන් වින්යාස කර ඇත, එනම් FileBeat වින්යාස දත්ත මත පදනම්ව. සියලුම පණිවිඩ එක් පෝලිමකට යයි. කිසියම් හේතුවක් නිසා පෝලිම් සේවාව නතර කර ඇත්නම්, මෙය පණිවිඩ අහිමි වීමට තුඩු නොදෙනු ඇත: FileBeats හට සම්බන්ධතා දෝෂ ලැබෙනු ඇති අතර එය යැවීම තාවකාලිකව නවත්වනු ඇත. තවද පෝලිමේ සිට කියවන LogStash හට ජාල දෝෂ ද ලැබෙන අතර සම්බන්ධතාවය ප්රතිසාධනය වන තෙක් බලා සිටිනු ඇත. මෙම අවස්ථාවෙහිදී, ඇත්ත වශයෙන්ම, දත්ත තවදුරටත් දත්ත සමුදාය වෙත නොලියනු ඇත.
පෝලිම් සෑදීමට සහ වින්යාස කිරීමට පහත උපදෙස් භාවිතා කරයි:
sudo /usr/local/bin/rabbitmqadmin/rabbitmqadmin declare exchange --vhost=/ name=monitor.direct type=direct sudo /usr/local/bin/rabbitmqadmin/rabbitmqadmin declare queue --vhost=/ name=web_log durable=true
sudo /usr/local/bin/rabbitmqadmin/rabbitmqadmin --vhost="/" declare binding source="monitor.direct" destination_type="queue" destination="web_log" routing_key="site1.domain.ru"
sudo /usr/local/bin/rabbitmqadmin/rabbitmqadmin --vhost="/" declare binding source="monitor.direct" destination_type="queue" destination="web_log" routing_key="site2.domain.ru"
ග්රෆානා. උපකරණ පුවරු
මෙම සංරචකය අධීක්ෂණ දත්ත දෘශ්යමාන කිරීමට භාවිතා කරයි. මෙම අවස්ථාවේදී, ඔබ Grafana 4.6+ ප්ලගිනය සඳහා ClickHouse දත්ත මූලාශ්රය ස්ථාපනය කළ යුතුය. උපකරණ පුවරුවේ SQL පෙරහන් සැකසීමේ කාර්යක්ෂමතාව වැඩි දියුණු කිරීම සඳහා අපට එය ටිකක් වෙනස් කිරීමට සිදු විය.
උදාහරණයක් ලෙස, අපි විචල්ය භාවිතා කරන අතර, ඒවා පෙරහන් ක්ෂේත්රයේ සකසා නොමැති නම්, පෝරමයේ කොතැනකද කොන්දේසියක් උත්පාදනය නොකිරීමට අපි කැමතියි ( uriStem = » සහ uriStem != » ). මෙම අවස්ථාවේදී, ClickHouse uriStem තීරුව කියවනු ඇත. සාමාන්යයෙන්, අපි විවිධ විකල්ප උත්සාහ කර අවසානයේ ප්ලගිනය ($valueIfEmpty macro) නිවැරදි කළෙමු, එවිට හිස් අගයක දී තීරුව සඳහන් නොකර 1 ආපසු ලබා දේ.
දැන් ඔබට ප්රස්තාරය සඳහා මෙම විමසුම භාවිතා කළ හැක
$columns(response, count(*) c) from $table where $adhoc
and $valueIfEmpty($fld_app_name, 1, fld_app_name = '$fld_app_name')
and $valueIfEmpty($fld_app_module, 1, fld_app_module = '$fld_app_module') and $valueIfEmpty($fld_server_name, 1, fld_server_name = '$fld_server_name') and $valueIfEmpty($uriStem, 1, uriStem like '%$uriStem%')
and $valueIfEmpty($clientRealIP, 1, clientRealIP = '$clientRealIP')
එය මෙම SQL වෙත පරිවර්තනය වේ (හිස් uriStem ක්ෂේත්ර 1ක් පමණක් බවට පරිවර්තනය කර ඇති බව සලකන්න)
SELECT
t,
groupArray((response, c)) AS groupArr
FROM (
SELECT
(intDiv(toUInt32(logdatetime), 60) * 60) * 1000 AS t, response,
count(*) AS c FROM default.log_web
WHERE (logdate >= toDate(1565061982)) AND (logdatetime >= toDateTime(1565061982)) AND 1 AND (fld_app_name = 'site1.domain.ru') AND (fld_app_module = 'web') AND 1 AND 1 AND 1
GROUP BY
t, response
ORDER BY
t ASC,
response ASC
)
GROUP BY t ORDER BY t ASC
නිගමනය
ClickHouse දත්ත සමුදායේ පෙනුම වෙළඳපොලේ සන්ධිස්ථානයක් බවට පත්ව ඇත. සම්පුර්ණයෙන්ම නොමිලේ, ක්ෂණයකින් අපි විශාල දත්ත සමඟ වැඩ කිරීම සඳහා බලවත් සහ ප්රායෝගික මෙවලමකින් සන්නද්ධ වූ බව සිතීම දුෂ්කර විය. ඇත්ත වශයෙන්ම, වැඩිවන අවශ්යතා සමඟ (උදාහරණයක් ලෙස, බෙදා හැරීම සහ බහු සේවාදායකයන්ට අනුකරණය කිරීම), යෝජනා ක්රමය වඩාත් සංකීර්ණ වනු ඇත. නමුත් පළමු හැඟීම් මත, මෙම දත්ත සමුදාය සමඟ වැඩ කිරීම ඉතා ප්රසන්න වේ. නිෂ්පාදිතය "මිනිසුන් සඳහා" සාදා ඇති බව පෙනේ.
ElasticSearch හා සසඳන විට, ලඝු-සටහන් ගබඩා කිරීමේ සහ සැකසීමේ පිරිවැය පහේ සිට දස ගුණයකින් අඩු වනු ඇතැයි ගණන් බලා ඇත. වෙනත් වචන වලින් කිවහොත්, දැනට පවතින දත්ත ප්රමාණය සඳහා අපට යන්ත්ර කිහිපයක පොකුරක් සැකසීමට සිදුවේ නම්, ClickHouse භාවිතා කරන විට, අපට අඩු බලැති යන්ත්රයක් ප්රමාණවත් වේ. ඔව්, ඇත්ත වශයෙන්ම, ElasticSearch සතුව තැටියේ දත්ත සම්පීඩන යාන්ත්රණ සහ සම්පත් පරිභෝජනය සැලකිය යුතු ලෙස අඩු කළ හැකි වෙනත් විශේෂාංග ඇත, නමුත් ClickHouse හා සසඳන විට මෙය වඩා මිල අධික වනු ඇත.
අපගේ පැත්තෙන් විශේෂ ප්රශස්තිකරණයකින් තොරව, පෙරනිමි සැකසුම් මත, දත්ත පැටවීම සහ දත්ත සමුදායෙන් තේරීම පුදුම වේගයකින් ක්රියා කරයි. අපට තවම බොහෝ දත්ත නොමැත (වාර්තා මිලියන 200 ක් පමණ), නමුත් සේවාදායකයම දුර්වලයි. ලඝු-සටහන් ගබඩා කිරීමට අදාළ නොවන වෙනත් අරමුණු සඳහා අපට අනාගතයේදී මෙම මෙවලම භාවිතා කළ හැකිය. උදාහරණයක් ලෙස, අන්තයේ සිට අවසානය දක්වා විශ්ලේෂණ සඳහා, ආරක්ෂක ක්ෂේත්රයේ, යන්ත්ර ඉගෙනීම.
අවසානයේදී, වාසි සහ අවාසි ගැන ටිකක්.
මිනිසු
- විශාල කණ්ඩායම් වල වාර්තා පූරණය කිරීම. එක් අතකින්, මෙය විශේෂාංගයකි, නමුත් ඔබට තවමත් බෆරින් වාර්තා සඳහා අමතර සංරචක භාවිතා කිරීමට සිදු වේ. මෙම කාර්යය සැමවිටම පහසු නැත, නමුත් තවමත් විසඳිය හැකිය. ඒ වගේම මම යෝජනා ක්රමය සරල කිරීමට කැමතියි.
- සමහර විදේශීය ක්රියාකාරීත්වයන් හෝ නව විශේෂාංග බොහෝ විට නව අනුවාද වල කැඩී යයි. මෙය කනස්සල්ලට හේතු වේ, නව අනුවාදයකට යාවත්කාලීන කිරීමට ඇති ආශාව අඩු කරයි. උදාහරණයක් ලෙස, කෆ්කා ටේබල් එන්ජිම පාරිභෝගිකයින් ක්රියාවට නැංවීමෙන් තොරව, කෆ්කා වෙතින් සිදුවීම් කෙලින්ම කියවීමට ඔබට ඉඩ සලසන ඉතා ප්රයෝජනවත් අංගයකි. නමුත් github හි ඇති ගැටළු ගණන අනුව විනිශ්චය කිරීම, අපි තවමත් මෙම එන්ජිම නිෂ්පාදනයේදී භාවිතා නොකිරීමට වගබලා ගන්නෙමු. කෙසේ වෙතත්, ඔබ පැත්තට හදිසි අභිනයන් නොකරන්නේ නම් සහ ප්රධාන ක්රියාකාරිත්වය භාවිතා කරන්නේ නම්, එය ස්ථාවර ලෙස ක්රියා කරයි.
ප්ලස්
- වේගය අඩු නොකරයි.
- අඩු ඇතුල්වීමේ සීමාව.
- විවෘත මූලාශ්ර.
- නිදහස්.
- හොඳින් පරිමාණයන් (පෙට්ටියෙන් පිටතට කැඩීම / අනුකරණය)
- සන්නිවේදන අමාත්යාංශය විසින් නිර්දේශ කරන ලද රුසියානු මෘදුකාංග ලේඛනයේ ඇතුළත් වේ.
- Yandex වෙතින් නිල සහාය ලබා ගැනීම.
මූලාශ්රය: www.habr.com