Եթե դուք երբևէ օգտագործել եք վեբ ինտերֆեյսներ տեղեկամատյանները դիտելու համար, ապա հավանաբար նկատել եք, թե ինչպես են, որպես կանոն, այդ ինտերֆեյսները ծանր և (հաճախ) ոչ այնքան հարմար և արձագանքող: Ոմանց կարելի է վարժվել, ոմանց՝ բացարձակապես սարսափելի, բայց ինձ թվում է, որ բոլոր խնդիրների պատճառն այն է, որ մենք սխալ ենք մոտենում տեղեկամատյանները դիտելու խնդրին. ավելի լավ է աշխատում: Ես անձամբ շատ հարմար եմ աշխատել tail-ի, grep-ի, awk-ի և այլոց հետ, և, հետևաբար, ինձ համար լոգերի հետ աշխատելու իդեալական ինտերֆեյսը կլինի tail-ի և grep-ի նման մի բան, որը կարող է օգտագործվել նաև բազմաթիվ սերվերներից ստացված տեղեկամատյանները կարդալու համար: Դա, իհարկե, կարդացեք դրանք ClickHouse-ից:
*ըստ habra օգտագործողի անձնական կարծիքի
Հանդիպեք logscli-ին
Ես իմ ինտերֆեյսի համար անուն չեմ հորինել, և, ճիշտն ասած, այն ավելի շուտ գոյություն ունի նախատիպի տեսքով, բայց եթե ցանկանում եք անմիջապես տեսնել աղբյուրի կոդը, ապա ողջունում եք. (Ընտրված Go կոդի 350 տող):
· ¶ R'RѕR RјRѕR RЅRѕSЃS, Fe
Իմ նպատակն էր ստեղծել ինտերֆեյս, որը ծանոթ կթվա նրանց, ովքեր սովոր են tail/grep-ին, այսինքն՝ աջակցել հետևյալ բաներին.
- Դիտեք բոլոր տեղեկամատյանները՝ առանց զտման:
- Թողեք ֆիքսված ենթատող պարունակող տողեր (դրոշ
-Fуgrep). - Թողնել տողեր, որոնք համապատասխանում են կանոնավոր արտահայտությանը (դրոշ
-Eуgrep). - Լռելյայնորեն դիտումը կատարվում է հակառակ ժամանակագրական կարգով, քանի որ ամենավերջին տեղեկամատյանները սովորաբար առաջին հերթին հետաքրքրում են:
- Ցույց տալ համատեքստը յուրաքանչյուր տողի կողքին (ընտրանքներ
-A,-Bи-Cуgrep, տպելով N տող՝ համապատասխանաբար յուրաքանչյուր համապատասխան տողի առաջ, հետո և շուրջը): - Դիտեք մուտքային տեղեկամատյանները իրական ժամանակում՝ զտմամբ կամ առանց զտման (ըստ էության
tail -f | grep). - Ինտերֆեյսը պետք է համատեղելի լինի
less,head,tailև մյուսները - լռելյայն, արդյունքները պետք է վերադարձվեն առանց դրանց քանակի սահմանափակումների. տողերը տպագրվում են որպես հոսք, քանի դեռ օգտվողը շահագրգռված է ստանալ դրանք. ազդանշանSIGPIPEպետք է լուռ ընդհատեն տեղեկամատյանների հոսքը, ճիշտ այնպես, ինչպես անում ենtail,grepև UNIX-ի այլ կոմունալ ծառայություններ:
Իրականացման
Ես կենթադրեմ, որ դուք արդեն ինչ-որ կերպ գիտեք, թե ինչպես փոխանցել տեղեկամատյանները ClickHouse-ին: Եթե ոչ, խորհուրդ եմ տալիս փորձել и Իսկ .
Նախ անհրաժեշտ է որոշել բազային սխեման: Քանի որ դուք սովորաբար ցանկանում եք ստանալ ժամանակի դասավորված տեղեկամատյանները, տրամաբանական է թվում դրանք պահել այդ կերպ: Եթե կան բազմաթիվ տեղեկամատյանների կատեգորիաներ, և դրանք բոլորը նույն տեսակի են, ապա դուք կարող եք կազմել տեղեկամատյանների կատեգորիա՝ որպես հիմնական բանալիի առաջին սյունակ. սա թույլ կտա ձեզ ունենալ մեկ աղյուսակ մի քանիսի փոխարեն, ինչը մեծ գումարած կլինի, երբ ClickHouse-ում տեղադրումը (կոշտ սկավառակներով սերվերների վրա խորհուրդ է տրվում տվյալներ տեղադրել ոչ ավելի, քան վայրկյանում 1 անգամ ամբողջ սերվերի համար).
Այսինքն, մեզ անհրաժեշտ է մոտավորապես հետևյալ աղյուսակի սխեման.
CREATE TABLE logs(
category LowCardinality(String), -- категория логов (опционально)
time DateTime, -- время события
millis UInt16, -- миллисекунды (могут быть и микросекунды, и т.д.): рекомендуется хранить, если событий много, чтобы было легче различать события между собой
..., -- ваши собственные поля, например имя сервера, уровень логирования, и так далее
message String -- текст сообщения
) ENGINE=MergeTree()
ORDER BY (category, time, millis)Ցավոք սրտի, ես չկարողացա անմիջապես գտնել որևէ բաց աղբյուրներ իրատեսական տեղեկամատյաններով, որոնք ես կարող էի վերցնել և ներբեռնել, ուստի ես դրա փոխարեն որպես օրինակ վերցրեցի: . Իհարկե, դրանց կառուցվածքը նույնը չէ, ինչ տեքստային տեղեկամատյանները, բայց նկարազարդման նպատակով դա կարևոր չէ:
Amazon-ի ակնարկները ClickHouse-ում վերբեռնելու հրահանգներ
Եկեք ստեղծենք աղյուսակ.
CREATE TABLE amazon(
review_date Date,
time DateTime DEFAULT toDateTime(toUInt32(review_date) * 86400 + rand() % 86400),
millis UInt16 DEFAULT rand() % 1000,
marketplace LowCardinality(String),
customer_id Int64,
review_id String,
product_id LowCardinality(String),
product_parent Int64,
product_title String,
product_category LowCardinality(String),
star_rating UInt8,
helpful_votes UInt32,
total_votes UInt32,
vine FixedString(1),
verified_purchase FixedString(1),
review_headline String,
review_body String
)
ENGINE=MergeTree()
ORDER BY (time, millis)
SETTINGS index_granularity=8192Ամազոնի տվյալների բազայում կա միայն վերանայման ամսաթիվ, բայց ճշգրիտ ժամանակ չկա, ուստի եկեք լրացնենք այս տվյալները ռանդոնով:
Պետք չէ ներբեռնել բոլոր tsv ֆայլերը և սահմանափակվել առաջին ~ 10-20-ով, որպեսզի ստանաք բավականին մեծ տվյալների հավաքածու, որը չի տեղավորվի 16 ԳԲ RAM-ի մեջ: TSV ֆայլեր վերբեռնելու համար ես օգտագործեցի հետևյալ հրամանը.
for i in *.tsv; do
echo $i;
tail -n +2 $i | pv |
clickhouse-client --input_format_allow_errors_ratio 0.5 --query='INSERT INTO amazon(marketplace,customer_id,review_id,product_id,product_parent,product_title,product_category,star_rating,helpful_votes,total_votes,vine,verified_purchase,review_headline,review_body,review_date) FORMAT TabSeparated'
doneՍտանդարտ կայուն սկավառակի վրա (որը HDD է) Google Cloud-ում 1000 ԳԲ չափսով (ես վերցրեցի այս չափը հիմնականում, որպեսզի արագությունը մի փոքր ավելի բարձր լիներ, չնայած, հնարավոր է, պահանջվող չափի SSD-ն ավելի էժան կլիներ) վերբեռնումը արագությունը մոտավորապես ~ 75 ՄԲ/վրկ էր 4 միջուկի վրա:
- Ես պետք է ամրագրեմ, որ աշխատում եմ Google-ում, բայց ես օգտագործել եմ անձնական հաշիվ, և այս հոդվածը կապ չունի ընկերությունում իմ աշխատանքի հետ։
Ես կպատրաստեմ բոլոր նկարազարդումները այս կոնկրետ տվյալների հավաքածուով, քանի որ սա այն ամենն է, ինչ ես ունեի ձեռքի տակ:
Ցույց տալ տվյալների սկանավորման առաջընթացը
Քանի որ ClickHouse-ում մենք կօգտագործենք ամբողջական սկանավորում սեղանի վրա տեղեկամատյաններով, և այս գործողությունը կարող է զգալի ժամանակ պահանջել և երկար ժամանակ արդյունք չտալ, եթե քիչ համընկնում գտնվեն, խորհուրդ է տրվում, որ կարողանանք ցույց տալ հարցման առաջընթացը, մինչև ստացվեն արդյունքով առաջին տողերը: Դա անելու համար HTTP ինտերֆեյսում կա մի պարամետր, որը թույլ է տալիս ուղարկել առաջընթաց HTTP վերնագրերում. send_progress_in_http_headers=1. Ցավոք, ստանդարտ Go գրադարանը չի կարող կարդալ վերնագրերը, երբ դրանք ստացվում են, բայց HTTP 1.0 ինտերֆեյսը (չշփոթել 1.1-ի հետ!) աջակցվում է ClickHouse-ի կողմից, այնպես որ կարող եք բացել չմշակված TCP կապը ClickHouse-ին և ուղարկել այն այնտեղ: GET /?query=... HTTP/1.0nn և ստացեք պատասխանի վերնագրերը և տեքստը առանց որևէ փախուստի կամ գաղտնագրման, ուստի այս դեպքում մենք նույնիսկ կարիք չունենք օգտագործելու ստանդարտ գրադարանը:
Հոսքային տեղեկամատյաններ ClickHouse-ից
ClickHouse-ը համեմատաբար երկար ժամանակ (2019 թվականից ի վեր) ORDER BY-ով հարցումների համար օպտիմիզացիա է ունեցել, այնպես որ նման հարցումը.
SELECT time, millis, message
FROM logs
WHERE message LIKE '%something%'
ORDER BY time DESC, millis DESCԱյն անմիջապես կսկսի վերադարձնել տողերը, որոնք իրենց հաղորդագրության մեջ ունեն ենթալարի «ինչ-որ բան»՝ չսպասելով սկանավորման ավարտին:
Նաև շատ հարմար կլիներ, եթե ինքը՝ ClickHouse-ը չեղարկեր հարցումը, երբ կապը փակվեց, բայց սա լռելյայն վարքագիծ չէ։ Հարցման ավտոմատ չեղարկումը կարող է միացված լինել՝ օգտագործելով ընտրանքը cancel_http_readonly_queries_on_client_close=1.
SIGPIPE-ի ճիշտ վարում Go-ում
Երբ դուք կատարում եք, ասեք, հրամանը some_cmd | head -n 10, ճիշտ ինչպես հրամանը some_cmd դադարեցնում է կատարումը, երբ head հանել 10 տող? Պատասխանը պարզ է՝ երբ head ավարտվում է, խողովակը փակվում է, և some_cmd հրամանի stdout-ը սկսում է պայմանականորեն ցույց տալ «ոչ մի տեղ»: Երբ some_cmd փորձում է գրել փակ խողովակի վրա, .
Go-ում դա տեղի է ունենում նաև լռելյայնորեն, բայց SIGPIPE ազդանշանի մշակիչը նաև վերջում տպում է «ազդանշան: SIGPIPE» կամ նմանատիպ հաղորդագրություն, և այս հաղորդագրությունը մաքրելու համար մենք պարզապես պետք է ինքներս աշխատենք SIGPIPE-ով այնպես, ինչպես ուզում ենք, այսինքն՝ լուռ: ելք:
ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGPIPE)
go func() {
<-ch
os.Exit(0)
}()Ցույց տալ հաղորդագրության համատեքստը
Հաճախ դուք ցանկանում եք տեսնել այն համատեքստը, որում տեղի է ունեցել ինչ-որ սխալ (օրինակ՝ ո՞ր հարցումն է խուճապ առաջացրել, կամ կապված ինչ խնդիրներ են տեսանելի եղել մինչև վթարը), և grep Դա արվում է օգտագործելով -A, -B և -C տարբերակները, որոնք ցույց են տալիս տողերի նշված թիվը համապատասխանաբար հաղորդագրությունից հետո, առաջ և շուրջը:
Ցավոք սրտի, ես չեմ գտել նույնը անելու հեշտ միջոց ClickHouse-ում, ուստի համատեքստը ցուցադրելու համար նման լրացուցիչ հարցում է ուղարկվում արդյունքի յուրաքանչյուր տողին (մանրամասները կախված են տեսակավորումից և համատեքստը նախկինում ցուցադրված լինելուց: կամ հետո):
SELECT time,millis,review_body FROM amazon
WHERE (time = 'ВРЕМЯ_СОБЫТИЯ' AND millis < МИЛЛИСЕКУНДЫ_СОБЫТИЯ) OR (time < 'ВРЕМЯ_СОБЫТИЯ')
ORDER BY time DESC, millis DESC
LIMIT КОЛИЧЕСТВО_СТРОК_КОНТЕКСТА
SETTINGS max_threads=1Քանի որ հարցումը ուղարկվում է գրեթե անմիջապես այն բանից հետո, երբ ClickHouse-ը վերադարձնում է համապատասխան տողը, այն հայտնվում է քեշում և, ընդհանուր առմամբ, հարցումը կատարվում է բավականին արագ և սպառում է մի փոքր պրոցեսոր (սովորաբար հարցումը տևում է մոտ ~6 մվ իմ վիրտուալ մեքենայի վրա):
Ցույց տալ նոր հաղորդագրությունները իրական ժամանակում
Մուտքային հաղորդագրությունները (գրեթե) իրական ժամանակում ցուցադրելու համար մենք պարզապես կատարում ենք հարցումը մի քանի վայրկյանը մեկ՝ հիշելով նախկինում հանդիպած վերջին ժամանակի դրոշմը։
Հրամանի օրինակներ
Ինչպիսի՞ն են տիպիկ logscli հրամանները գործնականում:
Եթե դուք ներբեռնել եք Amazon-ի տվյալների հավաքածուն, որը ես նշեցի հոդվածի սկզբում, կարող եք գործարկել հետևյալ հրամանները.
# Показать строки, где встречается слово walmart
$ logscli -F 'walmart' | less
# Показать самые свежие 10 строк, где встречается "terrible"
$ logscli -F terrible -limit 10
# То же самое без -limit:
$ logscli -F terrible | head -n 10
# Показать все строки, подходящие под /times [0-9]/, написанные для vine и у которых высокий рейтинг
$ logscli -E 'times [0-9]' -where="vine='Y' AND star_rating>4" | less
# Показать все строки со словом "panic" и 3 строки контекста вокруг
$ logscli -F 'panic' -C 3 | less
# Непрерывно показывать новые строки со словом "5-star"
$ logscli -F '5-star' -tailfՍայլակ
Կոմունալ ծածկագիրը (առանց փաստաթղթերի) հասանելի է github-ում . Ես ուրախ կլինեմ լսել ձեր մտքերը ClickHouse-ի վրա հիմնված տեղեկամատյանները դիտելու համար վահանակի միջերեսի իմ գաղափարի վերաբերյալ:
Source: www.habr.com
