ClickHouse Database for Humans, or Alien Technologies

Aleksey Lizunov، MKB جي انفارميشن ٽيڪنالاجي جي ڊائريڪٽوريٽ جي ريموٽ سروس چينلز لاء قابليت سينٽر جو سربراهه

ClickHouse Database for Humans, or Alien Technologies

ELK اسٽيڪ (ElasticSearch، Logstash، Kibana) جي متبادل جي طور تي، اسان لاگس لاءِ ڊيٽا اسٽور طور ClickHouse ڊيٽابيس کي استعمال ڪرڻ تي تحقيق ڪري رهيا آهيون.

هن آرٽيڪل ۾، اسان ڪلڪ هائوس ڊيٽابيس کي استعمال ڪرڻ جي اسان جي تجربي ۽ پائلٽ آپريشن جي ابتدائي نتيجن بابت ڳالهائڻ چاهيندا. اهو فوري طور تي نوٽ ڪيو وڃي ٿو ته نتيجا شاندار هئا.


ClickHouse Database for Humans, or Alien Technologies

اڳيون، اسان وڌيڪ تفصيل سان بيان ڪنداسين ته اسان جو سسٽم ڪيئن ترتيب ڏنو ويو آهي، ۽ ان ۾ ڪهڙا اجزاء شامل آهن. پر هاڻي مان ٿورڙي ڳالهائڻ چاهيان ٿو هن ڊيٽابيس بابت مجموعي طور تي، ۽ اهو ڇو ڌيان ڏيڻ جي قابل آهي. ClickHouse ڊيٽابيس Yandex کان هڪ اعلي ڪارڪردگي تجزياتي ڪالمن ڊيٽابيس آهي. اهو Yandex خدمتن ۾ استعمال ٿيندو آهي، شروعاتي طور تي اهو Yandex.Metrica لاء بنيادي ڊيٽا اسٽوريج آهي. اوپن سورس سسٽم، مفت. ڊولپر جي نقطي نظر کان، مون هميشه حيران ڪيو آهي ته انهن ان کي ڪيئن لاڳو ڪيو، ڇاڪاڻ ته اتي شاندار طور تي وڏي ڊيٽا آهي. ۽ Metrica جو يوزر انٽرفيس پاڻ تمام لچڪدار ۽ تيز آهي. هن ڊيٽابيس سان پهرين واقفيت تي، اهو تاثر آهي: "خير، آخرڪار! ماڻھن لاءِ ٺاھيو! انسٽاليشن جي عمل کان شروع ٿيڻ ۽ موڪلڻ جي درخواستن سان ختم ٿيڻ.

ھن ڊيٽابيس ۾ تمام گھٽ داخل ٿيڻ واري حد آھي. جيتوڻيڪ هڪ سراسري ماهر ڊولپر هن ڊيٽابيس کي چند منٽن ۾ انسٽال ڪري سگهي ٿو ۽ ان کي استعمال ڪرڻ شروع ڪري ٿو. هر شي واضح طور تي ڪم ڪري ٿو. جيتوڻيڪ اهي ماڻهو جيڪي لينڪس ۾ نوان آهن اهي جلدي انسٽاليشن کي هٿي وٺن ٿا ۽ آسان آپريشن ڪري سگهن ٿا. جيڪڏهن اڳ ۾، بگ ڊيٽا، هيڊوپ، گوگل بگ ٽيبل، HDFS، هڪ عام ڊولپر جي خيال سان اهو خيال هو ته اهو ڪجهه ٽيرا بائيٽس، پيٽابائٽس جي باري ۾ آهي، ته ڪجهه عظيم انسان انهن سسٽم لاء سيٽنگون ۽ ترقي ۾ مصروف آهن، پوء ڪلڪ هائوس جي آمد سان. ڊيٽابيس ۾، اسان وٽ ھڪڙو سادو، سمجھڻ وارو اوزار آھي جنھن سان توھان حل ڪري سگھوٿا اڳ ۾ ناقابل حاصل حد تائين ڪمن جي. اهو صرف هڪ مناسب اوسط مشين ۽ انسٽال ڪرڻ لاء پنج منٽ لڳن ٿا. اهو آهي، اسان وٽ هڪ اهڙو ڊيٽابيس آهي، مثال طور، MySql، پر صرف اربين رڪارڊن کي محفوظ ڪرڻ لاءِ! SQL ٻولي سان گڏ ھڪڙو خاص سپر آرڪيور. ڄڻ ته ماڻهن کي ڌارين جا هٿيار ڏنا ويا هئا.

اسان جي لاگنگ سسٽم بابت

معلومات گڏ ڪرڻ لاءِ، معياري فارميٽ جي ويب ايپليڪيشنن جون IIS لاگ فائلون استعمال ڪيون وينديون آهن (اسان هن وقت ايپليڪيشن لاگز کي پارس ڪري رهيا آهيون، پر پائلٽ اسٽيج تي بنيادي مقصد IIS لاگ گڏ ڪرڻ آهي).

مختلف سببن جي ڪري، اسان مڪمل طور تي ELK اسٽيڪ کي ڇڏي نه سگهيا آهيون، ۽ اسان LogStash ۽ Filebeat اجزاء استعمال ڪرڻ جاري رکون ٿا، جيڪي پاڻ کي سٺو ثابت ڪيو آهي ۽ ڪافي معتبر ۽ پيش گوئي سان ڪم ڪيو آهي.

عام لاگنگ اسڪيم هيٺ ڏنل شڪل ۾ ڏيکاريل آهي:

ClickHouse Database for Humans, or Alien Technologies

ClickHouse ڊيٽابيس ۾ ڊيٽا لکڻ جي خصوصيت غير معمولي (هڪ ڀيرو في سيڪنڊ) وڏي بيچ ۾ رڪارڊ داخل ڪرڻ آهي. اهو، ظاهري طور تي، اهو سڀ کان وڌيڪ "مشڪلات وارو" حصو آهي جيڪو توهان کي منهن ڏيڻو آهي جڏهن توهان پهريون ڀيرو ڪلڪ ڪيو هاؤس ڊيٽابيس سان ڪم ڪرڻ جو تجربو ڪيو آهي: اسڪيم ٿورو وڌيڪ پيچيده ٿي ويندو آهي.
LogStash لاءِ پلگ ان، جيڪو سڌو سنئون ڊيٽا کي ClickHouse ۾ داخل ڪري ٿو، هتي تمام گهڻي مدد ڪئي. هي جزو ساڳيو سرور تي لڳايو ويو آهي جيئن ڊيٽابيس پاڻ. تنهن ڪري، عام طور تي ڳالهائڻ، ان کي ڪرڻ جي سفارش نه ڪئي وئي آهي، پر عملي نقطي نظر کان، جيئن ته الڳ سرور پيدا نه ڪن جڏهن اهو ساڳيو سرور تي لڳايو ويو آهي. اسان ڊيٽابيس سان ڪا به ناڪامي يا وسيلن جي تضاد جو مشاهدو نه ڪيو. ان کان علاوه، اهو ياد رکڻ گهرجي ته پلگ ان ۾ غلطي جي صورت ۾ ٻيهر ڪوشش ڪرڻ وارو طريقو آهي. ۽ غلطين جي صورت ۾، پلگ ان ڊسڪ ۾ ڊيٽا جي بيچ کي لکي ٿو جيڪو داخل نه ٿي سگهيو (فائل فارميٽ آسان آهي: ايڊٽ ڪرڻ کان پوء، توهان آساني سان صحيح بيچ داخل ڪري سگهو ٿا ڪلڪ هائوس-ڪلائنٽ استعمال ڪندي).

اسڪيم ۾ استعمال ٿيل سافٽ ويئر جي مڪمل فهرست ٽيبل ۾ پيش ڪئي وئي آهي:

استعمال ٿيل سافٽ ويئر جي فهرست

ٽائيٽل

بيان

تقسيم لنڪ

اين اين جي آء

ريورس-پراڪسي بندرگاهن جي رسائي کي محدود ڪرڻ ۽ اختيار کي منظم ڪرڻ لاءِ

في الحال اسڪيم ۾ استعمال نه ڪيو ويو آهي

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

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

فائل بيٽ

فائل لاگز جي منتقلي.

https://www.elastic.co/downloads/beats/filebeat (ونڊوز 64bit لاءِ تقسيم کٽ).

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

logstash

لاگ جمع ڪندڙ.

FileBeat کان لاگ گڏ ڪرڻ لاءِ استعمال ڪيو ويو، ۽ گڏوگڏ RabbitMQ قطار مان لاگ گڏ ڪرڻ لاءِ (سرور لاءِ جيڪي DMZ ۾ آھن.)

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

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

Logstash-output-clickhouse

لاگ اسٽاش پلگ ان لاگ ان کي منتقل ڪرڻ لاءِ 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 کان شروع ٿي، "عام" rpm تعميرات RHEL لاءِ Yandex مخزن ۾ ظاهر ٿيو، تنهنڪري توهان انهن کي استعمال ڪرڻ جي ڪوشش ڪري سگهو ٿا. تنصيب جي وقت، اسان Altinity پاران ٺهيل پيڪيجز استعمال ڪري رهيا هئاسين.

گرافانا

لاگ بصري. ڊيش بورڊ قائم ڪرڻ

https://grafana.com/

https://grafana.com/grafana/download

Redhat ۽ Centos (64 بٽ) - تازو ورزن

Grafana 4.6+ لاءِ هائوس ڊيٽا ماخذ تي ڪلڪ ڪريو

ڪلڪ هائوس ڊيٽا ماخذ سان گرافانا لاءِ پلگ ان

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

رباب ايم

پيغام جي قطار. هي 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 لاءِ گھربل)

Erlang رن ٽائم. RabbitMQ ڪم ڪرڻ لاءِ گھربل آھي

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

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

ڪلڪ هاؤس ڊيٽابيس سان سرور جي ترتيب ڏنل جدول ۾ پيش ڪئي وئي آهي:

ٽائيٽل

قدر

ويچاري

ڪنفگريشن

HDD: 40GB
رام: 8GB
پروسيسر: ڪور 2 2GHz

ڪلڪ هائوس ڊيٽابيس (https://clickhouse.yandex/docs/ru/operations/tips/)

جنرل سسٽم سافٽ ويئر

OS: Red Hat Enterprise Linux سرور (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_name

ايپليڪيشن / سسٽم جو نالو
صحيح قدر:

  • site1.domain.com ٻاهرين سائيٽ 1
  • site2.domain.com ٻاهرين سائيٽ 2
  • اندروني سائيٽ 1.domain.local اندروني سائيٽ 1

site1.domain.com

fld_app_module

سسٽم ماڊل
صحيح قدر:

  • ويب - ويب سائيٽ
  • svc - ويب سائيٽ سروس
  • intgr - انٽيگريشن ويب سروس
  • بو - ايڊمن (BackOffice)

ويب

fld_website_name

IIS ۾ سائيٽ جو نالو

ڪيترائي سسٽم ھڪڙي سرور تي ترتيب ڏئي سگھجن ٿا، يا ھڪڙو سسٽم ماڊل جا ڪيترائي مثال

ويب مکيه

fld_server_name

سرور جو نالو

web1.domain.com

fld_log_file_name

سرور تي لاگ فائل ڏانهن رستو

ج: inetpublogsLogFiles
W3SVC1u_ex190711.log

هي توهان کي گرافانا ۾ گرافڪس ٺاهڻ جي اجازت ڏئي ٿو. مثال طور، هڪ خاص سسٽم جي فرنٽ اينڊ کان درخواستون ڏسو. اهو ساڳيو آهي 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.

استعمال ٿيل اجزاء جي وضاحت

فائل بيٽ. فائل لاگز جي منتقلي

هي جزو ڊسڪ تي لاگ فائلن ۾ تبديلين کي ٽريڪ ڪري ٿو ۽ معلومات کي 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 ۾ داخل ڪرڻ لاءِ، Logstash-output-clickhouse پلگ ان استعمال ڪيو ويندو آھي. Logstash پلگ ان ۾ هڪ درخواست جي ٻيهر ڪوشش ڪرڻ جو طريقو آهي، پر باقاعده بند ٿيڻ سان، اهو بهتر آهي ته سروس پاڻ کي روڪيو. جڏهن روڪيو ويندو، پيغام RabbitMQ قطار ۾ گڏ ڪيا ويندا، تنهنڪري جيڪڏهن اسٽاپ هڪ ڊگهي وقت لاء آهي، پوء اهو بهتر آهي ته سرور تي فائل بيٽس کي روڪيو وڃي. هڪ اسڪيم ۾ جتي RabbitMQ استعمال نه ڪيو ويو آهي (مقامي نيٽ ورڪ تي، فائل بيٽ سڌو سنئون لاگ اسٽاش ڏانهن لاگ موڪليندو آهي)، فائل بيٽس ڪافي قابل قبول ۽ محفوظ طور تي ڪم ڪن ٿيون، تنهنڪري انهن لاءِ بغير نتيجن جي آئوٽ پاسن جي غير موجودگي.

مثال جي ترتيب هن طرح نظر اچي ٿي:

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 لاگ. ايپليڪيشن لاگز لاء، جنهن ۾، مثال طور، غلطيون، معلوماتي پيغام، ڊيڄاريندڙ رڪارڊ ٿيل آهن، هڪ الڳ ٽيبل فراهم ڪئي ويندي مناسب ڍانچي سان (في الحال ڊزائين اسٽيج تي).

جڏهن ٽيبل ڊزائين ڪرڻ، اهو تمام ضروري آهي ته بنيادي ڪنجي تي فيصلو ڪيو وڃي (جنهن جي ذريعي ڊيٽا اسٽوريج دوران ترتيب ڏني ويندي). ڊيٽا جي ڪمپريشن جي درجي ۽ سوال جي رفتار هن تي منحصر آهي. اسان جي مثال ۾، اهم آهي
آرڊر ذريعي (fld_app_name, fld_app_module, logdatetime)
اهو آهي، سسٽم جي نالي سان، سسٽم جو نالو ۽ واقعي جي تاريخ. شروعات ۾، تقريب جي تاريخ پهرين آئي. ان کي آخري جڳهه تي منتقل ڪرڻ کان پوء، سوالن جي باري ۾ ٻه ڀيرا تيزيء سان ڪم ڪرڻ شروع ڪيو. پرائمري ڪيچ کي تبديل ڪرڻ جي ضرورت پوندي ٽيبل کي ٻيهر ٺاهڻ ۽ ڊيٽا کي ٻيهر لوڊ ڪرڻ لاءِ ته جيئن ڪلڪ هائوس ڊسڪ تي ڊيٽا کي ٻيهر ترتيب ڏئي. ھي ھڪڙو بھاري آپريشن آھي، تنھنڪري اھو سٺو خيال آھي تھ گھڻو سوچڻ گھرجي ته ڇا کي ترتيب واري ڪي ۾ شامل ڪيو وڃي.

اهو پڻ نوٽ ڪيو وڃي ٿو ته گھٽ ڪارڊينلٽي ڊيٽا جو قسم تازو ورزن ۾ نسبتا ظاهر ٿيو آهي. جڏهن ان کي استعمال ڪندي، ڪمپريسر ٿيل ڊيٽا جي سائيز انهن شعبن لاءِ انتهائي گهٽجي ويندي آهي جن ۾ گهٽ ڪارڪردگي (ڪجهه آپشن) آهن.

نسخو 19.6 في الحال استعمال ۾ آهي ۽ اسان تازو ورزن تي تازه ڪاري ڪرڻ جي ڪوشش ڪريون ٿا. انهن وٽ اهڙيون شاندار خاصيتون آهن جهڙوڪ Adaptive Granularity، Skipping indices ۽ DoubleDelta ڪوڊيڪ، مثال طور.

ڊفالٽ طور، انسٽاليشن دوران، لاگنگ جي سطح کي ٽريڪ ڪرڻ لاء مقرر ڪيو ويو آهي. لاگز گھميل ۽ محفوظ ٿيل آھن، پر ساڳئي وقت اھي ھڪڙي گيگا بائيٽ تائين وڌندا آھن. جيڪڏهن ڪا ضرورت ناهي، ته پوء توهان ڊيڄاريندڙ سطح مقرر ڪري سگهو ٿا، پوء لاگ ان جي سائيز کي انتهائي گھٽجي ويندي آهي. لاگنگ سيٽنگ 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 تي لکڻ لاءِ ٻاھرين پلگ ان نه آھي. ۽ اهڙي ڪارڪردگي، انهن جي گٿب تي مسئلي جو فيصلو ڪندي، عمل درآمد جي منصوبابندي نه ڪئي وئي آهي. ڪافڪا لاءِ هڪ پلگ ان آهي، پر ڪجهه سببن ڪري اسان ان کي گهر ۾ استعمال نٿا ڪري سگهون.
  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 ۾. رڪارڊنگ فائل بيٽ → LogStash جي هڪ گروپ ذريعي ڪئي وئي آهي. پڙهڻ DMZ کان ٻاهر LogStash ذريعي ڪيو ويندو آهي. جڏهن 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"

گرافانا. ڊيش بورڊ

هي حصو مانيٽرنگ ڊيٽا کي ڏسڻ لاءِ استعمال ڪيو ويندو آهي. انهي حالت ۾، توهان کي انسٽال ڪرڻ جي ضرورت آهي ClickHouse datasource for Grafana 4.6+ پلگ ان. اسان کي ڊيش بورڊ تي SQL فلٽر جي پروسيسنگ جي ڪارڪردگي کي بهتر بڻائڻ لاءِ ان کي ٿورو ٽوڪ ڪرڻو پوندو.

مثال طور، اسان متغير استعمال ڪندا آهيون، ۽ جيڪڏهن اهي فلٽر فيلڊ ۾ مقرر نه ڪيا ويا آهن، ته پوء اسان چاهيون ٿا ته فارم جي WHERE ۾ هڪ شرط پيدا نه ٿئي ( uriStem = » AND uriStem != »). ھن حالت ۾، ڪلڪ ھاؤس پڙھندو 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

ٿڪل

ڪلڪ هاؤس ڊيٽابيس جي ظاهر ٿيڻ مارڪيٽ ۾ هڪ تاريخي واقعو بڻجي چڪو آهي. اهو تصور ڪرڻ ڏکيو هو، مڪمل طور تي مفت، هڪ فوري ۾ اسان وڏي ڊيٽا سان ڪم ڪرڻ لاء هڪ طاقتور ۽ عملي اوزار سان هٿياربند هئاسين. يقينا، وڌندڙ ضرورتن سان (مثال طور، شارڊنگ ۽ ڪيترن ئي سرورن جي نقل)، اسڪيم وڌيڪ پيچيده ٿي ويندي. پر پهرين تاثرات تي، هن ڊيٽابيس سان ڪم ڪرڻ تمام خوشگوار آهي. اهو ڏسي سگھجي ٿو ته پيداوار "ماڻهن لاء" ٺاهيو ويو آهي.

ElasticSearch جي مقابلي ۾، لاگ ان کي محفوظ ڪرڻ ۽ پروسيسنگ ڪرڻ جي قيمت پنجن کان ڏهه ڀيرا گھٽجڻ جو اندازو لڳايو ويو آهي. ٻين لفظن ۾، جيڪڏهن ڊيٽا جي موجوده مقدار لاءِ اسان کي ڪيترن ئي مشينن جو ڪلسٽر قائم ڪرڻو پوندو، پوءِ جڏهن ClickHouse استعمال ڪريون، هڪ گهٽ طاقت واري مشين اسان لاءِ ڪافي آهي. ها، يقينا، ElasticSearch وٽ پڻ آن ڊسڪ ڊيٽا ڪمپريشن ميڪانيزم ۽ ٻيون خاصيتون آهن جيڪي وسيلن جي استعمال کي خاص طور تي گهٽائي سگهن ٿيون، پر ClickHouse جي مقابلي ۾، اهو وڌيڪ قيمتي هوندو.

اسان جي حصي تي ڪنهن خاص اصلاحن جي بغير، ڊفالٽ سيٽنگن تي، ڊيٽا کي لوڊ ڪرڻ ۽ ڊيٽابيس مان چونڊڻ هڪ شاندار رفتار تي ڪم ڪري ٿو. اسان وٽ اڃا وڌيڪ ڊيٽا نه آهي (اٽڪل 200 ملين رڪارڊ)، پر سرور پاڻ ڪمزور آهي. اسان هن اوزار کي مستقبل ۾ استعمال ڪري سگهون ٿا ٻين مقصدن لاءِ جيڪي لاگن کي محفوظ ڪرڻ سان لاڳاپيل نه آهن. مثال طور، آخر کان آخر تائين اينالائيٽڪس لاء، سيڪيورٽي جي شعبي ۾، مشين سکيا.

آخر ۾، نفعو ۽ نقصان جي باري ۾ ٿورو.

Минусы

  1. وڏي بيچ ۾ رڪارڊ لوڊ ڪندي. هڪ پاسي، هي هڪ خاصيت آهي، پر توهان اڃا تائين رڪارڊ بفرنگ لاء اضافي اجزاء استعمال ڪرڻو پوندو. اهو ڪم هميشه سولو ناهي، پر اڃا تائين حل ٿي سگهي ٿو. ۽ مان اسڪيم کي آسان ڪرڻ چاهيان ٿو.
  2. ڪجهه غير معمولي ڪارڪردگي يا نيون خاصيتون اڪثر ڪري نئين نسخن ۾ ڀڃندا آهن. اهو سبب آهي تشويش، نئين نسخي کي اپڊيٽ ڪرڻ جي خواهش کي گهٽائڻ. مثال طور، ڪافڪا ٽيبل انجڻ هڪ تمام مفيد خصوصيت آهي جيڪا توهان کي سڌو سنئون ڪافڪا کان واقعا پڙهڻ جي اجازت ڏئي ٿي، صارفين کي لاڳو ڪرڻ کان سواء. پر گٿب تي مسئلن جي تعداد جي لحاظ کان، اسان اڃا تائين محتاط آهيون ته هن انجڻ کي پيداوار ۾ استعمال نه ڪيو وڃي. تنهن هوندي، جيڪڏهن توهان اوچتو اشارو نه ٿا ڪن ته پاسي ڏانهن ۽ مکيه ڪارڪردگي استعمال ڪريو، پوء اهو مستحڪم طور تي ڪم ڪري ٿو.

Плюсы

  1. سست نٿو ٿئي.
  2. گھٽ داخلا جي حد.
  3. کليل ذريعو.
  4. واندو.
  5. اسڪيل چڱي طرح (دٻي کان ٻاهر شيڊنگ / نقل)
  6. مواصلاتي وزارت پاران تجويز ڪيل روسي سافٽ ويئر جي رجسٽر ۾ شامل.
  7. Yandex کان سرڪاري حمايت جي موجودگي.

جو ذريعو: www.habr.com

تبصرو شامل ڪريو