Em ji bo dîtina têketin navbera herî hêsan a cîhanê * pêş dixin

Em ji bo dîtina têketin navbera herî hêsan a cîhanê * pêş dixin Ger we carî ji bo dîtina têketinên navgînên malperê bikar aniye, wê hingê we belkî ferq kiriye ka, wekî qaîdeyek, ev navbeynkar çawa ne û (bi gelemperî) ne pir rehet û bersivdar in. Hin ku hûn dikarin bi wan re bikar bînin, hin jî bêkêmasî tirsnak in, lê ji min re dixuye ku sedema hemî pirsgirêkan ev e ku em bi xeletî nêzikî peywira dîtina têketinê dibin: em hewl didin ku navgînek webê li wir CLI (navbera rêza fermanê) biafirînin. çêtir dixebite. Ez bi xwe pir rehet im ku bi dûvik, grep, awk û yên din re dixebitim, û ji ber vê yekê ji bo min navbeynkariya îdeal a ji bo xebata bi têketin re dê tiştek mîna dûvik û grep be, lê ya ku dikare ji bo xwendina têketinên ku ji gelek serveran hatine jî were bikar anîn. Ango, bê guman, wan ji ClickHouse bixwînin!

*li gorî ramana kesane ya bikarhênerê habra youROCK

Bi logscli re hevdîtin bikin

Min ji bo navbeynkariya xwe navek dernexist, û, rast be, ew di forma prototîpê de heye, lê heke hûn dixwazin tavilê koda çavkaniyê bibînin, wê hingê hûn bi xêr hatine: https://github.com/YuriyNasretdinov/logscli (350 rêzikên koda Go ya hilbijartî).

Taybetmendiyên

Armanca min ew bû ku ez navberek çêkim ku ji kesên ku bi dûv / grep re têne bikar anîn nas xuya bike, ango piştgirîkirina tiştên jêrîn:

  1. Hemî têketin, bêyî fîlterkirin, bibînin.
  2. Rêzên ku tê de binerêzek sabît tê de bihêlin (ala -F у grep).
  3. Rêzên ku bi îfadeya birêkûpêk li hev dikin bihêlin (ala -E у grep).
  4. Bi xwerû, dîtin bi rêza kronolojîk berevajî ye, ji ber ku têketinên herî paşîn bi gelemperî pêşî balkêş in.
  5. Li kêleka her rêzê (vebijark). -A, -B и -C у grep, çapkirina N xetên berî, paş, û li dora her rêzek hevber, bi rêzê).
  6. Têketinên hatinê di wextê rast de, bi fîlterkirin an bêyî fîlterkirinê (bi bingehîn tail -f | grep).
  7. Divê navbeynkar bi hev re be less, head, tail û yên din - ji hêla xwerû ve, divê encam bêyî sînorkirinên hejmara wan werin vegerandin; xêz bi qasî ku bikarhêner bi wergirtina wan re eleqedar e wekî çemek têne çap kirin; nîşan SIGPIPE divê bi bêdengî weşana têketinê qut bike, mîna ku ew dikin tail, grep û karûbarên din ên UNIX.

Реализация

Ez ê texmîn bikim ku hûn jixwe bi rengekî dizanin ka meriv çawa têketinên ClickHouse radest dike. Heke ne, ez pêşniyar dikim ku wê biceribînin lsd и kittenhouseû herweha ev gotara li ser radestkirina têketinê.

Pêşî hûn hewce ne ku li ser nexşeya bingehîn biryar bidin. Ji ber ku hûn bi gelemperî dixwazin têketinên ku li gorî demê hatine rêz kirin bistînin, mentiq xuya dike ku hûn wan bi vî rengî hilînin. Ger gelek kategoriyên têketinê hebin û ew hemî ji heman celebê ne, wê hingê hûn dikarin kategoriyek têketinê wekî stûna yekem a mifteya seretayî çêbikin - ev ê dihêle ku hûn li şûna çendan tabloyek hebe, ku dê bibe plusek mezin dema ku têxe nav ClickHouse (li ser serverên bi dîskên hişk, tê pêşniyar kirin ku di çirkeyê de ~ 1 carî bêtir daneyan têxin ji bo tevahiya serverê).

Ango, em bi qasî nexşeya tabloya jêrîn hewce ne:

CREATE TABLE logs(
    category LowCardinality(String), -- категория логов (опционально)
    time DateTime, -- время события
    millis UInt16, -- миллисекунды (могут быть и микросекунды, и т.д.): рекомендуется хранить, если событий много, чтобы было легче различать события между собой
    ..., -- ваши собственные поля, например имя сервера, уровень логирования, и так далее
    message String -- текст сообщения
) ENGINE=MergeTree()
ORDER BY (category, time, millis)

Mixabin, min nikarî tavilê çavkaniyên vekirî yên bi têketinên rastîn ên ku ez bikaribim bigirim û dakêşim bibînim, ji ber vê yekê min li şûna vê yekê wekî mînak girt. nirxandinên hilberên ji Amazon-ê heya 2015-an. Bê guman, strukturên wan tam ne wekî yên têketinên nivîsê ye, lê ji bo mebestên nîgarkirinê ev ne girîng e.

talîmatên ji bo barkirina nirxandinên Amazon li ClickHouse

Ka em tabloyek çêbikin:

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

Di daneya Amazonê de tenê tarîxek ji bo vekolînê heye, lê wextek rast tune, ji ber vê yekê em vê daneyê bi randonek dagirtin.

Hûn ne hewce ne ku hûn hemî pelên tsv dakêşin û xwe bi yekem ~ 10-20-ê sînordar bikin da ku hûn komek daneya pir mezin a ku di nav 16 GB RAM-ê de cîh nagirin bistînin. Ji bo barkirina pelên TSV min fermana jêrîn bikar anî:

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

Li ser Dîskek Berdewam a standard (ku HDD-yek e) di Google Cloud-ê de bi mezinahiya 1000 GB (min ev mezinahî bi giranî girt da ku leza piçekî bilindtir bû, her çend dibe ku SSD-yek bi pîvana pêwîst erzantir bûya) barkirin. leza bi qasî ~ 75 MB / sec li ser 4 core bû.

  • Divê ez veqetandinê bikim ku ez li Google-ê dixebitim, lê min hesabek kesane bikar anî û ev gotar bi karê min re li pargîdaniyê re tune ye

Ez ê hemî nîgaran bi vê databasê ya taybetî çêkim, ji ber ku ev tişta ku li ber destê min bû ev e.

Pêşveçûna şopandina daneyê nîşan bide

Ji ber ku di ClickHouse de em ê li ser tabloyek bi têketin vekolînek tam bikar bînin, û ev operasyon dikare demek girîng bigire û dibe ku ji bo demek dirêj encamek dernekeve ger çend hevok werin dîtin, tê pêşniyar kirin ku meriv bikaribe nîşan bide. pêşveçûna pirsê heya ku rêzên yekem ên bi encam re têne wergirtin. Ji bo kirina vê yekê, di navgîniya HTTP de parametreyek heye ku dihêle hûn di sernavên HTTP de pêşkeftinê bişînin: send_progress_in_http_headers=1. Mixabin, pirtûkxaneya Go standard nikare sernavên ku têne wergirtin bixwîne, lê pêwendiya HTTP 1.0 (ku bi 1.1 re neyê tevlihev kirin!) ji hêla ClickHouse ve tê piştgirî kirin, ji ber vê yekê hûn dikarin pêwendiyek TCP ya xav ji ClickHouse re vekin û wê bişînin wir. GET /?query=... HTTP/1.0nn û sernav û laşê bersivê bêyî revîn û şîfrekirinê bistînin, ji ber vê yekê di vê rewşê de ne hewce ye ku em pirtûkxaneya standard bikar bînin.

Streaming têketinên ji ClickHouse

ClickHouse ji bo demek pir dirêj (ji sala 2019-an vir ve?) ji bo pirsên bi ORDER BY re xweşbîniyek heye, ji ber vê yekê pirsek mîna

SELECT time, millis, message
FROM logs
WHERE message LIKE '%something%'
ORDER BY time DESC, millis DESC

Ew ê tavilê dest bi vegerandina xêzên ku di peyama wan de binavçeya "tiştek" heye, bêyî ku li benda qedandina şopandinê be.

Di heman demê de, ew ê pir rehet be heke ClickHouse bixwe dema ku pêwendiya pê re girtî bû daxwazê ​​betal bike, lê ev ne tevgera xwerû ye. Betalkirina daxwaza otomatîkî dikare bi karanîna vebijarkê were çalak kirin cancel_http_readonly_queries_on_client_close=1.

Rêvekirina rast a SIGPIPE di Go de

Dema ku hûn bicîh bikin, bêjin, emrê some_cmd | head -n 10, tam çawa ferman some_cmd dema îdamê disekine head 10 xet jê kirin? Bersiv hêsan e: kengê head diqede, boriyek diqede, û stdout fermana some_cmd dest pê dike, bi şert û merc, "ber bi ti cihî ve" nîşan bide. Heke some_cmd hewl dide ku li boriyek girtî binivîse, ew sînyalek SIGPIPE distîne, ku bernameyê ji hêla xwerû ve bêdeng diqedîne.

Di Go de ev jî ji hêla xwerû ve diqewime, lê hilgirê sînyala SIGPIPE di dawiyê de jî "signal: SIGPIPE" an peyamek mîna wê çap dike, û ji bo paqijkirina vê peyamê em tenê hewce ne ku SIGPIPE xwe bi awayê ku em dixwazin, yanî bi bêdengî bi rê ve bibin. derî:

ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGPIPE)
go func() {
    <-ch
    os.Exit(0)
}()

Têkiliya peyamê nîşan bide

Pir caran hûn dixwazin çarçoweya ku tê de hin xeletî çêbûne bibînin (mînakî, kîjan daxwazî ​​bû sedema panîkê, an kîjan pirsgirêkên têkildar beriya hilweşînê xuya bûn), û di grep Ev bi karanîna vebijarkên -A, -B, û -C pêk tê, ku bi rêzê ve hejmarek rêzikên diyarkirî piştî, berî, û li dora peyamê nîşan didin.

Mixabin, min rêyek hêsan nedît ku ez heman tiştî di ClickHouse-ê de bikim, ji ber vê yekê ji bo pêşandana çarçovê, daxwazek din a bi vî rengî ji her rêzek encamê re tê şandin (hûragahiyan bi veqetandinê ve girêdayî ye û gelo çarçove berê tê xuyang kirin an piştî):

SELECT time,millis,review_body FROM amazon
WHERE (time = 'ВРЕМЯ_СОБЫТИЯ' AND millis < МИЛЛИСЕКУНДЫ_СОБЫТИЯ) OR (time < 'ВРЕМЯ_СОБЫТИЯ')
ORDER BY time DESC, millis DESC
LIMIT КОЛИЧЕСТВО_СТРОК_КОНТЕКСТА
SETTINGS max_threads=1

Ji ber ku daxwaz hema di cih de tê şandin piştî ku ClickHouse xeta têkildar vedigere, ew di cache de diqede û bi gelemperî daxwaz pir zû tê darve kirin û CPU-ya piçûk dixwe (bi gelemperî daxwaz li ser makîneya min a virtual bi qasî 6 ms digire).

Peyamên nû di wextê rast de nîşan bide

Ji bo ku em peyamên hatinê di wextê (hema hema) rast de nîşan bidin, em bi tenê daxwazê ​​ji çend saniyan carekê pêk tînin, mohra paşîn a ku me berê pê re rû bi rû maye bi bîr tîne.

Nimûneyên fermanê

Fermanên tîpîk ên logscli di pratîkê de çawa xuya dikin?

Ger we databasa Amazon-ê ya ku min di destpêka gotarê de behs kir dakêşand, hûn dikarin fermanên jêrîn bimeşînin:

# Показать строки, где встречается слово 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

references

Koda karûbar (bêyî belge) li ser github heye https://github.com/YuriyNasretdinov/logscli. Ez ê kêfxweş bibim ku ramanên we li ser ramana xwe ya ji bo navgînek konsolê ji bo dîtina têketinên li ser bingeha ClickHouse bibihîzim.

Source: www.habr.com

Add a comment