Tunatengeneza kiolesura kinachofaa zaidi ulimwenguni* cha kutazama kumbukumbu

Tunatengeneza kiolesura kinachofaa zaidi ulimwenguni* cha kutazama kumbukumbu Ikiwa umewahi kutumia miingiliano ya wavuti kutazama kumbukumbu, basi labda umegundua jinsi, kama sheria, miingiliano hii ni ngumu na (mara nyingi) sio rahisi sana na sikivu. Baadhi unaweza kuzoea, wengine ni mbaya kabisa, lakini inaonekana kwangu kwamba sababu ya shida zote ni kwamba tunakaribia kazi ya kutazama kumbukumbu vibaya: tunajaribu kuunda kiolesura cha wavuti ambapo CLI (kiolesura cha mstari wa amri) inafanya kazi vizuri zaidi. Binafsi niko vizuri sana kufanya kazi na tail, grep, awk na wengine, na kwa hivyo kwangu kiolesura bora cha kufanya kazi na magogo kitakuwa kitu sawa na tail na grep, lakini ambacho kinaweza pia kutumika kusoma magogo yaliyotoka kwa seva nyingi. Hiyo ni, kwa kweli, uwasome kutoka kwa ClickHouse!

*kulingana na maoni ya kibinafsi ya mtumiaji wa habra MWAMBA wako

Kutana na logscli

Sikuja na jina la kiolesura changu, na, kuwa mkweli, linapatikana katika mfumo wa mfano, lakini ikiwa unataka kuona mara moja nambari ya chanzo, basi unakaribishwa: https://github.com/YuriyNasretdinov/logscli (mistari 350 ya msimbo wa Go uliochaguliwa).

Uwezo

Kusudi langu lilikuwa kutengeneza kiolesura ambacho kingeonekana kuwa cha kawaida kwa wale ambao wamezoea mkia/grep, ambayo ni kuunga mkono mambo yafuatayo:

  1. Tazama kumbukumbu zote, bila kuchuja.
  2. Acha mistari iliyo na kamba ndogo isiyobadilika (bendera -F у grep).
  3. Acha mistari inayolingana na usemi wa kawaida (bendera -E у grep).
  4. Kwa chaguo-msingi, kutazama kunafuatana katika mpangilio wa matukio, kwa kuwa kumbukumbu za hivi majuzi kwa kawaida ndizo zinazovutia kwanza.
  5. Onyesha muktadha kando ya kila mstari (chaguo -A, -B и -C у grep, kuchapisha mistari N kabla, baada, na kuzunguka kila mstari unaolingana, mtawalia).
  6. Tazama kumbukumbu zinazoingia kwa wakati halisi, na au bila kuchuja (kimsingi tail -f | grep).
  7. Kiolesura lazima sambamba na less, head, tail na wengine - kwa default, matokeo yanapaswa kurejeshwa bila vikwazo kwa idadi yao; mistari huchapishwa kama mkondo mradi tu mtumiaji angependa kupokea; ishara SIGPIPE inapaswa kukatiza utiririshaji wa kumbukumbu kimya kimya, kama wao hufanya tail, grep na huduma zingine za UNIX.

Utekelezaji

Nitafikiria kuwa tayari unajua jinsi ya kutoa kumbukumbu kwa ClickHouse. Ikiwa sivyo, napendekeza kujaribu lsd и kittenhouseNa makala hii kuhusu utoaji wa logi.

Kwanza unahitaji kuamua juu ya mpango wa msingi. Kwa kuwa kwa kawaida unataka kupokea kumbukumbu zilizopangwa kulingana na wakati, inaonekana ni jambo la busara kuzihifadhi kwa njia hiyo. Ikiwa kuna aina nyingi za logi na zote ni za aina moja, basi unaweza kufanya kitengo cha logi kama safu ya kwanza ya ufunguo wa msingi - hii itakuruhusu kuwa na meza moja badala ya kadhaa, ambayo itakuwa kubwa zaidi wakati. kuingiza kwenye ClickHouse (kwenye seva zilizo na anatoa ngumu, inashauriwa kuingiza data sio zaidi ya ~ mara 1 kwa sekunde kwa seva nzima).

Hiyo ni, tunahitaji takriban mpango wa jedwali ufuatao:

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

Kwa bahati mbaya, sikuweza kupata mara moja vyanzo vyovyote vilivyo wazi vilivyo na kumbukumbu za kweli ambazo ningeweza kunyakua na kupakua, kwa hivyo nilichukua hii kama mfano. hakiki za bidhaa kutoka Amazon hadi 2015. Bila shaka, muundo wao haufanani kabisa na ule wa kumbukumbu za maandishi, lakini kwa madhumuni ya kielelezo hii sio muhimu.

maagizo ya kupakia hakiki za Amazon kwenye ClickHouse

Wacha tutengeneze meza:

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

Katika hifadhidata ya Amazon kuna tarehe tu ya ukaguzi, lakini hakuna wakati kamili, kwa hivyo wacha tujaze data hii na randon.

Si lazima upakue faili zote za tsv na ujiwekee kikomo hadi ~10-20 za kwanza ili kupata seti kubwa ya data ambayo haitatosha kwenye GB 16 ya RAM. Ili kupakia faili za TSV nilitumia amri ifuatayo:

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

Kwenye Diski ya Kudumu ya kawaida (ambayo ni HDD) katika Wingu la Google yenye ukubwa wa GB 1000 (nilichukua saizi hii haswa ili kasi iwe juu kidogo, ingawa labda SSD ya saizi inayohitajika ingekuwa nafuu) upakiaji. kasi ilikuwa takriban ~ 75 MB/sec kwenye cores 4.

  • Lazima niweke nafasi kuwa ninafanya kazi katika Google, lakini nilitumia akaunti ya kibinafsi na makala haya hayahusiani na kazi yangu katika kampuni.

Nitatoa vielelezo vyote na hifadhidata hii, kwani hii ndiyo yote niliyokuwa nayo.

Onyesha maendeleo ya kuchanganua data

Kwa kuwa katika ClickHouse tutatumia skanisho kamili kwenye jedwali iliyo na magogo, na operesheni hii inaweza kuchukua muda mwingi na inaweza isitoe matokeo yoyote kwa muda mrefu ikiwa mechi chache zitapatikana, ni vyema kuweza kuonyesha maendeleo ya hoja hadi safu mlalo za kwanza zenye matokeo zipokee. Ili kufanya hivyo, kuna kigezo katika kiolesura cha HTTP ambacho hukuruhusu kutuma maendeleo katika vichwa vya HTTP: send_progress_in_http_headers=1. Kwa bahati mbaya, maktaba ya kawaida ya Go haiwezi kusoma vichwa jinsi yanavyopokelewa, lakini kiolesura cha HTTP 1.0 (si cha kuchanganyikiwa na 1.1!) kinasaidiwa na ClickHouse, kwa hivyo unaweza kufungua muunganisho mbichi wa TCP kwa ClickHouse na utume hapo. GET /?query=... HTTP/1.0nn na upokee vichwa vya majibu na mwili bila kutoroka au usimbaji fiche wowote, kwa hivyo katika kesi hii hatuhitaji hata kutumia maktaba ya kawaida.

Kutiririsha kumbukumbu kutoka kwa ClickHouse

ClickHouse imekuwa na uboreshaji wa maswali na ORDER BY kwa muda mrefu (tangu 2019?), kwa hivyo swali kama

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

Itaanza mara moja kurejesha mistari iliyo na "kitu" kidogo katika ujumbe wao, bila kungoja tambazo imalizike.

Pia, itakuwa rahisi sana ikiwa ClickHouse yenyewe ilighairi ombi wakati muunganisho wake umefungwa, lakini hii sio tabia chaguo-msingi. Kughairi ombi kiotomatiki kunaweza kuwezeshwa kwa kutumia chaguo cancel_http_readonly_queries_on_client_close=1.

Ushughulikiaji sahihi wa SIGPIPE katika Go

Unapotekeleza, sema, amri some_cmd | head -n 10, jinsi amri some_cmd inaacha utekelezaji wakati head umeondoa mistari 10? Jibu ni rahisi: lini head huisha, bomba hufunga, na stdout ya amri some_cmd huanza kuelekeza, kwa masharti, "hapana popote". Lini some_cmd anajaribu kuandika kwa bomba iliyofungwa, inapokea ishara ya SIGPIPE, ambayo inasitisha kimya programu kwa default.

Katika Go hii pia hufanyika kwa chaguo-msingi, lakini kidhibiti cha mawimbi cha SIGPIPE pia huchapisha "signal: SIGPIPE" au ujumbe sawa na huo mwishoni, na ili kufuta ujumbe huu tunahitaji tu kushughulikia SIGPIPE wenyewe jinsi tunavyotaka, yaani, kimya kimya. Utgång:

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

Onyesha muktadha wa ujumbe

Mara nyingi ungependa kuona muktadha ambamo hitilafu fulani ilitokea (kwa mfano, ombi gani lilisababisha hofu, au matatizo gani yanayohusiana yalionekana kabla ya ajali), na katika grep Hii inafanywa kwa kutumia -A, -B, na -C chaguo, ambazo zinaonyesha idadi maalum ya mistari baada, kabla, na karibu na ujumbe, kwa mtiririko huo.

Kwa bahati mbaya, sijapata njia rahisi ya kufanya hivyo katika ClickHouse, kwa hivyo ili kuonyesha muktadha, ombi la ziada kama hili hutumwa kwa kila safu ya matokeo (maelezo hutegemea upangaji na ikiwa muktadha umeonyeshwa hapo awali. au baada):

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

Kwa kuwa ombi hutumwa mara tu baada ya ClickHouse kurudisha laini inayolingana, inaishia kwenye kashe na kwa ujumla ombi hutekelezwa haraka sana na hutumia CPU kidogo (kawaida ombi huchukua ~ 6 ms kwenye mashine yangu ya kawaida).

Onyesha ujumbe mpya kwa wakati halisi

Ili kuonyesha ujumbe unaoingia katika (karibu) muda halisi, tunatekeleza ombi mara moja kila baada ya sekunde chache, tukikumbuka muhuri wa muda wa mwisho ambao tulikumbana nao hapo awali.

Mifano ya amri

Amri za kawaida za logscli zinaonekanaje katika mazoezi?

Ikiwa ulipakua hifadhidata ya Amazon ambayo nilitaja mwanzoni mwa kifungu, unaweza kutekeleza amri zifuatazo:

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

marejeo

Nambari ya matumizi (bila hati) inapatikana kwenye github kwa https://github.com/YuriyNasretdinov/logscli. Ningefurahi kusikia mawazo yako juu ya wazo langu la kiolesura cha kiweko cha kutazama kumbukumbu kulingana na ClickHouse.

Chanzo: mapenzi.com

Kuongeza maoni