์ธ๊ฐ„ ๋˜๋Š” ์™ธ๊ณ„์ธ ๊ธฐ์ˆ ์„ ์œ„ํ•œ ClickHouse ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค

Aleksey Lizunov, MKB ์ •๋ณด ๊ธฐ์ˆ ๊ตญ ์›๊ฒฉ ์„œ๋น„์Šค ์ฑ„๋„ ์—ญ๋Ÿ‰ ์„ผํ„ฐ ์ฑ…์ž„์ž

์ธ๊ฐ„ ๋˜๋Š” ์™ธ๊ณ„์ธ ๊ธฐ์ˆ ์„ ์œ„ํ•œ ClickHouse ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค

ELK ์Šคํƒ(ElasticSearch, Logstash, Kibana)์˜ ๋Œ€์•ˆ์œผ๋กœ ClickHouse ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋กœ๊ทธ์šฉ ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์—ฐ๊ตฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๊ธฐ์‚ฌ์—์„œ๋Š” ClickHouse ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‚ฌ์šฉ ๊ฒฝํ—˜๊ณผ ์‹œ๋ฒ” ์šด์˜์˜ ์˜ˆ๋น„ ๊ฒฐ๊ณผ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ๋Š” ์ธ์ƒ์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค.


์ธ๊ฐ„ ๋˜๋Š” ์™ธ๊ณ„์ธ ๊ธฐ์ˆ ์„ ์œ„ํ•œ ClickHouse ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค

๋‹ค์Œ์œผ๋กœ ์‹œ์Šคํ…œ ๊ตฌ์„ฑ ๋ฐฉ๋ฒ•๊ณผ ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด์ œ ์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ „์ฒด์— ๋Œ€ํ•ด ์กฐ๊ธˆ ์ด์•ผ๊ธฐํ•˜๊ณ  ์ฃผ๋ชฉํ•ด์•ผ ํ•˜๋Š” ์ด์œ ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ClickHouse ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” Yandex์˜ ๊ณ ์„ฑ๋Šฅ ๋ถ„์„ ์ปฌ๋Ÿผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์ž…๋‹ˆ๋‹ค. Yandex ์„œ๋น„์Šค์—์„œ ์‚ฌ์šฉ๋˜๋ฉฐ ์ฒ˜์Œ์—๋Š” Yandex.Metrica์˜ ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ์ž…๋‹ˆ๋‹ค. ์˜คํ”ˆ ์†Œ์Šค ์‹œ์Šคํ…œ, ๋ฌด๋ฃŒ. ๊ฐœ๋ฐœ์ž ์ž…์žฅ์—์„œ ๋ณด๋ฉด ์—„์ฒญ๋‚˜๊ฒŒ ํฐ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ–ˆ๋Š”์ง€ ํ•ญ์ƒ ๊ถ๊ธˆํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Metrica์˜ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค ์ž์ฒด๋Š” ๋งค์šฐ ์œ ์—ฐํ•˜๊ณ  ๋น ๋ฆ…๋‹ˆ๋‹ค. ์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ฒ˜์Œ ์ ‘ํ–ˆ์„ ๋•Œ ์ธ์ƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. โ€œ๋“œ๋””์–ด! ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค! ์„ค์น˜ ํ”„๋กœ์„ธ์Šค์—์„œ ์‹œ์ž‘ํ•˜์—ฌ ์š”์ฒญ ๋ณด๋‚ด๊ธฐ๋กœ ๋๋‚ฉ๋‹ˆ๋‹ค.

์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ์ง„์ž… ์ž„๊ณ„๊ฐ’์ด ๋งค์šฐ ๋‚ฎ์Šต๋‹ˆ๋‹ค. ํ‰๊ท  ์ˆ˜์ค€์˜ ์ˆ™๋ จ๋œ ๊ฐœ๋ฐœ์ž๋„ ๋ช‡ ๋ถ„ ์•ˆ์— ์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์„ค์น˜ํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฒƒ์ด ๋ช…ํ™•ํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. Linux๋ฅผ ์ฒ˜์Œ ์ ‘ํ•˜๋Š” ์‚ฌ๋žŒ๋„ ์„ค์น˜๋ฅผ ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ณ  ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ „์— Big Data, Hadoop, Google BigTable, HDFS๋ผ๋Š” ๋‹จ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ผ๋ฐ˜ ๊ฐœ๋ฐœ์ž๋Š” ์ผ๋ถ€ ์ดˆ์ธ์ด ์ด๋Ÿฌํ•œ ์‹œ์Šคํ…œ์˜ ์„ค์ • ๋ฐ ๊ฐœ๋ฐœ์— ์ฐธ์—ฌํ•˜๋Š” ๊ฒƒ์ด ๋ช‡ ํ…Œ๋ผ๋ฐ”์ดํŠธ, ํŽ˜ํƒ€๋ฐ”์ดํŠธ์— ๊ด€ํ•œ ์•„์ด๋””์–ด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ๋‹ค๋ฉด ClickHouse์˜ ์ถœํ˜„๊ณผ ํ•จ๊ป˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค, ์šฐ๋ฆฌ๋Š” ์ด์ „์—๋Š” ๋‹ฌ์„ฑํ•  ์ˆ˜ ์—†์—ˆ๋˜ ๋ฒ”์œ„์˜ ์ž‘์—…์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ„๋‹จํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šด ๋„๊ตฌ๋ฅผ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค. ์ƒ๋‹นํžˆ ํ‰๊ท ์ ์ธ ๊ธฐ๊ณ„ ํ•œ ๋Œ€์™€ ์„ค์น˜ํ•˜๋Š” ๋ฐ XNUMX๋ถ„๋ฐ–์— ๊ฑธ๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์˜ˆ๋ฅผ ๋“ค์–ด MySql๊ณผ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์žˆ์ง€๋งŒ ์ˆ˜์‹ญ์–ต ๊ฐœ์˜ ๋ ˆ์ฝ”๋“œ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค! SQL ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํŠน์ • ์Šˆํผ ์•„์นด์ด๋ฒ„. ์‚ฌ๋žŒ๋“ค์ด ์™ธ๊ณ„์ธ์˜ ๋ฌด๊ธฐ๋ฅผ ๊ฑด๋„ค๋ฐ›์€ ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋กœ๊น… ์‹œ์Šคํ…œ ์ •๋ณด

์ •๋ณด ์ˆ˜์ง‘์„ ์œ„ํ•ด ํ‘œ์ค€ ํ˜•์‹ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ IIS ๋กœ๊ทธ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค(ํ˜„์žฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ๊ทธ๋„ ํŒŒ์‹ฑํ•˜๊ณ  ์žˆ์ง€๋งŒ ํŒŒ์ผ๋Ÿฟ ๋‹จ๊ณ„์˜ ์ฃผ์š” ๋ชฉํ‘œ๋Š” IIS ๋กœ๊ทธ ์ˆ˜์ง‘์ž…๋‹ˆ๋‹ค).

์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ด์œ ๋กœ ์šฐ๋ฆฌ๋Š” ELK ์Šคํƒ์„ ์™„์ „ํžˆ ํฌ๊ธฐํ•  ์ˆ˜ ์—†์—ˆ๊ณ , ์ž์ฒด์ ์œผ๋กœ ์ž˜ ์ž…์ฆ๋˜๊ณ  ๋งค์šฐ ์•ˆ์ •์ ์ด๊ณ  ์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜๊ฒŒ ์ž‘๋™ํ•˜๋Š” LogStash ๋ฐ Filebeat ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๊ณ„์† ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์ธ ๋กœ๊น… ์ฒด๊ณ„๋Š” ์•„๋ž˜ ๊ทธ๋ฆผ์— ๋‚˜์™€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ธ๊ฐ„ ๋˜๋Š” ์™ธ๊ณ„์ธ ๊ธฐ์ˆ ์„ ์œ„ํ•œ ClickHouse ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค

ClickHouse ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ฐ์ดํ„ฐ๋ฅผ ์“ฐ๋Š” ๊ธฐ๋Šฅ์€ ๋“œ๋ฌผ๊ฒŒ(์ดˆ๋‹น ํ•œ ๋ฒˆ) ๋Œ€๊ทœ๋ชจ ๋ฐฐ์น˜๋กœ ๋ ˆ์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ถ„๋ช…ํžˆ ClickHouse ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž‘์—…์„ ์ฒ˜์Œ ๊ฒฝํ—˜ํ•  ๋•Œ ๊ฐ€์žฅ "๋ฌธ์ œ๊ฐ€ ๋˜๋Š”" ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ์ฒด๊ณ„๊ฐ€ ์กฐ๊ธˆ ๋” ๋ณต์žกํ•ด์ง‘๋‹ˆ๋‹ค.
๋ฐ์ดํ„ฐ๋ฅผ ClickHouse์— ์ง์ ‘ ์‚ฝ์ž…ํ•˜๋Š” LogStash์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์—ฌ๊ธฐ์—์„œ ๋งŽ์€ ๋„์›€์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž์ฒด์™€ ๋™์ผํ•œ ์„œ๋ฒ„์— ๋ฐฐํฌ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ผ๋ฐ˜์ ์œผ๋กœ ๊ถŒ์žฅํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ์‹ค์šฉ์ ์ธ ๊ด€์ ์—์„œ ๋™์ผํ•œ ์„œ๋ฒ„์— ๋ฐฐํฌ๋˜๋Š” ๋™์•ˆ ๋ณ„๋„์˜ ์„œ๋ฒ„๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€์˜ ์žฅ์•  ๋˜๋Š” ๋ฆฌ์†Œ์Šค ์ถฉ๋Œ์„ ๊ด€์ฐฐํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์—๋Š” ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ ์žฌ์‹œ๋„ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ์žˆ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์‚ฝ์ž…ํ•  ์ˆ˜ ์—†๋Š” ๋ฐ์ดํ„ฐ ๋ฐฐ์น˜๋ฅผ ๋””์Šคํฌ์— ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค(ํŒŒ์ผ ํ˜•์‹์ด ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ํŽธ์ง‘ ํ›„ clickhouse-client๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ˆ˜์ •๋œ ๋ฐฐ์น˜๋ฅผ ์‰ฝ๊ฒŒ ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค).

๊ณ„ํš์— ์‚ฌ์šฉ๋œ ์†Œํ”„ํŠธ์›จ์–ด์˜ ์ „์ฒด ๋ชฉ๋ก์ด ํ‘œ์— ๋‚˜์™€ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ๋œ ์†Œํ”„ํŠธ์›จ์–ด ๋ชฉ๋ก

์ด๋ฆ„

๊ธฐ์ˆ 

๋ฐฐํฌ ๋งํฌ

NGINX

ํฌํŠธ๋ณ„ ์•ก์„ธ์Šค๋ฅผ ์ œํ•œํ•˜๊ณ  ์ธ์ฆ์„ ๊ตฌ์„ฑํ•˜๋Š” ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ

ํ˜„์žฌ ๊ณ„ํš์—์„œ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Œ

https://nginx.org/ru/download.html

https://nginx.org/download/nginx-1.16.0.tar.gz

ํŒŒ์ผ๋น„ํŠธ

ํŒŒ์ผ ๋กœ๊ทธ ์ „์†ก.

https://www.elastic.co/downloads/beats/filebeat (Windows 64๋น„ํŠธ์šฉ ๋ฐฐํฌ ํ‚คํŠธ).

https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.3.0-windows-x86_64.zip

๋กœ๊ทธ์Šคํƒœ์‹œ

๋กœ๊ทธ ์ˆ˜์ง‘๊ธฐ.

FileBeat์—์„œ ๋กœ๊ทธ๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ  RabbitMQ ๋Œ€๊ธฐ์—ด์—์„œ ๋กœ๊ทธ๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค(DMZ์— ์žˆ๋Š” ์„œ๋ฒ„์˜ ๊ฒฝ์šฐ).

https://www.elastic.co/products/logstash

https://artifacts.elastic.co/downloads/logstash/logstash-7.0.1.rpm

Logstash ์ถœ๋ ฅ ํด๋ฆญํ•˜์šฐ์Šค

์ผ๊ด„์ ์œผ๋กœ ClickHouse ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋กœ๊ทธ๋ฅผ ์ „์†กํ•˜๊ธฐ ์œ„ํ•œ Loagstash ํ”Œ๋Ÿฌ๊ทธ์ธ

https://github.com/mikechris/logstash-output-clickhouse

/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

ํด๋ฆญ ํ•˜์šฐ์Šค

๋กœ๊ทธ ์ €์žฅ https://clickhouse.yandex/docs/ru/

https://packagecloud.io/Altinity/clickhouse/packages/el/7/clickhouse-server-19.5.3.8-1.el7.x86_64.rpm

https://packagecloud.io/Altinity/clickhouse/packages/el/7/clickhouse-client-19.5.3.8-1.el7.x86_64.rpm

๋ฉ”๋ชจ. 2018๋…„ XNUMX์›”๋ถ€ํ„ฐ Yandex ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— RHEL์šฉ "์ผ๋ฐ˜" rpm ๋นŒ๋“œ๊ฐ€ ๋‚˜ํƒ€๋‚˜๋ฏ€๋กœ ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ค์น˜ ๋‹น์‹œ Altinity์—์„œ ๋งŒ๋“  ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ผ ํŒŒ๋‚˜

๋กœ๊ทธ ์‹œ๊ฐํ™”. ๋Œ€์‹œ๋ณด๋“œ ์„ค์ •

https://grafana.com/

https://grafana.com/grafana/download

Redhat & Centos(64 Bit) - ์ตœ์‹  ๋ฒ„์ „

Grafana 4.6+์šฉ ClickHouse ๋ฐ์ดํ„ฐ ์†Œ์Šค

ClickHouse ๋ฐ์ดํ„ฐ ์†Œ์Šค๊ฐ€ ํฌํ•จ๋œ Grafana์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ

https://grafana.com/plugins/vertamedia-clickhouse-datasource

https://grafana.com/api/plugins/vertamedia-clickhouse-datasource/versions/1.8.1/download

๋กœ๊ทธ์Šคํƒœ์‹œ

FileBeat์—์„œ RabbitMQ ๋Œ€๊ธฐ์—ด๋กœ ๋ผ์šฐํ„ฐ๋ฅผ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.

๋ฉ”๋ชจ. ์•ˆํƒ€๊น๊ฒŒ๋„ FileBeat๋Š” RabbitMQ๋กœ ์ง์ ‘ ์ถœ๋ ฅ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ Logstash ํ˜•์‹์˜ ์ค‘๊ฐ„ ๋งํฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

https://www.elastic.co/products/logstash

https://artifacts.elastic.co/downloads/logstash/logstash-7.0.1.rpm

RabbitMQ

๋ฉ”์‹œ์ง€ ํ. ์ด๊ฒƒ์€ DMZ์˜ ๋กœ๊ทธ ๋ฒ„ํผ์ž…๋‹ˆ๋‹ค.

https://www.rabbitmq.com/download.html

https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.7.14/rabbitmq-server-3.7.14-1.el7.noarch.rpm

Erlang ๋Ÿฐํƒ€์ž„(RabbitMQ์— ํ•„์š”)

์–ผ๋žญ ๋Ÿฐํƒ€์ž„. RabbitMQ๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

http://www.erlang.org/download.html

https://www.rabbitmq.com/install-rpm.html#install-erlang http://www.erlang.org/downloads/21.3

ClickHouse ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์žˆ๋Š” ์„œ๋ฒ„ ๊ตฌ์„ฑ์€ ๋‹ค์Œ ํ‘œ์— ๋‚˜์™€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฆ„

๊ฐ€์น˜

์ฃผ์˜

๊ตฌ์„ฑ

HDD : 40GB
RAM : 8GB
ํ”„๋กœ์„ธ์„œ: ์ฝ”์–ด 2 2Ghz

ClickHouse ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์šด์˜ ํŒ์— ์ฃผ์˜๋ฅผ ๊ธฐ์šธ์ผ ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค(https://clickhouse.yandex/docs/ru/operations/tips/)

์ผ๋ฐ˜ ์‹œ์Šคํ…œ ์†Œํ”„ํŠธ์›จ์–ด

์šด์˜ ์ฒด์ œ: Red Hat Enterprise Linux ์„œ๋ฒ„(Maipo)

JRE(์ž๋ฐ” 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 ํƒœ๊ทธ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ๋ณ„๋„์˜ ํ•„๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค(์ฟผ๋ฆฌ ๋ฌธ์ž์—ด ํ•„๋“œ์—์„œ ํ…Œ์ด๋ธ”์— ์‚ฝ์ž…ํ•˜๋Š” ๋‹จ๊ณ„์—์„œ ๊ตฌ๋ฌธ ๋ถ„์„๋จ).

๋˜ํ•œ ์‹œ์Šคํ…œ, ๊ตฌ์„ฑ ์š”์†Œ, ์„œ๋ฒ„์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ๋Ÿฌ ์‹œ์Šคํ…œ ํ•„๋“œ๊ฐ€ ํ…Œ์ด๋ธ”์— ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํ•„๋“œ์— ๋Œ€ํ•œ ์„ค๋ช…์€ ์•„๋ž˜ ํ‘œ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. ํ•˜๋‚˜์˜ ํ…Œ์ด๋ธ”์— ์—ฌ๋Ÿฌ ์‹œ์Šคํ…œ์— ๋Œ€ํ•œ ๋กœ๊ทธ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฆ„

๊ธฐ์ˆ 

์˜ˆ

fld_app_name

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜/์‹œ์Šคํ…œ ์ด๋ฆ„
์œ ํšจํ•œ ๊ฐ’:

  • site1.domain.com ์™ธ๋ถ€ ์‚ฌ์ดํŠธ 1
  • site2.domain.com ์™ธ๋ถ€ ์‚ฌ์ดํŠธ 2
  • internal-site1.domain.local ๋‚ด๋ถ€ ์‚ฌ์ดํŠธ 1

site1.domain.com

fld_app_module

์‹œ์Šคํ…œ ๋ชจ๋“ˆ
์œ ํšจํ•œ ๊ฐ’:

  • ์›น - ์›น์‚ฌ์ดํŠธ
  • svc - ์›น ์‚ฌ์ดํŠธ ์„œ๋น„์Šค
  • intgr - ํ†ตํ•ฉ ์›น ์„œ๋น„์Šค
  • bo - ๊ด€๋ฆฌ์ž(๋ฐฑ์˜คํ”ผ์Šค)

์›น

fld_website_name

IIS์˜ ์‚ฌ์ดํŠธ ์ด๋ฆ„

ํ•˜๋‚˜์˜ ์„œ๋ฒ„ ๋˜๋Š” ํ•˜๋‚˜์˜ ์‹œ์Šคํ…œ ๋ชจ๋“ˆ์˜ ์—ฌ๋Ÿฌ ์ธ์Šคํ„ด์Šค์— ์—ฌ๋Ÿฌ ์‹œ์Šคํ…œ์„ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์›น ๋ฉ”์ธ

fld_์„œ๋ฒ„_์ด๋ฆ„

์„œ๋ฒ„ ์ด๋ฆ„

web1.domain.com

fld_log_file_name

์„œ๋ฒ„์˜ ๋กœ๊ทธ ํŒŒ์ผ ๊ฒฝ๋กœ

C:inetpublogsLogFiles
W3SVC1u_ex190711.log

์ด๋ฅผ ํ†ตํ•ด Grafana์—์„œ ํšจ์œจ์ ์œผ๋กœ ๊ทธ๋ž˜ํ”„๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํŠน์ • ์‹œ์Šคํ…œ์˜ ํ”„๋ŸฐํŠธ์—”๋“œ์—์„œ ์š”์ฒญ์„ ๋ด…๋‹ˆ๋‹ค. ์ด๋Š” Yandex.Metrica์˜ ์‚ฌ์ดํŠธ ์นด์šดํ„ฐ์™€ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์€ XNUMX๊ฐœ์›” ๋™์•ˆ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•œ ํ†ต๊ณ„์ž…๋‹ˆ๋‹ค.

์‹œ์Šคํ…œ ๋ฐ ํ•ด๋‹น ๊ตฌ์„ฑ ์š”์†Œ๋ณ„๋กœ ๋ถ„๋ฅ˜๋œ ๋ ˆ์ฝ”๋“œ ์ˆ˜

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)์— ์„ค์น˜๋ฉ๋‹ˆ๋‹ค. ๊ผฌ๋ฆฌ ๋ชจ๋“œ์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค(์ฆ‰, ์ถ”๊ฐ€๋œ ๋ ˆ์ฝ”๋“œ๋งŒ ํŒŒ์ผ๋กœ ์ „์†ก). ๊ทธ๋Ÿฌ๋‚˜ ๋ณ„๋„๋กœ ์ „์ฒด ํŒŒ์ผ์„ ์ „์†กํ•˜๋„๋ก ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ „ ๋‹ฌ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•ด์•ผ ํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋กœ๊ทธ ํŒŒ์ผ์„ ํด๋”์— ๋„ฃ์œผ๋ฉด ์ „์ฒด ๋‚ด์šฉ์„ ์ฝ์Šต๋‹ˆ๋‹ค.

์„œ๋น„์Šค๊ฐ€ ์ค‘์ง€๋˜๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ ๋” ์ด์ƒ ์ €์žฅ์†Œ๋กœ ์ „์†ก๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์˜ˆ์ œ ๊ตฌ์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

ํŒŒ์ผ๋น„ํŠธ.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"

ํด๋ฆญํ•˜์šฐ์Šค. ๋กœ๊ทธ ์ €์žฅ

๋ชจ๋“  ์‹œ์Šคํ…œ์— ๋Œ€ํ•œ ๋กœ๊ทธ๋Š” ํ•˜๋‚˜์˜ ํ…Œ์ด๋ธ”์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค(๊ธฐ์‚ฌ ์‹œ์ž‘ ๋ถ€๋ถ„ ์ฐธ์กฐ). ์š”์ฒญ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” IIS ๋กœ๊ทธ, Apache ๋ฐ nginx ๋กœ๊ทธ์™€ ๊ฐ™์€ ๋‹ค์–‘ํ•œ ํ˜•์‹์— ๋Œ€ํ•ด ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์˜ค๋ฅ˜, ์ •๋ณด ๋ฉ”์‹œ์ง€, ๊ฒฝ๊ณ ๊ฐ€ ๊ธฐ๋ก๋˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ๊ทธ์˜ ๊ฒฝ์šฐ ์ ์ ˆํ•œ ๊ตฌ์กฐ๋กœ ๋ณ„๋„์˜ ํ…Œ์ด๋ธ”์ด ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค(ํ˜„์žฌ ์„ค๊ณ„ ๋‹จ๊ณ„).

ํ…Œ์ด๋ธ”์„ ์„ค๊ณ„ํ•  ๋•Œ ๊ธฐ๋ณธ ํ‚ค(์ €์žฅ ์ค‘์— ๋ฐ์ดํ„ฐ๊ฐ€ ์ •๋ ฌ๋˜๋Š” ํ‚ค)๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ์••์ถ• ์ •๋„์™€ ์ฟผ๋ฆฌ ์†๋„๋Š” ์ด์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. ์ด ์˜ˆ์—์„œ ํ•ต์‹ฌ์€
ORDER BY(fld_app_name, fld_app_module, logdatetime)
์ฆ‰, ์‹œ์Šคํ…œ ์ด๋ฆ„, ์‹œ์Šคํ…œ ๊ตฌ์„ฑ ์š”์†Œ ์ด๋ฆ„ ๋ฐ ์ด๋ฒคํŠธ ๋‚ ์งœ์ž…๋‹ˆ๋‹ค. ์ฒ˜์Œ์—๋Š” ์ด๋ฒคํŠธ ๋‚ ์งœ๊ฐ€ ๋จผ์ €์˜€์Šต๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰ ์œ„์น˜๋กœ ์ด๋™ํ•œ ํ›„ ์ฟผ๋ฆฌ๊ฐ€ ์•ฝ ๋‘ ๋ฐฐ ๋น ๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ํ‚ค๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ClickHouse๊ฐ€ ๋””์Šคํฌ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ์ •๋ ฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ…Œ์ด๋ธ”์„ ๋‹ค์‹œ ๋งŒ๋“ค๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ๋กœ๋“œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ฌด๊ฑฐ์šด ์ž‘์—…์ด๋ฏ€๋กœ ์ •๋ ฌ ํ‚ค์— ๋ฌด์—‡์„ ํฌํ•จํ•ด์•ผ ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด ๋งŽ์ด ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

LowCardinality ๋ฐ์ดํ„ฐ ์œ ํ˜•์ด ๋น„๊ต์  ์ตœ์‹  ๋ฒ„์ „์— ๋“ฑ์žฅํ–ˆ๋‹ค๋Š” ์ ๋„ ์ฃผ๋ชฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์นด๋””๋„๋ฆฌํ‹ฐ๊ฐ€ ๋‚ฎ์€ ํ•„๋“œ(์„ ํƒ ์‚ฌํ•ญ์ด ๊ฑฐ์˜ ์—†์Œ)์— ๋Œ€ํ•ด ์••์ถ•๋œ ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๊ฐ€ ํฌ๊ฒŒ ์ค„์–ด๋“ญ๋‹ˆ๋‹ค.

ํ˜„์žฌ 19.6 ๋ฒ„์ „์„ ์‚ฌ์šฉ ์ค‘์ด๋ฉฐ ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ์—…๋ฐ์ดํŠธ๋ฅผ ์‹œ๋„ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Adaptive Granularity, Skipping index ๋ฐ DoubleDelta ์ฝ”๋ฑ๊ณผ ๊ฐ™์€ ๋†€๋ผ์šด ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ ์„ค์น˜ ์ค‘์— ๋กœ๊น… ์ˆ˜์ค€์€ ์ถ”์ ์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ๋กœ๊ทธ๋Š” ํšŒ์ „ ๋ฐ ๋ณด๊ด€๋˜์ง€๋งŒ ๋™์‹œ์— ์ตœ๋Œ€ XNUMXGB๊นŒ์ง€ ํ™•์žฅ๋ฉ๋‹ˆ๋‹ค. ํ•„์š”ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๊ฒฝ๊ณ  ์ˆ˜์ค€์„ ์„ค์ •ํ•˜๋ฉด ๋กœ๊ทธ ํฌ๊ธฐ๊ฐ€ ํฌ๊ฒŒ ์ค„์–ด๋“ญ๋‹ˆ๋‹ค. ๋กœ๊น… ์„ค์ •์€ 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 ๋Œ€๊ธฐ์—ด๋กœ ๋ผ์šฐํŒ…ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ๋‘ ๊ฐ€์ง€ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ์•ˆํƒ€๊น๊ฒŒ๋„ FileBeat์—๋Š” RabbitMQ์— ์ง์ ‘ ์“ธ ์ˆ˜ ์žˆ๋Š” ์ถœ๋ ฅ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  github์˜ ๋ฌธ์ œ๋กœ ํŒ๋‹จ๋˜๋Š” ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์€ ๊ตฌํ˜„ ๊ณ„ํš์ด ์—†์Šต๋‹ˆ๋‹ค. Kafka์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์žˆ์ง€๋งŒ ์–ด๋–ค ์ด์œ ๋กœ ์ง‘์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  2. 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 ํ•„ํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํšจ์œจ์„ฑ์„ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ์•ฝ๊ฐ„ ์กฐ์ •ํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ํ•„ํ„ฐ ํ•„๋“œ์— ์„ค์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ WHERE ํ˜•์‹( uriStem = ยป AND uriStem != ยป )์—์„œ ์กฐ๊ฑด์„ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ธฐ๋ฅผ ์›ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ClickHouse๋Š” uriStem ์—ด์„ ์ฝ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์šฐ๋ฆฌ๋Š” ๋‹ค๋ฅธ ์˜ต์…˜์„ ์‹œ๋„ํ–ˆ๊ณ  ๊ฒฐ๊ตญ ํ”Œ๋Ÿฌ๊ทธ์ธ($valueIfEmpty ๋งคํฌ๋กœ)์„ ์ˆ˜์ •ํ•˜์—ฌ ๋นˆ ๊ฐ’์˜ ๊ฒฝ์šฐ ์—ด ์ž์ฒด๋ฅผ ์–ธ๊ธ‰ํ•˜์ง€ ์•Š๊ณ  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์— ๋น„ํ•ด ๋กœ๊ทธ ์ €์žฅ ๋ฐ ์ฒ˜๋ฆฌ ๋น„์šฉ์ด XNUMX~XNUMX๋ฐฐ ์ •๋„ ์ ˆ๊ฐ๋  ๊ฒƒ์œผ๋กœ ์ถ”์ •๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, ํ˜„์žฌ ๋ฐ์ดํ„ฐ ์–‘์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ์‹œ์Šคํ…œ์˜ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์„ค์ •ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ClickHouse๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ํ•˜๋‚˜์˜ ์ €์ „๋ ฅ ์‹œ์Šคํ…œ์ด๋ฉด ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ, ๋ฌผ๋ก  ElasticSearch์—๋Š” ์˜จ๋””์Šคํฌ ๋ฐ์ดํ„ฐ ์••์ถ• ๋ฉ”์ปค๋‹ˆ์ฆ˜๊ณผ ๋ฆฌ์†Œ์Šค ์†Œ๋น„๋ฅผ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ๋Š” ๊ธฐํƒ€ ๊ธฐ๋Šฅ๋„ ์žˆ์ง€๋งŒ ClickHouse์— ๋น„ํ•ด ๋น„์šฉ์ด ๋” ๋งŽ์ด ๋“ญ๋‹ˆ๋‹ค.

ํŠน๋ณ„ํ•œ ์ตœ์ ํ™” ์—†์ด ๊ธฐ๋ณธ ์„ค์ •์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์„ ํƒํ•˜๋ฉด ๋†€๋ผ์šด ์†๋„๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์•„์ง ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์ง€๋Š” ์•Š์ง€๋งŒ(์•ฝ 200์–ต ๋ ˆ์ฝ”๋“œ) ์„œ๋ฒ„ ์ž์ฒด๊ฐ€ ์•ฝํ•ฉ๋‹ˆ๋‹ค. ํ–ฅํ›„ ๋กœ๊ทธ ์ €์žฅ๊ณผ ๊ด€๋ จ๋˜์ง€ ์•Š์€ ๋‹ค๋ฅธ ์šฉ๋„๋กœ ์ด ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์—”๋“œํˆฌ์—”๋“œ ๋ถ„์„, ๋ณด์•ˆ ๋ถ„์•ผ, ๊ธฐ๊ณ„ ํ•™์Šต์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ์ฐฌ๋ฐ˜ ์–‘๋ก ์— ๋Œ€ํ•ด ์กฐ๊ธˆ.

์ฃ„์ˆ˜ ํŒ€์€

  1. ๋Œ€๊ทœ๋ชจ ์ผ๊ด„ ์ฒ˜๋ฆฌ๋กœ ๋ ˆ์ฝ”๋“œ๋ฅผ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. ํ•œํŽธ์œผ๋กœ ์ด๊ฒƒ์€ ๊ธฐ๋Šฅ์ด์ง€๋งŒ ์—ฌ์ „ํžˆ ๋ ˆ์ฝ”๋“œ ๋ฒ„ํผ๋ง์„ ์œ„ํ•œ ์ถ”๊ฐ€ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ž‘์—…์ด ํ•ญ์ƒ ์‰ฌ์šด ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ์—ฌ์ „ํžˆ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚˜๋Š” ๊ณ„ํš์„ ๋‹จ์ˆœํ™”ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
  2. ์ผ๋ถ€ ์ด๊ตญ์ ์ธ ๊ธฐ๋Šฅ์ด๋‚˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์€ ์ข…์ข… ์ƒˆ ๋ฒ„์ „์—์„œ ์ค‘๋‹จ๋ฉ๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ์šฐ๋ ค๊ฐ€ ์ƒ๊ธฐ๊ณ  ์ƒˆ ๋ฒ„์ „์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋ ค๋Š” ์š•๊ตฌ๊ฐ€ ์ค„์–ด๋“ญ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Kafka ํ…Œ์ด๋ธ” ์—”์ง„์€ ์†Œ๋น„์ž๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๊ณ  Kafka์—์„œ ์ง์ ‘ ์ด๋ฒคํŠธ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๋งค์šฐ ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ github์˜ ์ด์Šˆ ์ˆ˜๋กœ ํŒ๋‹จํ•  ๋•Œ, ์šฐ๋ฆฌ๋Š” ์ด ์—”์ง„์„ ์ƒ์‚ฐ์— ์‚ฌ์šฉํ•˜์ง€ ์•Š๋„๋ก ์—ฌ์ „ํžˆ ์กฐ์‹ฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ฐ‘์ž๊ธฐ ์˜†์œผ๋กœ ์ œ์Šค์ณ๋ฅผ ํ•˜์ง€ ์•Š๊ณ  ์ฃผ์š” ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ์ •์ ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

ํ”„๋กœ

  1. ๋Š๋ ค์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  2. ๋‚ฎ์€ ์ง„์ž… ์ž„๊ณ„ ๊ฐ’.
  3. ์˜คํ”ˆ ์†Œ์Šค.
  4. ๋ฌด๋ฃŒ.
  5. ์ž˜ ํ™•์žฅ๋จ(์ฆ‰์‹œ ์ƒค๋”ฉ/๋ณต์ œ)
  6. ํ†ต์‹ ๋ถ€๊ฐ€ ๊ถŒ์žฅํ•˜๋Š” ๋Ÿฌ์‹œ์•„ ์†Œํ”„ํŠธ์›จ์–ด ๋“ฑ๋ก๋ถ€์— ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.
  7. Yandex์˜ ๊ณต์‹ ์ง€์›์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€