Aleksey Lizunov, MKB ์ ๋ณด ๊ธฐ์ ๊ตญ ์๊ฒฉ ์๋น์ค ์ฑ๋ ์ญ๋ ์ผํฐ ์ฑ ์์
ELK ์คํ(ElasticSearch, Logstash, Kibana)์ ๋์์ผ๋ก 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์ ์ง์ ์ฝ์
ํ๋ LogStash์ฉ ํ๋ฌ๊ทธ์ธ์ด ์ฌ๊ธฐ์์ ๋ง์ ๋์์ด ๋์์ต๋๋ค. ์ด ๊ตฌ์ฑ ์์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ฒด์ ๋์ผํ ์๋ฒ์ ๋ฐฐํฌ๋ฉ๋๋ค. ๋ฐ๋ผ์ ์ผ๋ฐ์ ์ผ๋ก ๊ถ์ฅํ์ง๋ ์์ง๋ง ์ค์ฉ์ ์ธ ๊ด์ ์์ ๋์ผํ ์๋ฒ์ ๋ฐฐํฌ๋๋ ๋์ ๋ณ๋์ ์๋ฒ๋ฅผ ์์ฑํ์ง ์๋๋ก ํฉ๋๋ค. ์ฐ๋ฆฌ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ฅ์ ๋๋ ๋ฆฌ์์ค ์ถฉ๋์ ๊ด์ฐฐํ์ง ์์์ต๋๋ค. ๋ํ ํ๋ฌ๊ทธ์ธ์๋ ์ค๋ฅ ๋ฐ์ ์ ์ฌ์๋ ๋ฉ์ปค๋์ฆ์ด ์๋ค๋ ์ ์ ์ ์ํด์ผ ํฉ๋๋ค. ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ํ๋ฌ๊ทธ์ธ์ ์ฝ์
ํ ์ ์๋ ๋ฐ์ดํฐ ๋ฐฐ์น๋ฅผ ๋์คํฌ์ ๊ธฐ๋กํฉ๋๋ค(ํ์ผ ํ์์ด ํธ๋ฆฌํฉ๋๋ค. ํธ์ง ํ clickhouse-client๋ฅผ ์ฌ์ฉํ์ฌ ์์ ๋ ๋ฐฐ์น๋ฅผ ์ฝ๊ฒ ์ฝ์
ํ ์ ์์ต๋๋ค).
๊ณํ์ ์ฌ์ฉ๋ ์ํํธ์จ์ด์ ์ ์ฒด ๋ชฉ๋ก์ด ํ์ ๋์ ์์ต๋๋ค.
์ฌ์ฉ๋ ์ํํธ์จ์ด ๋ชฉ๋ก
์ด๋ฆ
๊ธฐ์
๋ฐฐํฌ ๋งํฌ
NGINX
ํฌํธ๋ณ ์ก์ธ์ค๋ฅผ ์ ํํ๊ณ ์ธ์ฆ์ ๊ตฌ์ฑํ๋ ๋ฆฌ๋ฒ์ค ํ๋ก์
ํ์ฌ ๊ณํ์์ ์ฌ์ฉ๋์ง ์์
ํ์ผ๋นํธ
ํ์ผ ๋ก๊ทธ ์ ์ก.
๋ก๊ทธ์คํ์
๋ก๊ทธ ์์ง๊ธฐ.
FileBeat์์ ๋ก๊ทธ๋ฅผ ์์งํ๊ณ RabbitMQ ๋๊ธฐ์ด์์ ๋ก๊ทธ๋ฅผ ์์งํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค(DMZ์ ์๋ ์๋ฒ์ ๊ฒฝ์ฐ).
Logstash ์ถ๋ ฅ ํด๋ฆญํ์ฐ์ค
์ผ๊ด์ ์ผ๋ก 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๋ XNUMX์๋ถํฐ Yandex ๋ฆฌํฌ์งํ ๋ฆฌ์ RHEL์ฉ "์ผ๋ฐ" rpm ๋น๋๊ฐ ๋ํ๋๋ฏ๋ก ์ฌ์ฉํด ๋ณผ ์ ์์ต๋๋ค. ์ค์น ๋น์ Altinity์์ ๋ง๋ ํจํค์ง๋ฅผ ์ฌ์ฉํ๊ณ ์์์ต๋๋ค.
๊ทธ๋ผ ํ๋
๋ก๊ทธ ์๊ฐํ. ๋์๋ณด๋ ์ค์
Redhat & Centos(64 Bit) - ์ต์ ๋ฒ์
Grafana 4.6+์ฉ ClickHouse ๋ฐ์ดํฐ ์์ค
ClickHouse ๋ฐ์ดํฐ ์์ค๊ฐ ํฌํจ๋ Grafana์ฉ ํ๋ฌ๊ทธ์ธ
๋ก๊ทธ์คํ์
FileBeat์์ RabbitMQ ๋๊ธฐ์ด๋ก ๋ผ์ฐํฐ๋ฅผ ๊ธฐ๋กํฉ๋๋ค.
๋ฉ๋ชจ. ์ํ๊น๊ฒ๋ FileBeat๋ RabbitMQ๋ก ์ง์ ์ถ๋ ฅ๋์ง ์์ผ๋ฏ๋ก Logstash ํ์์ ์ค๊ฐ ๋งํฌ๊ฐ ํ์ํฉ๋๋ค.
RabbitMQ
๋ฉ์์ง ํ. ์ด๊ฒ์ DMZ์ ๋ก๊ทธ ๋ฒํผ์ ๋๋ค.
Erlang ๋ฐํ์(RabbitMQ์ ํ์)
์ผ๋ญ ๋ฐํ์. RabbitMQ๊ฐ ์๋ํ๋ ๋ฐ ํ์ํฉ๋๋ค.
ClickHouse ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์๋ ์๋ฒ ๊ตฌ์ฑ์ ๋ค์ ํ์ ๋์ ์์ต๋๋ค.
์ด๋ฆ
๊ฐ์น
์ฃผ์
๊ตฌ์ฑ
HDD : 40GB
RAM : 8GB
ํ๋ก์ธ์: ์ฝ์ด 2 2Ghz
ClickHouse ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ด์ ํ์ ์ฃผ์๋ฅผ ๊ธฐ์ธ์ผ ํ์๊ฐ ์์ต๋๋ค(
์ผ๋ฐ ์์คํ ์ํํธ์จ์ด
์ด์ ์ฒด์ : 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 ๋๊ธฐ์ด๋ก ๋ผ์ฐํ ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ์ฌ๊ธฐ์๋ ๋ ๊ฐ์ง ์ฌํญ์ด ์์ต๋๋ค.
- ์ํ๊น๊ฒ๋ 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 ํํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ํจ์จ์ฑ์ ๊ฐ์ ํ๊ธฐ ์ํด ์ฝ๊ฐ ์กฐ์ ํด์ผ ํ์ต๋๋ค.
์๋ฅผ ๋ค์ด ๋ณ์๋ฅผ ์ฌ์ฉํ๊ณ ํํฐ ํ๋์ ์ค์ ๋์ง ์์ ๊ฒฝ์ฐ 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์ต ๋ ์ฝ๋) ์๋ฒ ์์ฒด๊ฐ ์ฝํฉ๋๋ค. ํฅํ ๋ก๊ทธ ์ ์ฅ๊ณผ ๊ด๋ จ๋์ง ์์ ๋ค๋ฅธ ์ฉ๋๋ก ์ด ๋๊ตฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ์๋ํฌ์๋ ๋ถ์, ๋ณด์ ๋ถ์ผ, ๊ธฐ๊ณ ํ์ต์ด ์์ต๋๋ค.
๋ง์ง๋ง์ผ๋ก ์ฐฌ๋ฐ ์๋ก ์ ๋ํด ์กฐ๊ธ.
์ฃ์ ํ์
- ๋๊ท๋ชจ ์ผ๊ด ์ฒ๋ฆฌ๋ก ๋ ์ฝ๋๋ฅผ ๋ก๋ํฉ๋๋ค. ํํธ์ผ๋ก ์ด๊ฒ์ ๊ธฐ๋ฅ์ด์ง๋ง ์ฌ์ ํ ๋ ์ฝ๋ ๋ฒํผ๋ง์ ์ํ ์ถ๊ฐ ๊ตฌ์ฑ ์์๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ์ด ์์ ์ด ํญ์ ์ฌ์ด ๊ฒ์ ์๋์ง๋ง ์ฌ์ ํ ํด๊ฒฐํ ์ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋๋ ๊ณํ์ ๋จ์ํํ๊ณ ์ถ์ต๋๋ค.
- ์ผ๋ถ ์ด๊ตญ์ ์ธ ๊ธฐ๋ฅ์ด๋ ์๋ก์ด ๊ธฐ๋ฅ์ ์ข ์ข ์ ๋ฒ์ ์์ ์ค๋จ๋ฉ๋๋ค. ์ด๋ก ์ธํด ์ฐ๋ ค๊ฐ ์๊ธฐ๊ณ ์ ๋ฒ์ ์ผ๋ก ์ ๊ทธ๋ ์ด๋ํ๋ ค๋ ์๊ตฌ๊ฐ ์ค์ด๋ญ๋๋ค. ์๋ฅผ ๋ค์ด Kafka ํ ์ด๋ธ ์์ง์ ์๋น์๋ฅผ ๊ตฌํํ์ง ์๊ณ Kafka์์ ์ง์ ์ด๋ฒคํธ๋ฅผ ์ฝ์ ์ ์๋ ๋งค์ฐ ์ ์ฉํ ๊ธฐ๋ฅ์ ๋๋ค. ํ์ง๋ง github์ ์ด์ ์๋ก ํ๋จํ ๋, ์ฐ๋ฆฌ๋ ์ด ์์ง์ ์์ฐ์ ์ฌ์ฉํ์ง ์๋๋ก ์ฌ์ ํ ์กฐ์ฌํ๊ณ ์์ต๋๋ค. ํ์ง๋ง ๊ฐ์๊ธฐ ์์ผ๋ก ์ ์ค์ณ๋ฅผ ํ์ง ์๊ณ ์ฃผ์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ฉด ์์ ์ ์ผ๋ก ๋์ํ๋ค.
ํ๋ก
- ๋๋ ค์ง์ง ์์ต๋๋ค.
- ๋ฎ์ ์ง์ ์๊ณ ๊ฐ.
- ์คํ ์์ค.
- ๋ฌด๋ฃ.
- ์ ํ์ฅ๋จ(์ฆ์ ์ค๋ฉ/๋ณต์ )
- ํต์ ๋ถ๊ฐ ๊ถ์ฅํ๋ ๋ฌ์์ ์ํํธ์จ์ด ๋ฑ๋ก๋ถ์ ํฌํจ๋ฉ๋๋ค.
- Yandex์ ๊ณต์ ์ง์์ด ์์ต๋๋ค.
์ถ์ฒ : habr.com