ClickHouse Database for Humans፣ ወይም Alien Technologies

አሌክሲ ሊዙኖቭ፣ የ MKB የመረጃ ቴክኖሎጂዎች ዳይሬክቶሬት የርቀት አገልግሎት ቻናሎች የብቃት ማእከል ኃላፊ

ClickHouse Database for Humans፣ ወይም Alien Technologies

ከኤልኬ ቁልል (ElasticSearch, Logstash, Kibana) እንደ አማራጭ የ ClickHouse ዳታቤዝ የምዝግብ ማስታወሻዎችን እንደ የውሂብ ማከማቻ ስለመጠቀም ምርምር እያደረግን ነው።

በዚህ ጽሑፍ ውስጥ ስለ ClickHouse ዳታቤዝ ስለመጠቀም ያለንን ልምድ እና የአብራሪ ሥራ የመጀመሪያ ውጤቶችን መነጋገር እንፈልጋለን። ውጤቶቹ አስደናቂ እንደነበሩ ወዲያውኑ ልብ ሊባል ይገባል.


ClickHouse Database for Humans፣ ወይም Alien Technologies

በመቀጠል, የእኛ ስርዓት እንዴት እንደሚዋቀር, እና ምን አይነት አካላትን እንደሚያካትት በበለጠ ዝርዝር እንገልፃለን. አሁን ግን ስለዚህ የውሂብ ጎታ በአጠቃላይ ትንሽ ማውራት እፈልጋለሁ, እና ለምን ትኩረት መስጠት እንዳለበት. የ ClickHouse ዳታቤዝ ከ Yandex ከፍተኛ አፈጻጸም ያለው የትንታኔ ዓምድ ዳታቤዝ ነው። በ Yandex አገልግሎቶች ውስጥ ጥቅም ላይ ይውላል, መጀመሪያ ላይ ለ Yandex.Metrica ዋናው የውሂብ ማከማቻ ነው. ክፍት ምንጭ ስርዓት ፣ ነፃ። ከገንቢ እይታ አንጻር፣ እንዴት እንደተገበሩት ሁልጊዜ አስብ ነበር፣ ምክንያቱም በሚያስደንቅ ሁኔታ ትልቅ መረጃ አለ። እና የሜትሪክስ የተጠቃሚ በይነገጽ ራሱ በጣም ተለዋዋጭ እና ፈጣን ነው። ከዚህ የመረጃ ቋት ጋር ለመጀመሪያ ጊዜ ሲያውቁ ፣ ግንዛቤው “ደህና ፣ በመጨረሻ! ለህዝብ የተሰራ! ከመጫን ሂደቱ ጀምሮ እና በመላክ ጥያቄዎችን ያበቃል.

ይህ የውሂብ ጎታ በጣም ዝቅተኛ የመግቢያ ገደብ አለው። አማካኝ ችሎታ ያለው ገንቢ እንኳን ይህን ዳታቤዝ በጥቂት ደቂቃዎች ውስጥ ጭኖ መጠቀም ሊጀምር ይችላል። ሁሉም ነገር በግልጽ ይሰራል. ለሊኑክስ አዲስ የሆኑ ሰዎች እንኳን መጫኑን በፍጥነት ማስተናገድ እና ቀላል ስራዎችን ማከናወን ይችላሉ። ቀደም ሲል ፣ ቢግ ዳታ ፣ ሃዱፕ ፣ ጎግል ቢግ ቴብል ፣ ኤችዲኤፍኤስ በሚሉት ቃላት አንድ ተራ ገንቢ ስለ አንዳንድ ቴራባይት ፣ ፔታባይት ፣ አንዳንድ ከሰው በላይ የሆኑ ሰዎች ለእነዚህ ስርዓቶች ቅንጅቶች እና ልማት ውስጥ ይሳተፋሉ የሚል ሀሳብ ነበረው ፣ ከዚያ የ ClickHouse መምጣት ጋር። የውሂብ ጎታ፣ ከዚህ ቀደም ሊደረስ የማይችለውን የተግባር ብዛት መፍታት የሚችሉበት ቀላል እና ለመረዳት የሚቻል መሳሪያ አግኝተናል። ለመጫን አንድ ትክክለኛ አማካይ ማሽን እና አምስት ደቂቃ ብቻ ነው የሚወስደው። ያም ማለት እንደ MySql ያሉ የውሂብ ጎታ አግኝተናል ነገር ግን በቢሊዮኖች የሚቆጠሩ መዝገቦችን ለማከማቸት ብቻ ነው! ከSQL ቋንቋ ጋር የተወሰነ ልዕለ-መዝገብ ቤት። ሰዎች የባዕድ ጦር መሳሪያ እንደተሰጣቸው ነው።

ስለ እኛ የምዝግብ ማስታወሻ ስርዓት

መረጃን ለመሰብሰብ የ IIS ሎግ ፋይሎች መደበኛ ቅርጸት የድር መተግበሪያዎች ጥቅም ላይ ይውላሉ (በአሁኑ ጊዜ የመተግበሪያ ምዝግብ ማስታወሻዎችን እየተመለከትን ነው ነገር ግን በሙከራ ደረጃ ላይ ያለው ዋናው ግብ የ IIS ምዝግብ ማስታወሻዎችን መሰብሰብ ነው)።

በተለያዩ ምክንያቶች የ ELK ቁልል ሙሉ በሙሉ መተው አልቻልንም፣ እና እራሳቸውን በሚገባ ያረጋገጡ እና በትክክል የሚሰሩትን LogStash እና Filebeat ክፍሎችን መጠቀማችንን ቀጥለናል።

አጠቃላይ የምዝገባ እቅድ ከዚህ በታች ባለው ስእል ውስጥ ይታያል።

ClickHouse Database for Humans፣ ወይም Alien Technologies

ወደ ClickHouse ዳታቤዝ ውሂብ የመፃፍ ባህሪ ብዙ ጊዜ (በሴኮንድ አንድ ጊዜ) መዝገቦችን በትላልቅ ስብስቦች ውስጥ ማስገባት ነው። ይህ ከክሊክ ሃውስ ዳታቤዝ ጋር ለመጀመሪያ ጊዜ ሲሰሩ የሚያጋጥሙት በጣም “ችግር ያለበት” ክፍል ነው፡ እቅዱ ትንሽ የተወሳሰበ ይሆናል።
የ LogStash ፕለጊን ፣ መረጃን በቀጥታ ወደ ClickHouse የሚያስገባ ፣ እዚህ ብዙ ረድቷል። ይህ አካል እንደ ዳታቤዝ ራሱ በተመሳሳይ አገልጋይ ላይ ተዘርግቷል። ስለዚህ, በአጠቃላይ አነጋገር, በተመሳሳይ አገልጋይ ላይ በሚሰራጭበት ጊዜ የተለያዩ አገልጋዮችን እንዳያመርቱ, ከተግባራዊ እይታ አንጻር ግን እንዲያደርጉት አይመከርም. ከመረጃ ቋቱ ጋር ምንም አይነት ውድቀቶች ወይም የንብረት ግጭቶች አላየንም። በተጨማሪም, ፕለጊኑ ስህተቶች ካሉ እንደገና የመሞከር ዘዴ እንዳለው ልብ ሊባል ይገባል. እና ስህተቶች ካሉ, ፕለጊኑ ሊገባ የማይችል የውሂብ ስብስብ ወደ ዲስክ ይጽፋል (የፋይል ቅርጸቱ ምቹ ነው: ከአርትዖት በኋላ የተስተካከለውን ክሊክ ቤት-ደንበኛን በመጠቀም በቀላሉ ማስገባት ይችላሉ).

በእቅዱ ውስጥ ጥቅም ላይ የዋሉ የሶፍትዌር ሙሉ ዝርዝር በሠንጠረዥ ውስጥ ቀርቧል-

ያገለገሉ ሶፍትዌሮች ዝርዝር

ርዕስ

መግለጫ

የስርጭት አገናኝ

NGINX

በወደቦች መዳረሻን ለመገደብ እና ፍቃድን ለማደራጀት በግልባጭ ተኪ

በአሁኑ ጊዜ በእቅዱ ውስጥ ጥቅም ላይ አልዋለም

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

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

FileBeat

የፋይል መዝገቦችን ማስተላለፍ.

https://www.elastic.co/downloads/beats/filebeat (ለዊንዶውስ 64 ቢት ማከፋፈያ)።

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

logstash

የምዝግብ ማስታወሻ ሰብሳቢ.

ምዝግብ ማስታወሻዎችን ከፋይልቢት ለመሰብሰብ፣ እንዲሁም ከ RabbitMQ ወረፋ (በዲኤምዚኤስ ውስጥ ላሉ አገልጋዮች) ምዝግብ ማስታወሻዎችን ለመሰብሰብ ይጠቅማል።

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

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

Logstash-ውጤት-ክሊክ ሃውስ

Loagstash plugin ምዝግብ ማስታወሻዎችን ወደ ClickHouse ዳታቤዝ በቡድን ለማዛወር

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 ጀምሮ ለ RHEL "መደበኛ" rpm ይገነባል በ Yandex ማከማቻ ውስጥ ታየ, ስለዚህ እነሱን ለመጠቀም መሞከር ይችላሉ. በመጫን ጊዜ በአልቲኒቲ የተገነቡ ጥቅሎችን እንጠቀም ነበር.

ግራፋና

የምዝግብ ማስታወሻ እይታ. ዳሽቦርዶችን በማዘጋጀት ላይ

https://grafana.com/

https://grafana.com/grafana/download

Redhat & Centos(64 ቢት) - የቅርብ ጊዜ ስሪት

ClickHouse የውሂብ ምንጭ ለ Grafana 4.6+

ለ Grafana ተሰኪ በ ClickHouse የውሂብ ምንጭ

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

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

logstash

ራውተርን ከፋይልቢት ወደ 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 Runtime (ለ 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
ራም: 8 ጊባ
ፕሮሰሰር: ኮር 2 2Ghz

የ ClickHouse ዳታቤዝ (ክሊክሃውስ) የመረጃ ቋቱን ለማስኬድ ምክሮችን ትኩረት መስጠት ያስፈልጋል ።https://clickhouse.yandex/docs/ru/operations/tips/)

አጠቃላይ የስርዓት ሶፍትዌር

ስርዓተ ክወና፡ Red Hat Enterprise Linux Server (Maipo)

ጄአርአይ (ጃቫ 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-tags ለማከማቸት የተለዩ መስኮች እንዳሉ እናስተውላለን (ከጥያቄው ሕብረቁምፊ መስክ ወደ ጠረጴዛው ውስጥ በሚያስገቡበት ደረጃ ላይ ይለጠፋሉ).

እንዲሁም ስለ ስርዓቶች, አካላት, አገልጋዮች መረጃን ለማከማቸት ብዙ የስርዓት መስኮች ወደ ጠረጴዛው ተጨምረዋል. የእነዚህን መስኮች መግለጫ ለማግኘት ከዚህ በታች ያለውን ሰንጠረዥ ይመልከቱ። በአንድ ሠንጠረዥ ውስጥ ለብዙ ስርዓቶች ምዝግብ ማስታወሻዎችን እናከማቻለን.

ርዕስ

መግለጫ

ለምሳሌ:

fld_app_ስም

የመተግበሪያ / የስርዓት ስም
ትክክለኛ እሴቶች፡-

  • site1.domain.com ውጫዊ ጣቢያ 1
  • site2.domain.com ውጫዊ ጣቢያ 2
  • internal-site1.domain.local Internal site 1

site1.domain.com

fld_app_module

የስርዓት ሞጁል
ትክክለኛ እሴቶች፡-

  • ድር - ድር ጣቢያ
  • svc - የድር ጣቢያ አገልግሎት
  • intgr - የውህደት ድር አገልግሎት
  • ቦ - አስተዳዳሪ (BackOffice)

የድር

fld_ድረ-ገጽ_ስም

በ IIS ውስጥ የጣቢያ ስም

ብዙ ስርዓቶች በአንድ አገልጋይ ላይ ሊሰማሩ ይችላሉ፣ ወይም በአንድ የስርዓት ሞጁል ውስጥ ብዙ አጋጣሚዎች

የድር ዋና

fld_አገልጋይ_ስም

የአገልጋይ ስም

web1.domain.com

fld_log_ፋይል_ስም

በአገልጋዩ ላይ ወደ የምዝግብ ማስታወሻ ፋይል የሚወስደው መንገድ

ሐ፡ inetpublogsLogFiles
W3SVC1u_ex190711.ሎግ

ይህ በግራፋና ውስጥ ግራፎችን በብቃት እንዲገነቡ ያስችልዎታል። ለምሳሌ፣ ከአንድ የተወሰነ ስርዓት ፊት ለፊት የሚመጡ ጥያቄዎችን ይመልከቱ። ይህ በ Yandex.Metrica ውስጥ ካለው የጣቢያ ቆጣሪ ጋር ተመሳሳይ ነው።

ለሁለት ወራት ያህል የውሂብ ጎታ አጠቃቀምን በተመለከተ አንዳንድ ስታቲስቲክስ እነሆ።

በስርዓቶች እና ክፍሎቻቸው የተከፋፈሉ መዝገቦች ብዛት

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)። በጅራት ሁነታ ይሰራል (ማለትም የተጨመሩትን መዝገቦች ወደ ፋይሉ ብቻ ያስተላልፋል). ነገር ግን በተናጥል ሁሉንም ፋይሎች ለማስተላለፍ ሊዋቀር ይችላል. ካለፉት ወራት ውሂብ ማውረድ ሲፈልጉ ይህ ጠቃሚ ነው። የሎግ ፋይሉን ወደ ማህደር ማስገባት ብቻ ነው እና ሙሉ በሙሉ ያነበዋል።

አገልግሎቱ ሲቆም ውሂቡ ከአሁን በኋላ ወደ ማከማቻው አይተላለፍም።

የምሳሌ ውቅር ይህን ይመስላል።

filebeat.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. የምዝግብ ማስታወሻ ሰብሳቢ

ይህ አካል የተነደፈው ከፋይልቢት (ወይም በ 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"
        }
    }
 
}

pipelines.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 logs. ለመተግበሪያ ምዝግብ ማስታወሻዎች, ለምሳሌ, ስህተቶች, የመረጃ መልዕክቶች, ማስጠንቀቂያዎች የተመዘገቡበት, የተለየ ሠንጠረዥ በተገቢው መዋቅር (በአሁኑ ጊዜ በንድፍ ደረጃ) ይቀርባል.

ጠረጴዛን ሲነድፉ ዋናውን ቁልፍ መወሰን በጣም አስፈላጊ ነው (በማከማቻው ወቅት መረጃው የሚለየው) ። የውሂብ መጨመቂያ እና የመጠይቅ ፍጥነት መጠን በዚህ ላይ የተመሰረተ ነው. በእኛ ምሳሌ, ዋናው ነገር ነው
ትእዛዝ በ (fld_app_name፣ fld_app_module፣ logdatetime)
ይህም ማለት በስርዓቱ ስም, የስርዓቱ አካል ስም እና የዝግጅቱ ቀን. መጀመሪያ ላይ የክስተቱ ቀን መጀመሪያ መጣ. ወደ መጨረሻው ቦታ ከተዛወረ በኋላ፣ መጠይቆች በእጥፍ ፍጥነት መስራት ጀመሩ። ዋናውን ቁልፍ መቀየር ሰንጠረዡን እንደገና መፍጠር እና ውሂቡን እንደገና መጫን ያስፈልገዋል ClickHouse በዲስክ ላይ ያለውን መረጃ እንደገና ለመደርደር. ይህ ከባድ ክዋኔ ነው፣ስለዚህ በመደርደር ቁልፍ ውስጥ ምን መካተት እንዳለበት ብዙ ማሰብ ጥሩ ሀሳብ ነው።

በተጨማሪም የሎውካርዲናሊቲ የውሂብ አይነት በአንጻራዊነት በቅርብ ጊዜ ስሪቶች ውስጥ እንደታየ ልብ ሊባል ይገባል. በሚጠቀሙበት ጊዜ ዝቅተኛ ካርዲኒቲ (ጥቂት አማራጮች) ላላቸው መስኮች የታመቀ መረጃ መጠን በእጅጉ ይቀንሳል.

ስሪት 19.6 በአሁኑ ጊዜ ጥቅም ላይ የዋለ ሲሆን ወደ አዲሱ ስሪት ለማዘመን አቅደናል። እንደ Adaptive Granularity፣ Skipping Indices እና DoubleDelta Codec፣ ለምሳሌ ድንቅ ባህሪያት አሏቸው።

በነባሪ, በመጫን ጊዜ, የመግቢያ ደረጃ ለመከታተል ተቀናብሯል. ምዝግቦቹ ይሽከረከራሉ እና ይቀመጣሉ, ግን በተመሳሳይ ጊዜ እስከ ጊጋባይት ድረስ ይሰፋሉ. ምንም ፍላጎት ከሌለ, የማስጠንቀቂያ ደረጃውን ማዘጋጀት ይችላሉ, ከዚያ የምዝግብ ማስታወሻው መጠን በከፍተኛ ሁኔታ ይቀንሳል. የምዝግብ ማስታወሻው በ 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. ራውተርን ከፋይልቢት ወደ RabbitMQ ወረፋ ያስገቡ

ይህ አካል ከፋይልቢት የሚመጡትን ምዝግብ ማስታወሻዎች ወደ RabbitMQ ወረፋ ለመምራት ይጠቅማል። እዚህ ሁለት ነጥቦች አሉ.

  1. እንደ አለመታደል ሆኖ FileBeat በቀጥታ ወደ RabbitMQ የሚጽፍ የውጤት ተሰኪ የለውም። እና እንደዚህ አይነት ተግባራዊነት, በ github ላይ ባለው ጉዳይ ላይ በመመዘን, ለትግበራ የታቀደ አይደለም. ለካፍካ ፕለጊን አለ፣ ግን በሆነ ምክንያት በቤት ውስጥ ልንጠቀምበት አንችልም።
  2. በ DMZ ውስጥ ምዝግብ ማስታወሻዎችን ለመሰብሰብ መስፈርቶች አሉ. በእነሱ ላይ በመመስረት, ምዝግብ ማስታወሻዎቹ መጀመሪያ ወደ ወረፋው መጨመር አለባቸው ከዚያም LogStash መዝገቦቹን ከወረፋው ከውጭ ያነባል.

ስለዚህ, አንድ ሰው ትንሽ የተወሳሰበ እቅድ መጠቀም ያለበት በዲኤምኤስ ውስጥ አገልጋዮች በሚገኙበት ጊዜ ነው. የምሳሌ ውቅር ይህን ይመስላል።

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 ውስጥ የምዝግብ ማስታወሻዎችን ለማስቀመጥ ይጠቅማል። ቀረጻ የሚከናወነው በፋይልቢት → LogStash ስብስብ ነው። ማንበብ የሚካሄደው ከDMZ ውጪ በLogStash በኩል ነው። በRabboitMQ በኩል ሲሰራ በሰከንድ ወደ 4 ሺህ የሚጠጉ መልእክቶች ይስተናገዳሉ።

የመልእክት ማዘዋወር በስርዓት ስም የተዋቀረ ነው፣ ማለትም በፋይልቢት ውቅር ውሂብ ላይ በመመስረት። ሁሉም መልዕክቶች ወደ አንድ ወረፋ ይሄዳሉ። በሆነ ምክንያት የወረፋ አገልግሎት ከቆመ ይህ ወደ መልእክቶች መጥፋት አይመራም: 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"

ግራፋና ዳሽቦርዶች

ይህ አካል የክትትል ውሂብን በምስል ለማሳየት ያገለግላል። በዚህ አጋጣሚ ለግራፋና 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 ጋር ሲነፃፀር የማከማቻ እና የማቀነባበሪያ ዋጋ ከአምስት እስከ አስር እጥፍ እንደሚቀንስ ይገመታል። በሌላ አነጋገር አሁን ላለው የመረጃ መጠን የበርካታ ማሽኖች ክላስተር ማዘጋጀት ካለብን ClickHouse ስንጠቀም አንድ አነስተኛ ኃይል ያለው ማሽን ይበቃናል። አዎ፣ በእርግጥ፣ ElasticSearch በዲስክ ላይ የመረጃ መጨመሪያ ዘዴዎች እና ሌሎች የሃብት ፍጆታን በእጅጉ የሚቀንሱ ባህሪያት አሉት፣ ነገር ግን ከ ClickHouse ጋር ሲወዳደር ይህ የበለጠ ውድ ይሆናል።

በእኛ በኩል ምንም ልዩ ማመቻቸት ከሌለ በነባሪ ቅንጅቶች ላይ, ውሂብን መጫን እና ከመረጃ ቋት ውስጥ መምረጥ በሚያስደንቅ ፍጥነት ይሰራል. እስካሁን ብዙ መረጃ የለንም (ወደ 200 ሚሊዮን መዝገቦች) ፣ ግን አገልጋዩ ራሱ ደካማ ነው። ይህንን መሳሪያ ለወደፊቱ ምዝግብ ማስታወሻዎችን ከማጠራቀም ጋር ለተያያዙ ሌሎች ዓላማዎች ልንጠቀምበት እንችላለን. ለምሳሌ, ከጫፍ እስከ ጫፍ ትንታኔ, በደህንነት መስክ, የማሽን ትምህርት.

በመጨረሻ ፣ ስለ ጥቅሞቹ እና ጉዳቶች ትንሽ።

Минусы

  1. በትላልቅ ስብስቦች መዝገቦችን በመጫን ላይ. በአንድ በኩል, ይህ ባህሪ ነው, ነገር ግን አሁንም ተጨማሪ ክፍሎችን ለ መዝገቦች ማቆያ መጠቀም አለብዎት. ይህ ተግባር ሁልጊዜ ቀላል አይደለም, ግን አሁንም ሊፈታ የሚችል ነው. እና እቅዱን ቀላል ማድረግ እፈልጋለሁ.
  2. አንዳንድ ያልተለመዱ ተግባራት ወይም አዲስ ባህሪያት ብዙውን ጊዜ በአዲስ ስሪቶች ውስጥ ይሰበራሉ. ይህ ጭንቀትን ያስከትላል, ወደ አዲስ ስሪት የማሻሻል ፍላጎት ይቀንሳል. ለምሳሌ, የካፍካ የጠረጴዛ ሞተር ሸማቾችን ሳይተገበሩ ከካፍካ ክስተቶችን በቀጥታ እንዲያነቡ የሚያስችልዎ በጣም ጠቃሚ ባህሪ ነው. ነገር ግን በ github ላይ ባሉ ጉዳዮች ብዛት በመመዘን ይህንን ሞተር በምርት ውስጥ እንዳንጠቀም አሁንም እንጠነቀቃለን። ሆኖም ድንገተኛ ምልክቶችን ወደ ጎን ካላደረጉ እና ዋናውን ተግባር ካልተጠቀሙ ከዚያ በተረጋጋ ሁኔታ ይሰራል።

ደማቅ

  1. አይዘገይም።
  2. ዝቅተኛ የመግቢያ ገደብ።
  3. ክፍት ምንጭ.
  4. ፍርይ.
  5. ሚዛኖች በደንብ (ከሳጥኑ ውስጥ መከፋፈል/ማባዛት)
  6. በኮሙኒኬሽን ሚኒስቴር የተጠቆመው የሩስያ ሶፍትዌር መዝገብ ውስጥ ተካትቷል.
  7. ከ Yandex ኦፊሴላዊ ድጋፍ መገኘት.

ምንጭ: hab.com

አስተያየት ያክሉ