1.1 เบžเบฑเบ™เบฅเป‰เบฒเบ™เบเบฒเบ™เป€เบ”เบตเบ™เบ—เบฒเบ‡ taxi: 108-core ClickHouse cluster

เบเบฒเบ™เปเบ›เบžเบฒเบชเบฒเบ‚เบญเบ‡เบšเบปเบ”เบ„เบงเบฒเบกเป„เบ”เป‰เบ–เบทเบเบเบฐเบเบฝเบกเป‚เบ”เบเบชเบฐเป€เบžเบฒเบฐเบชเปเบฒเบฅเบฑเบšเบ™เบฑเบเบชเบถเบเบชเบฒเบ‚เบญเบ‡เบซเบผเบฑเบเบชเบนเบ” เบงเบดเบชเบฐเบงเบฐเบเบญเบ™เบ‚เปเป‰เบกเบนเบ™.

1.1 เบžเบฑเบ™เบฅเป‰เบฒเบ™เบเบฒเบ™เป€เบ”เบตเบ™เบ—เบฒเบ‡ taxi: 108-core ClickHouse cluster

เบเบปเบ”เบ›เบธเปˆเบก เป€เบ›เบฑเบ™เบ–เบฒเบ™เบ‚เปเป‰เบกเบนเบ™เบ–เบฑเบ™เปเบซเบผเปˆเบ‡เป€เบ›เบตเบ”. เบกเบฑเบ™เป€เบ›เบฑเบ™เบชเบฐเบžเบฒเบšเปเบงเบ”เบฅเป‰เบญเบกเบ—เบตเปˆเบ”เบตเบ—เบตเปˆเบ™เบฑเบเบงเบดเป€เบ„เบฒเบฐเบซเบผเบฒเบเบฎเป‰เบญเบเบ„เบปเบ™เบชเบฒเบกเบฒเบ”เบชเบญเบšเบ–เบฒเบกเบ‚เปเป‰เบกเบนเบ™เบฅเบฒเบเบฅเบฐเบญเบฝเบ”เป„เบ”เป‰เบขเปˆเบฒเบ‡เบงเปˆเบญเบ‡เป„เบง, เป€เบ–เบดเบ‡เปเบกเปˆเบ™เบงเปˆเบฒเบšเบฑเบ™เบ—เบถเบเปƒเบซเบกเปˆเบซเบผเบฒเบเบชเบดเบšเบ•เบทเป‰เบˆเบฐเบ–เบทเบเบ›เป‰เบญเบ™เบ•เปเปˆเบกเบทเป‰. เบ„เปˆเบฒเปƒเบŠเป‰เบˆเปˆเบฒเบเบžเบทเป‰เบ™เบ–เบฒเบ™เป‚เบ„เบ‡เบฅเปˆเบฒเบ‡เป€เบžเบทเปˆเบญเบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™เบฅเบฐเบšเบปเบšเบ”เบฑเปˆเบ‡เบเปˆเบฒเบงเบญเบฒเบ”เบˆเบฐเบชเบนเบ‡เป€เบ–เบดเบ‡ 100 เป‚เบ”เบฅเบฒเบ•เปเปˆเบ›เบต, เปเบฅเบฐเบญเบฒเบ”เบˆเบฐเป€เบ›เบฑเบ™เป€เบ„เบดเปˆเบ‡เบซเบ™เบถเปˆเบ‡เปเบกเปˆเบ™เบ‚เบถเป‰เบ™เบเบฑเบšเบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰. เปƒเบ™เบˆเบธเบ”เบซเบ™เบถเปˆเบ‡, เบเบฒเบ™เบ•เบดเบ”เบ•เบฑเป‰เบ‡ ClickHouse เบˆเบฒเบ Yandex Metrics เบกเบตเบšเบฑเบ™เบ—เบถเบ 10 เบžเบฑเบ™เบ•เบทเป‰. เบ™เบญเบเป€เบซเบ™เบทเบญเบˆเบฒเบ Yandex, ClickHouse เบเบฑเบ‡เบžเบปเบšเบ„เบงเบฒเบกเบชเปเบฒเป€เบฅเบฑเบ”เบเบฑเบš Bloomberg เปเบฅเบฐ Cloudflare.

เบชเบญเบ‡เบ›เบตเบเปˆเบญเบ™เบซเบ™เป‰เบฒเบ™เบตเป‰เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เปƒเบŠเป‰เป€เบงเบฅเบฒ เบเบฒเบ™โ€‹เบงเบดโ€‹เป€เบ„เบฒเบฐโ€‹เบเบฒเบ™โ€‹เบ›เบฝเบšโ€‹เบ—เบฝเบšโ€‹ เบ–เบฒเบ™โ€‹เบ‚เปเป‰โ€‹เบกเบนเบ™โ€‹เบเบฒเบ™โ€‹เบ™เปเบฒโ€‹เปƒเบŠเป‰โ€‹เป€เบ„เบทเปˆเบญเบ‡โ€‹เบซเบ™เบถเปˆเบ‡โ€‹, เปเบฅเบฐโ€‹เบกเบฑเบ™โ€‹เป„เบ”เป‰โ€‹เบเบฒเบโ€‹เป€เบ›เบฑเบ™โ€‹ เป„เบงเบ—เบตเปˆเบชเบธเบ” เบŠเบญเบšเปเบงเบ–เบฒเบ™เบ‚เปเป‰เบกเบนเบ™เบŸเบฃเบตเบ—เบตเปˆเบ‚เป‰เบญเบเป€เบ„เบตเบเป€เบซเบฑเบ™. เบ™เบฑเบšเบ•เบฑเป‰เบ‡เปเบ•เปˆเบ™เบฑเป‰เบ™เบกเบฒ, เบ™เบฑเบเบžเบฑเบ”เบ—เบฐเบ™เบฒเบšเปเปˆเป„เบ”เป‰เบขเบธเบ”เป€เบŠเบปเบฒเบเบฒเบ™เป€เบžเบตเปˆเบกเบ„เบธเบ™เบชเบปเบกเบšเบฑเบ”, เบฅเบงเบกเบ—เบฑเบ‡เบเบฒเบ™เบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™เบเบฒเบ™เบšเบตเบšเบญเบฑเบ” Kafka, HDFS เปเบฅเบฐ ZStandard. เบ›เบตเบ—เบตเปˆเบœเปˆเบฒเบ™เบกเบฒเบžเบงเบเป€เบ‚เบปเบฒเป€เบžเบตเปˆเบกเบเบฒเบ™เบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™เบงเบดเบ—เบตเบเบฒเบ™เบšเบตเบšเบญเบฑเบ” cascading, เปเบฅเบฐ delta-from-delta เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเบฅเบฐเบซเบฑเบ”เป„เบ”เป‰เบเบฒเบเป€เบ›เบฑเบ™เบ„เบงเบฒเบกเป€เบ›เบฑเบ™เป„เบ›เป„เบ”เป‰. เป€เบกเบทเปˆเบญเบšเบตเบšเบญเบฑเบ”เบ‚เปเป‰เบกเบนเบ™เบŠเบธเบ”เป€เบงเบฅเบฒ, เบ„เปˆเบฒเบงเบฑเบ”เบชเบฒเบกเบฒเบ”เบ–เบทเบเบšเบตเบšเบญเบฑเบ”เป„เบ”เป‰เบ”เบตเป‚เบ”เบเปƒเบŠเป‰เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเบฅเบฐเบซเบฑเบ” delta, เปเบ•เปˆเบชเบณเบฅเบฑเบšเบ•เบปเบงเบ™เบฑเบšเบกเบฑเบ™เบˆเบฐเบ”เบตเบเบงเปˆเบฒเบ—เบตเปˆเบˆเบฐเปƒเบŠเป‰เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเบฅเบฐเบซเบฑเบ” delta-by-delta. เบเบฒเบ™เบšเบตเบšเบญเบฑเบ”เบ—เบตเปˆเบ”เบตเป„เบ”เป‰เบเบฒเบเป€เบ›เบฑเบ™เบเบธเบ™เปเบˆเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบ‡เบฒเบ™เบ‚เบญเบ‡ ClickHouse.

ClickHouse เบ›เบฐเบเบญเบšเบ”เป‰เบงเบ 170 เบžเบฑเบ™เบชเบฒเบเบ‚เบญเบ‡เบฅเบฐเบซเบฑเบ” C++, เบšเปเปˆเบฅเบงเบกเบซเป‰เบญเบ‡เบชเบฐเบซเบกเบธเบ”เบ‚เบญเบ‡เบžเบฒเบเบชเปˆเบงเบ™เบ—เบตเบชเบฒเบก, เปเบฅเบฐเป€เบ›เบฑเบ™เบซเบ™เบถเปˆเบ‡เปƒเบ™เบฅเบฐเบซเบฑเบ”เบ–เบฒเบ™เบ‚เปเป‰เบกเบนเบ™เบ—เบตเปˆเปเบˆเบเบขเบฒเบเบ‚เบฐเบซเบ™เบฒเบ”เบ™เป‰เบญเบเบ—เบตเปˆเบชเบธเบ”. เปƒเบ™เบเบฒเบ™เบ›เบฝเบšเบ—เบฝเบš, SQLite เบšเปเปˆเบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™เบเบฒเบ™เปเบˆเบเบขเบฒเบเปเบฅเบฐเบ›เบฐเบเบญเบšเบ”เป‰เบงเบ 235 เบžเบฑเบ™เบชเบฒเบเบ‚เบญเบ‡เบฅเบฐเบซเบฑเบ” C. เปƒเบ™เบ–เบฒเบ™เบฐเป€เบ›เบฑเบ™เบเบฒเบ™เบ‚เบฝเบ™เบ™เบตเป‰, เบงเบดเบชเบฐเบงเบฐเบเบญเบ™ 207 เป„เบ”เป‰เบ›เบฐเบเบญเบšเบชเปˆเบงเบ™เปƒเบซเป‰ ClickHouse, เปเบฅเบฐเบ„เบงเบฒเบกเป€เบ‚เบฑเป‰เบกเบ‚เบปเป‰เบ™เบ‚เบญเบ‡ commits เป„เบ”เป‰เป€เบžเบตเปˆเบกเบ‚เบถเป‰เบ™เบšเปเปˆเบ”เบปเบ™เบกเบฒเบ™เบตเป‰.

เปƒเบ™เป€เบ”เบทเบญเบ™เบกเบตเบ™เบฒ 2017, ClickHouse เป€เบฅเบตเปˆเบกเบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™ เบšเบฑเบ™เบ—เบถเบเบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡ เป€เบ›เบฑเบ™เบงเบดเบ—เบตเบ—เบตเปˆเบ‡เปˆเบฒเบเบ—เบตเปˆเบˆเบฐเบ•เบดเบ”เบ•เบฒเบกเบเบฒเบ™เบžเบฑเบ”เบ—เบฐเบ™เบฒ. เบžเบงเบเป€เบ‚เบปเบฒเป€เบˆเบปเป‰เบฒเบเบฑเบ‡เป„เบ”เป‰เปเบเบเป„เบŸเบฅเปŒเป€เบญเบเบฐเบชเบฒเบ™ monolithic เป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เบฅเปเบฒเบ”เบฑเบšเบŠเบฑเป‰เบ™เป„เบŸเบฅเปŒเบ—เบตเปˆเบญเบตเบ‡เปƒเบชเปˆ Markdown. เบšเบฑเบ™เบซเบฒเปเบฅเบฐเบฅเบฑเบเบชเบฐเบ™เบฐเบ•เปˆเบฒเบ‡เป†เปเบกเปˆเบ™เบ•เบดเบ”เบ•เบฒเบกเบœเปˆเบฒเบ™ GitHub, เปเบฅเบฐเป‚เบ”เบเบ—เบปเปˆเบงเป„เบ›เปเบฅเป‰เบงเบŠเบญเบšเปเบงเป„เบ”เป‰เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบซเบผเบฒเบเปƒเบ™เบชเบญเบ‡เบชเบฒเบกเบ›เบตเบœเปˆเบฒเบ™เบกเบฒ.

เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบกเบ™เบตเป‰, เบ‚เป‰เบญเบเบˆเบฐเบžเบดเบˆเบฒเบฅเบฐเบ™เบฒเบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบ‚เบญเบ‡เบเบธเปˆเบก ClickHouse เปƒเบ™ AWS EC2 เป‚เบ”เบเปƒเบŠเป‰เป‚เบ›เป€เบŠเบ”เป€เบŠเบต 36-core เปเบฅเบฐเบเบฒเบ™เป€เบเบฑเบšเบฎเบฑเบเบชเบฒ NVMe.

เบญเบฑเบšเป€เบ”เบ”: เปœเบถเปˆเบ‡เบญเบฒเบ—เบดเบ”เบซเบผเบฑเบ‡เบˆเบฒเบเบเบฒเบ™เป€เบœเบตเบเปเบœเปˆเป‚เบžเบชเบ™เบตเป‰เปƒเบ™เป€เบšเบทเป‰เบญเบ‡เบ•เบปเป‰เบ™, เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เป€เบฎเบฑเบ”เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบ„เบทเบ™เปƒเปเปˆเบ”เป‰เบงเบเบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบ—เบตเปˆเบ›เบฑเบšเบ›เบธเบ‡เปƒเบซเป‰เบ”เบตเบ‚เบถเป‰เบ™ เปเบฅเบฐเป„เบ”เป‰เบœเบปเบ™เบ”เบตเบ‚เบทเป‰เบ™เบซเบผเบฒเบ. เป‚เบžเบชเบ™เบตเป‰เป„เบ”เป‰เบ–เบทเบเบ›เบฑเบšเบ›เบธเบ‡เป€เบžเบทเปˆเบญเบชเบฐเบ—เป‰เบญเบ™เป€เบ–เบดเบ‡เบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰.

เป€เบ›เบตเบ”เบ•เบปเบง AWS EC2 Cluster

เบ‚เป‰เบญเบเบˆเบฐเปƒเบŠเป‰เบชเบฒเบกเบ•เบปเบงเบขเปˆเบฒเบ‡ c5d.9xlarge EC2 เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ•เบญเบšเบ™เบตเป‰. เปเบ•เปˆเบฅเบฐเบญเบฑเบ™เบกเบต 36 CPU virtual, 72 GB เบ‚เบญเบ‡ RAM, 900 GB เบ‚เบญเบ‡ NVMe SSD storage เปเบฅเบฐเบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™เป€เบ„เบทเบญเบ‚เปˆเบฒเบ 10 Gigabit. เบžเบงเบเป€เบ‚เบปเบฒเบกเบตเบฅเบฒเบ„เบฒ 1,962 เป‚เบ”เบฅเบฒ/เบŠเบปเปˆเบงเป‚เบกเบ‡ เปƒเบ™เปเบ•เปˆเบฅเบฐเบ‚เบปเบ‡เป€เบ‚เบ” eu-west-1 เป€เบกเบทเปˆเบญเปเบฅเปˆเบ™เบ•เบฒเบกเบ„เบงเบฒเบกเบ•เป‰เบญเบ‡เบเบฒเบ™. เบ‚เป‰เบญเบเบˆเบฐเปƒเบŠเป‰ Ubuntu Server 16.04 LTS เป€เบ›เบฑเบ™เบฅเบฐเบšเบปเบšเบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™.

Firewall เป„เบ”เป‰เบ–เบทเบเบ•เบฑเป‰เบ‡เบ„เปˆเบฒเป€เบžเบทเปˆเบญเปƒเบซเป‰เปเบ•เปˆเบฅเบฐเป€เบ„เบทเปˆเบญเบ‡เบชเบฒเบกเบฒเบ”เบชเบทเปˆเบชเบฒเบ™เบเบฑเบšเบเบฑเบ™เป„เบ”เป‰เป‚เบ”เบเบšเปเปˆเบกเบตเบ‚เปเป‰เบˆเปเบฒเบเบฑเบ”, เปเบฅเบฐเบกเบตเบžเบฝเบ‡เปเบ•เปˆเบ—เบตเปˆเบขเบนเปˆ IPv4 เบ‚เบญเบ‡เบ‚เป‰เบญเบเป€เบ—เบปเปˆเบฒเบ™เบฑเป‰เบ™เบ—เบตเปˆเบ–เบทเบเบšเบฑเบ™เบŠเบตเบ‚เบฒเบงเป‚เบ”เบ SSH เปƒเบ™เบเบธเปˆเบก.

เป„เบ” NVMe เบขเบนเปˆเปƒเบ™เบชเบฐเบžเบฒเบšเบเบฝเบกเบžเป‰เบญเบกเปƒเบ™เบเบฒเบ™เบ”เปเบฒเป€เบ™เบตเบ™เบ‡เบฒเบ™

เป€เบžเบทเปˆเบญเปƒเบซเป‰ ClickHouse เป€เบฎเบฑเบ”เบงเบฝเบ, เบ‚เป‰เบญเบเบˆเบฐเบชเป‰เบฒเบ‡เบฅเบฐเบšเบปเบšเป„เบŸเบฅเปŒเปƒเบ™เบฎเบนเบšเปเบšเบš EXT4 เปƒเบ™เป„เบ” NVMe เปƒเบ™เปเบ•เปˆเบฅเบฐเป€เบ„เบทเปˆเบญเบ‡เปเบกเปˆเบ‚เปˆเบฒเบ.

$ sudo mkfs -t ext4 /dev/nvme1n1
$ sudo mkdir /ch
$ sudo mount /dev/nvme1n1 /ch

เป€เบกเบทเปˆเบญเบ—เบธเบเบชเบดเปˆเบ‡เบ—เบธเบเบขเปˆเบฒเบ‡เบ–เบทเบเบ•เบฑเป‰เบ‡เบ„เปˆเบฒ, เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เป€เบšเบดเปˆเบ‡เบˆเบธเบ”เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเปเบฅเบฐเบžเบทเป‰เบ™เบ—เบตเปˆ 783 GB เบ—เบตเปˆเบกเบตเบขเบนเปˆเปƒเบ™เปเบ•เปˆเบฅเบฐเบฅเบฐเบšเบปเบš.

$ lsblk

NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
loop0         7:0    0  87.9M  1 loop /snap/core/5742
loop1         7:1    0  16.5M  1 loop /snap/amazon-ssm-agent/784
nvme0n1     259:1    0     8G  0 disk
โ””โ”€nvme0n1p1 259:2    0     8G  0 part /
nvme1n1     259:0    0 838.2G  0 disk /ch

$ df -h

Filesystem      Size  Used Avail Use% Mounted on
udev             35G     0   35G   0% /dev
tmpfs           6.9G  8.8M  6.9G   1% /run
/dev/nvme0n1p1  7.7G  967M  6.8G  13% /
tmpfs            35G     0   35G   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs            35G     0   35G   0% /sys/fs/cgroup
/dev/loop0       88M   88M     0 100% /snap/core/5742
/dev/loop1       17M   17M     0 100% /snap/amazon-ssm-agent/784
tmpfs           6.9G     0  6.9G   0% /run/user/1000
/dev/nvme1n1    825G   73M  783G   1% /ch

เบŠเบธเบ”เบ‚เปเป‰เบกเบนเบ™เบ—เบตเปˆเบ‚เป‰เบญเบเบˆเบฐเปƒเบŠเป‰เปƒเบ™เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบ™เบตเป‰เปเบกเปˆเบ™เบšเปˆเบญเบ™เบ–เบดเป‰เบกเบ‚เปเป‰เบกเบนเบ™เบ—เบตเปˆเบ‚เป‰เบญเบเบชเป‰เบฒเบ‡เบ‚เบถเป‰เบ™เบˆเบฒเบเบเบฒเบ™เบ‚เบตเปˆเบฅเบปเบ”เปเบ—เบฑเบเบŠเบต 1.1 เบ•เบทเป‰เป€เบ—เบทเปˆเบญเบ„เบปเบ™เปƒเบ™เบ™เบฐเบ„เบญเบ™เบ™เบดเบงเบขเบญเบเปƒเบ™เป„เบฅเบเบฐเบซเบปเบเบ›เบต. เปƒเบ™ blog เบเบฒเบ™เป€เบ”เบตเบ™เบ—เบฒเบ‡ taxi เบซเบ™เบถเปˆเบ‡เบ•เบทเป‰เปƒเบ™ Redshift เบฅเบฒเบเบฅเบฐเบญเบฝเบ”เบงเบดเบ—เบตเบเบฒเบ™เป€เบเบฑเบšเบเบณเบ‚เปเป‰เบกเบนเบ™เบŠเบธเบ”เบ™เบตเป‰. เบžเบงเบเบกเบฑเบ™เบ–เบทเบเป€เบเบฑเบšเป„เบงเป‰เปƒเบ™ AWS S3, เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เบ‚เป‰เบญเบเบˆเบฐเบ•เบฑเป‰เบ‡เบ„เปˆเบฒ AWS CLI เบ”เป‰เบงเบเบเบฒเบ™เป€เบ‚เบปเป‰เบฒเปƒเบŠเป‰เบ‚เบญเบ‡เบ‚เป‰เบญเบ เปเบฅเบฐเบเบฐเปเบˆเบฅเบฑเบš.

$ sudo apt update
$ sudo apt install awscli
$ aws configure

เบ‚เป‰เบญเบเบˆเบฐเบ•เบฑเป‰เบ‡เบ‚เบญเบšเป€เบ‚เบ”เบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเบžเป‰เบญเบกเบเบฑเบ™เบ‚เบญเบ‡เบฅเบนเบเบ„เป‰เบฒเป€เบ›เบฑเบ™ 100 เป€เบžเบทเปˆเบญเปƒเบซเป‰เป„เบŸเบฅเปŒเบ”เบฒเบงเป‚เบซเบผเบ”เป„เบงเบเบงเปˆเบฒเบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™.

$ aws configure set 
    default.s3.max_concurrent_requests 
    100

เบ‚เป‰เบญเบเบˆเบฐเบ”เบฒเบงเป‚เบซเบฅเบ”เบŠเบธเบ”เบ‚เปเป‰เบกเบนเบ™เบเบฒเบ™เบ‚เบฑเบšเบ‚เบตเปˆ taxi เบˆเบฒเบ AWS S3 เปเบฅเบฐเป€เบเบฑเบšเป„เบงเป‰เปƒเบ™เป„เบ” NVMe เบขเบนเปˆเปƒเบ™เป€เบ„เบทเปˆเบญเบ‡เปเบกเปˆเบ‚เปˆเบฒเบเบ—เปเบฒเบญเบดเบ”. เบŠเบธเบ”เบ‚เปเป‰เบกเบนเบ™เบ™เบตเป‰เปเบกเปˆเบ™ ~104GB เปƒเบ™เบฎเบนเบšเปเบšเบš CSV เบ—เบตเปˆเบšเบตเบšเบญเบฑเบ” GZIP.

$ sudo mkdir -p /ch/csv
$ sudo chown -R ubuntu /ch/csv
$ aws s3 sync s3://<bucket>/csv /ch/csv

เบเบฒเบ™เบ•เบดเบ”เบ•เบฑเป‰เบ‡ ClickHouse

เบ‚เป‰เบญเบเบˆเบฐเบ•เบดเบ”เบ•เบฑเป‰เบ‡เบเบฒเบ™เปเบˆเบเบขเบฒเบ OpenJDK เบชเปเบฒเบฅเบฑเบš Java 8 เบเป‰เบญเบ™เบงเปˆเบฒเบกเบฑเบ™เบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™ Apache ZooKeeper, เป€เบŠเบดเปˆเบ‡เบ•เป‰เบญเบ‡เบเบฒเบ™เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ•เบดเบ”เบ•เบฑเป‰เบ‡ ClickHouse เบ—เบตเปˆเปเบˆเบเบขเบฒเบเบขเบนเปˆเปƒเบ™เบ—เบฑเบ‡เบชเบฒเบกเป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบ.

$ sudo apt update
$ sudo apt install 
    openjdk-8-jre 
    openjdk-8-jdk-headless

เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™, เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเบเปเบฒเบ™เบปเบ”เบ•เบปเบงเปเบ›เบชเบฐเบžเบฒเบšเปเบงเบ”เบฅเป‰เบญเบก JAVA_HOME.

$ sudo vi /etc/profile
 
export JAVA_HOME=/usr
 
$ source /etc/profile

เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบ‚เป‰เบญเบเบˆเบฐเปƒเบŠเป‰เบฅเบฐเบšเบปเบšเบเบฒเบ™เบˆเบฑเบ”เบเบฒเบ™เปเบžเบฑเบเป€เบเบฑเบ”เบ‚เบญเบ‡ Ubuntu เป€เบžเบทเปˆเบญเบ•เบดเบ”เบ•เบฑเป‰เบ‡ ClickHouse 18.16.1, glances เปเบฅเบฐ ZooKeeper เปƒเบ™เบ—เบฑเบ‡เบชเบฒเบกเป€เบ„เบทเปˆเบญเบ‡.

$ sudo apt-key adv 
    --keyserver hkp://keyserver.ubuntu.com:80 
    --recv E0C56BD4
$ echo "deb http://repo.yandex.ru/clickhouse/deb/stable/ main/" | 
    sudo tee /etc/apt/sources.list.d/clickhouse.list
$ sudo apt-get update

$ sudo apt install 
    clickhouse-client 
    clickhouse-server 
    glances 
    zookeeperd

เบ‚เป‰เบญเบเบˆเบฐเบชเป‰เบฒเบ‡เป„เบ”เป€เบฅเบเบฐเบ—เปเบฅเบตเบชเปเบฒเบฅเบฑเบš ClickHouse เปเบฅเบฐเบเบฑเบ‡เป€เบฎเบฑเบ”เบšเบฒเบ‡เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒ overrides เปƒเบ™เบ—เบฑเบ‡เบชเบฒเบกเป€เบ„เบทเปˆเบญเบ‡เปเบกเปˆเบ‚เปˆเบฒเบ.

$ sudo mkdir /ch/clickhouse
$ sudo chown -R clickhouse /ch/clickhouse

$ sudo mkdir -p /etc/clickhouse-server/conf.d
$ sudo vi /etc/clickhouse-server/conf.d/taxis.conf

เป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เปเบกเปˆเบ™ overrides เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบ—เบตเปˆเบ‚เป‰เบญเบเบˆเบฐเปƒเบŠเป‰.

<?xml version="1.0"?>
<yandex>
    <listen_host>0.0.0.0</listen_host>
    <path>/ch/clickhouse/</path>

 <remote_servers>
        <perftest_3shards>
            <shard>
                <replica>
                    <host>172.30.2.192</host>
                    <port>9000</port>
                 </replica>
            </shard>
            <shard>
                 <replica>
                    <host>172.30.2.162</host>
                    <port>9000</port>
                 </replica>
            </shard>
            <shard>
                 <replica>
                    <host>172.30.2.36</host>
                    <port>9000</port>
                 </replica>
            </shard>
        </perftest_3shards>
    </remote_servers>

  <zookeeper-servers>
        <node>
            <host>172.30.2.192</host>
            <port>2181</port>
        </node>
        <node>
            <host>172.30.2.162</host>
            <port>2181</port>
        </node>
        <node>
            <host>172.30.2.36</host>
            <port>2181</port>
        </node>
    </zookeeper-servers>

 <macros>
        <shard>03</shard>
        <replica>01</replica>
    </macros>
</yandex>

เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเบˆเบฐเบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™ ZooKeeper เปเบฅเบฐเป€เบ„เบทเปˆเบญเบ‡เปเบกเปˆเบ‚เปˆเบฒเบ ClickHouse เปƒเบ™เบ—เบฑเบ‡เบชเบฒเบกเป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบ.

$ sudo /etc/init.d/zookeeper start
$ sudo service clickhouse-server start

เบเบณเบฅเบฑเบ‡เบญเบฑเบšเป‚เบซเบฅเบ”เบ‚เปเป‰เบกเบนเบ™เปƒเบชเปˆ ClickHouse

เปƒเบ™เป€เบ„เบทเปˆเบญเบ‡เปเบกเปˆเบ‚เปˆเบฒเบเบ—เปเบฒเบญเบดเบ”เบ‚เป‰เบญเบเบˆเบฐเบชเป‰เบฒเบ‡เบ•เบฒเบ•เบฐเบฅเบฒเบ‡เบเบฒเบ™เป€เบ”เบตเบ™เบ—เบฒเบ‡ (trips), เป€เบŠเบดเปˆเบ‡เบˆเบฐเป€เบเบฑเบšเบฎเบฑเบเบชเบฒเบŠเบธเบ”เบ‚เปเป‰เบกเบนเบ™เบ‚เบญเบ‡เบเบฒเบ™เป€เบ”เบตเบ™เบ—เบฒเบ‡ taxi เป‚เบ”เบเปƒเบŠเป‰เป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบ Log.

$ clickhouse-client --host=0.0.0.0
 
CREATE TABLE trips (
    trip_id                 UInt32,
    vendor_id               String,

    pickup_datetime         DateTime,
    dropoff_datetime        Nullable(DateTime),

    store_and_fwd_flag      Nullable(FixedString(1)),
    rate_code_id            Nullable(UInt8),
    pickup_longitude        Nullable(Float64),
    pickup_latitude         Nullable(Float64),
    dropoff_longitude       Nullable(Float64),
    dropoff_latitude        Nullable(Float64),
    passenger_count         Nullable(UInt8),
    trip_distance           Nullable(Float64),
    fare_amount             Nullable(Float32),
    extra                   Nullable(Float32),
    mta_tax                 Nullable(Float32),
    tip_amount              Nullable(Float32),
    tolls_amount            Nullable(Float32),
    ehail_fee               Nullable(Float32),
    improvement_surcharge   Nullable(Float32),
    total_amount            Nullable(Float32),
    payment_type            Nullable(String),
    trip_type               Nullable(UInt8),
    pickup                  Nullable(String),
    dropoff                 Nullable(String),

    cab_type                Nullable(String),

    precipitation           Nullable(Int8),
    snow_depth              Nullable(Int8),
    snowfall                Nullable(Int8),
    max_temperature         Nullable(Int8),
    min_temperature         Nullable(Int8),
    average_wind_speed      Nullable(Int8),

    pickup_nyct2010_gid     Nullable(Int8),
    pickup_ctlabel          Nullable(String),
    pickup_borocode         Nullable(Int8),
    pickup_boroname         Nullable(String),
    pickup_ct2010           Nullable(String),
    pickup_boroct2010       Nullable(String),
    pickup_cdeligibil       Nullable(FixedString(1)),
    pickup_ntacode          Nullable(String),
    pickup_ntaname          Nullable(String),
    pickup_puma             Nullable(String),

    dropoff_nyct2010_gid    Nullable(UInt8),
    dropoff_ctlabel         Nullable(String),
    dropoff_borocode        Nullable(UInt8),
    dropoff_boroname        Nullable(String),
    dropoff_ct2010          Nullable(String),
    dropoff_boroct2010      Nullable(String),
    dropoff_cdeligibil      Nullable(String),
    dropoff_ntacode         Nullable(String),
    dropoff_ntaname         Nullable(String),
    dropoff_puma            Nullable(String)
) ENGINE = Log;

เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเบชเบฐเบเบฑเบ”เปเบฅเบฐเป‚เบซเบฅเบ”เปเบ•เปˆเบฅเบฐเป„เบŸเบฅเปŒ CSV เป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เบ•เบฒเบ•เบฐเบฅเบฒเบ‡เบเบฒเบ™เป€เบ”เบตเบ™เบ—เบฒเบ‡ (trips). เบ•เปเปˆเป„เบ›เบ™เบตเป‰เปเบกเปˆเบ™เบชเปเบฒเป€เบฅเบฑเบ”เปƒเบ™ 55 เบ™เบฒเบ—เบต 10 เบงเบดเบ™เบฒเบ—เบต. เบซเบผเบฑเบ‡เบˆเบฒเบเบเบฒเบ™เบ”เปเบฒเป€เบ™เบตเบ™เบ‡เบฒเบ™เบ™เบตเป‰, เบ‚เบฐเบซเบ™เบฒเบ”เบ‚เบญเบ‡เป„เบ”เป€เบฅเบเบฐเบ—เปเบฅเบตเบ‚เปเป‰เบกเบนเบ™เปเบกเปˆเบ™ 134 GB.

$ time (for FILENAME in /ch/csv/trips_x*.csv.gz; do
            echo $FILENAME
            gunzip -c $FILENAME | 
                clickhouse-client 
                    --host=0.0.0.0 
                    --query="INSERT INTO trips FORMAT CSV"
        done)

เบ„เบงเบฒเบกเป„เบงเบเบฒเบ™เบ™เปเบฒเป€เบ‚เบปเป‰เบฒเปเบกเปˆเบ™ 155 MB เบ‚เบญเบ‡เป€เบ™เบทเป‰เบญเปƒเบ™ CSV เบ—เบตเปˆเบšเปเปˆเป„เบ”เป‰เบšเบตเบšเบญเบฑเบ”เบ•เปเปˆเบงเบดเบ™เบฒเบ—เบต. เบ‚เป‰เบญเบเบชเบปเบ‡เปƒเบชเบงเปˆเบฒเบ™เบตเป‰เปเบกเปˆเบ™เบเป‰เบญเบ™เบเบฒเบ™เบšเบตเบšเบญเบฑเบ”เบ‚เบญเบ‡ GZIP decompression. เบกเบฑเบ™เบญเบฒเบ”เบˆเบฐเป„เบงเบเบงเปˆเบฒเบ—เบตเปˆเบˆเบฐ unzip เป„เบŸเบฅเปŒ gzipped เบ—เบฑเบ‡เบซเบกเบปเบ”เปƒเบ™เบ‚เบฐเบซเบ™เบฒเบ™เป‚เบ”เบเปƒเบŠเป‰ xargs เปเบฅเบฐเบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เป‚เบซเบผเบ” unzipped เบ‚เปเป‰เบกเบนเบ™. เบ‚เป‰เบฒเบ‡เบฅเบธเปˆเบกเบ™เบตเป‰เปเบกเปˆเบ™เบฅเบฒเบเบฅเบฐเบญเบฝเบ”เบ‚เบญเบ‡เบชเบดเปˆเบ‡เบ—เบตเปˆเป„เบ”เป‰เบฅเบฒเบเบ‡เบฒเบ™เปƒเบ™เบฅเบฐเบซเบงเปˆเบฒเบ‡เบ‚เบฐเบšเบงเบ™เบเบฒเบ™เบ™เปเบฒเป€เบ‚เบปเป‰เบฒ CSV.

$ sudo glances

ip-172-30-2-200 (Ubuntu 16.04 64bit / Linux 4.4.0-1072-aws)                                                                                                 Uptime: 0:11:42
CPU       8.2%  nice:     0.0%                           LOAD    36-core                           MEM      9.8%  active:    5.20G                           SWAP      0.0%
user:     6.0%  irq:      0.0%                           1 min:    2.24                            total:  68.7G  inactive:  61.0G                           total:       0
system:   0.9%  iowait:   1.3%                           5 min:    1.83                            used:   6.71G  buffers:   66.4M                           used:        0
idle:    91.8%  steal:    0.0%                           15 min:   1.01                            free:   62.0G  cached:    61.6G                           free:        0

NETWORK     Rx/s   Tx/s   TASKS 370 (507 thr), 2 run, 368 slp, 0 oth sorted automatically by cpu_percent, flat view
ens5        136b    2Kb
lo         343Mb  343Mb     CPU%  MEM%  VIRT   RES   PID USER        NI S    TIME+ IOR/s IOW/s Command
                           100.4   1.5 1.65G 1.06G  9909 ubuntu       0 S  1:01.33     0     0 clickhouse-client --host=0.0.0.0 --query=INSERT INTO trips FORMAT CSV
DISK I/O     R/s    W/s     85.1   0.0 4.65M  708K  9908 ubuntu       0 R  0:50.60   32M     0 gzip -d -c /ch/csv/trips_xac.csv.gz
loop0          0      0     54.9   5.1 8.14G 3.49G  8091 clickhous    0 S  1:44.23     0   45M /usr/bin/clickhouse-server --config=/etc/clickhouse-server/config.xml
loop1          0      0      4.5   0.0     0     0   319 root         0 S  0:07.50    1K     0 kworker/u72:2
nvme0n1        0     3K      2.3   0.0 91.1M 28.9M  9912 root         0 R  0:01.56     0     0 /usr/bin/python3 /usr/bin/glances
nvme0n1p1      0     3K      0.3   0.0     0     0   960 root       -20 S  0:00.10     0     0 kworker/28:1H
nvme1n1    32.1M   495M      0.3   0.0     0     0  1058 root       -20 S  0:00.90     0     0 kworker/23:1H

เบ‚เป‰เบญเบเบˆเบฐเบชเป‰เบฒเบ‡เบžเบทเป‰เบ™เบ—เบตเปˆเบซเบงเปˆเบฒเบ‡เบขเบนเปˆเปƒเบ™เป„เบ”เบฃเบŸเปŒ NVMe เป‚เบ”เบเบเบฒเบ™เบฅเบถเบšเป„เบŸเบฅเปŒ CSV เบ•เบปเป‰เบ™เบชเบฐเบšเบฑเบšเบญเบญเบเบเปˆเบญเบ™เบ—เบตเปˆเบˆเบฐเบชเบทเบšเบ•เปเปˆ.

$ sudo rm -fr /ch/csv

เบ›เปˆเบฝเบ™เป€เบ›เบฑเบ™เปเบšเบšเบŸเบญเบกเบ–เบฑเบ™

เป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบ Log ClickHouse เบˆเบฐเป€เบเบฑเบšเบ‚เปเป‰เบกเบนเบ™เปƒเบ™เบฎเบนเบšเปเบšเบšเปเบ–เบง. เป€เบžเบทเปˆเบญเบชเบญเบšเบ–เบฒเบกเบ‚เปเป‰เบกเบนเบ™เป„เบงเบ‚เบถเป‰เบ™, เบ‚เป‰เบญเบเบ›เปˆเบฝเบ™เป€เบ›เบฑเบ™เบฎเบนเบšเปเบšเบšเบ–เบฑเบ™เป‚เบ”เบเปƒเบŠเป‰เป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบ MergeTree.

$ clickhouse-client --host=0.0.0.0

เบ•เปเปˆเป„เบ›เบ™เบตเป‰เปเบกเปˆเบ™เบชเปเบฒเป€เบฅเบฑเบ”เปƒเบ™ 34 เบ™เบฒเบ—เบต 50 เบงเบดเบ™เบฒเบ—เบต. เบซเบผเบฑเบ‡เบˆเบฒเบเบเบฒเบ™เบ”เปเบฒเป€เบ™เบตเบ™เบ‡เบฒเบ™เบ™เบตเป‰, เบ‚เบฐเบซเบ™เบฒเบ”เบ‚เบญเบ‡เป„เบ”เป€เบฅเบเบฐเบ—เปเบฅเบตเบ‚เปเป‰เบกเบนเบ™เปเบกเปˆเบ™ 237 GB.

CREATE TABLE trips_mergetree
    ENGINE = MergeTree(pickup_date, pickup_datetime, 8192)
    AS SELECT
        trip_id,
        CAST(vendor_id AS Enum8('1' = 1,
                                '2' = 2,
                                'CMT' = 3,
                                'VTS' = 4,
                                'DDS' = 5,
                                'B02512' = 10,
                                'B02598' = 11,
                                'B02617' = 12,
                                'B02682' = 13,
                                'B02764' = 14)) AS vendor_id,
        toDate(pickup_datetime)                 AS pickup_date,
        ifNull(pickup_datetime, toDateTime(0))  AS pickup_datetime,
        toDate(dropoff_datetime)                AS dropoff_date,
        ifNull(dropoff_datetime, toDateTime(0)) AS dropoff_datetime,
        assumeNotNull(store_and_fwd_flag)       AS store_and_fwd_flag,
        assumeNotNull(rate_code_id)             AS rate_code_id,

        assumeNotNull(pickup_longitude)         AS pickup_longitude,
        assumeNotNull(pickup_latitude)          AS pickup_latitude,
        assumeNotNull(dropoff_longitude)        AS dropoff_longitude,
        assumeNotNull(dropoff_latitude)         AS dropoff_latitude,
        assumeNotNull(passenger_count)          AS passenger_count,
        assumeNotNull(trip_distance)            AS trip_distance,
        assumeNotNull(fare_amount)              AS fare_amount,
        assumeNotNull(extra)                    AS extra,
        assumeNotNull(mta_tax)                  AS mta_tax,
        assumeNotNull(tip_amount)               AS tip_amount,
        assumeNotNull(tolls_amount)             AS tolls_amount,
        assumeNotNull(ehail_fee)                AS ehail_fee,
        assumeNotNull(improvement_surcharge)    AS improvement_surcharge,
        assumeNotNull(total_amount)             AS total_amount,
        assumeNotNull(payment_type)             AS payment_type_,
        assumeNotNull(trip_type)                AS trip_type,

        pickup AS pickup,
        pickup AS dropoff,

        CAST(assumeNotNull(cab_type)
            AS Enum8('yellow' = 1, 'green' = 2))
                                AS cab_type,

        precipitation           AS precipitation,
        snow_depth              AS snow_depth,
        snowfall                AS snowfall,
        max_temperature         AS max_temperature,
        min_temperature         AS min_temperature,
        average_wind_speed      AS average_wind_speed,

        pickup_nyct2010_gid     AS pickup_nyct2010_gid,
        pickup_ctlabel          AS pickup_ctlabel,
        pickup_borocode         AS pickup_borocode,
        pickup_boroname         AS pickup_boroname,
        pickup_ct2010           AS pickup_ct2010,
        pickup_boroct2010       AS pickup_boroct2010,
        pickup_cdeligibil       AS pickup_cdeligibil,
        pickup_ntacode          AS pickup_ntacode,
        pickup_ntaname          AS pickup_ntaname,
        pickup_puma             AS pickup_puma,

        dropoff_nyct2010_gid    AS dropoff_nyct2010_gid,
        dropoff_ctlabel         AS dropoff_ctlabel,
        dropoff_borocode        AS dropoff_borocode,
        dropoff_boroname        AS dropoff_boroname,
        dropoff_ct2010          AS dropoff_ct2010,
        dropoff_boroct2010      AS dropoff_boroct2010,
        dropoff_cdeligibil      AS dropoff_cdeligibil,
        dropoff_ntacode         AS dropoff_ntacode,
        dropoff_ntaname         AS dropoff_ntaname,
        dropoff_puma            AS dropoff_puma
    FROM trips;

เบ™เบตเป‰เปเบกเปˆเบ™เบชเบดเปˆเบ‡เบ—เบตเปˆเบœเบปเบ™เบœเบฐเบฅเบดเบ” glance เป€เบšเบดเปˆเบ‡เบ„เบทเปƒเบ™เบฅเบฐเบซเบงเปˆเบฒเบ‡เบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบ‡เบฒเบ™:

ip-172-30-2-200 (Ubuntu 16.04 64bit / Linux 4.4.0-1072-aws)                                                                                                 Uptime: 1:06:09
CPU      10.3%  nice:     0.0%                           LOAD    36-core                           MEM     16.1%  active:    13.3G                           SWAP      0.0%
user:     7.9%  irq:      0.0%                           1 min:    1.87                            total:  68.7G  inactive:  52.8G                           total:       0
system:   1.6%  iowait:   0.8%                           5 min:    1.76                            used:   11.1G  buffers:   71.8M                           used:        0
idle:    89.7%  steal:    0.0%                           15 min:   1.95                            free:   57.6G  cached:    57.2G                           free:        0

NETWORK     Rx/s   Tx/s   TASKS 367 (523 thr), 1 run, 366 slp, 0 oth sorted automatically by cpu_percent, flat view
ens5         1Kb    8Kb
lo           2Kb    2Kb     CPU%  MEM%  VIRT   RES   PID USER        NI S    TIME+ IOR/s IOW/s Command
                           241.9  12.8 20.7G 8.78G  8091 clickhous    0 S 30:36.73   34M  125M /usr/bin/clickhouse-server --config=/etc/clickhouse-server/config.xml
DISK I/O     R/s    W/s      2.6   0.0 90.4M 28.3M  9948 root         0 R  1:18.53     0     0 /usr/bin/python3 /usr/bin/glances
loop0          0      0      1.3   0.0     0     0   203 root         0 S  0:09.82     0     0 kswapd0
loop1          0      0      0.3   0.1  315M 61.3M 15701 ubuntu       0 S  0:00.40     0     0 clickhouse-client --host=0.0.0.0
nvme0n1        0     3K      0.3   0.0     0     0     7 root         0 S  0:00.83     0     0 rcu_sched
nvme0n1p1      0     3K      0.0   0.0     0     0   142 root         0 S  0:00.22     0     0 migration/27
nvme1n1    25.8M   330M      0.0   0.0 59.7M 1.79M  2764 ubuntu       0 S  0:00.00     0     0 (sd-pam)

เปƒเบ™เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบ„เบฑเป‰เบ‡เบชเบธเบ”เบ—เป‰เบฒเบ, เบซเบผเบฒเบเบ–เบฑเบ™เป„เบ”เป‰เบ–เบทเบเบ›เปˆเบฝเบ™เปเบฅเบฐเบ„เบดเบ”เป„เบฅเปˆเบ„เบทเบ™เปƒเบซเบกเปˆ. เบ‚เป‰เบญเบเบžเบปเบšเบงเปˆเบฒเบšเบฒเบ‡เบŸเบฑเบ‡เบŠเบฑเบ™เป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เบšเปเปˆเป€เบฎเบฑเบ”เบงเบฝเบเบ•เบฒเบกเบ—เบตเปˆเบ„เบฒเบ”เป„เบงเป‰เบขเบนเปˆเปƒเบ™เบŠเบธเบ”เบ‚เปเป‰เบกเบนเบ™เบ™เบตเป‰. เป€เบžเบทเปˆเบญเปเบเป‰เป„เบ‚เบšเบฑเบ™เบซเบฒเบ™เบตเป‰, เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เบฅเบถเบšเบซเบ™เป‰เบฒเบ—เบตเปˆเบšเปเปˆเป€เบซเบกเบฒเบฐเบชเบปเบกเปเบฅเบฐเป‚เบซเบฅเบ”เบ‚เปเป‰เบกเบนเบ™เป‚เบ”เบเบšเปเปˆเบกเบตเบเบฒเบ™เบ›เปˆเบฝเบ™เป€เบ›เบฑเบ™เบ›เบฐเป€เบžเบ”เป€เบกเบฑเบ”เบซเบผเบฒเบ.

เบเบฒเบ™เปเบˆเบเบขเบฒเบเบ‚เปเป‰เบกเบนเบ™เบ—เบปเปˆเบงเบเบธเปˆเบก

เบ‚เป‰เบญเบเบˆเบฐเปเบˆเบเบขเบฒเบเบ‚เปเป‰เบกเบนเบ™เบ—เบปเปˆเบงเบ—เบฑเบ‡เบชเบฒเบกเบ‚เปเป‰เบ‚เบญเบ‡เบเบธเปˆเบก. เป€เบžเบทเปˆเบญเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™, เบ‚เป‰เบฒเบ‡เบฅเบธเปˆเบกเบ™เบตเป‰เบ‚เป‰เบญเบเบˆเบฐเบชเป‰เบฒเบ‡เบ•เบฒเบ•เบฐเบฅเบฒเบ‡เปƒเบ™เบ—เบฑเบ‡เบชเบฒเบกเป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบ.

$ clickhouse-client --host=0.0.0.0

CREATE TABLE trips_mergetree_third (
    trip_id                 UInt32,
    vendor_id               String,
    pickup_date             Date,
    pickup_datetime         DateTime,
    dropoff_date            Date,
    dropoff_datetime        Nullable(DateTime),
    store_and_fwd_flag      Nullable(FixedString(1)),
    rate_code_id            Nullable(UInt8),
    pickup_longitude        Nullable(Float64),
    pickup_latitude         Nullable(Float64),
    dropoff_longitude       Nullable(Float64),
    dropoff_latitude        Nullable(Float64),
    passenger_count         Nullable(UInt8),
    trip_distance           Nullable(Float64),
    fare_amount             Nullable(Float32),
    extra                   Nullable(Float32),
    mta_tax                 Nullable(Float32),
    tip_amount              Nullable(Float32),
    tolls_amount            Nullable(Float32),
    ehail_fee               Nullable(Float32),
    improvement_surcharge   Nullable(Float32),
    total_amount            Nullable(Float32),
    payment_type            Nullable(String),
    trip_type               Nullable(UInt8),
    pickup                  Nullable(String),
    dropoff                 Nullable(String),

    cab_type                Nullable(String),

    precipitation           Nullable(Int8),
    snow_depth              Nullable(Int8),
    snowfall                Nullable(Int8),
    max_temperature         Nullable(Int8),
    min_temperature         Nullable(Int8),
    average_wind_speed      Nullable(Int8),

    pickup_nyct2010_gid     Nullable(Int8),
    pickup_ctlabel          Nullable(String),
    pickup_borocode         Nullable(Int8),
    pickup_boroname         Nullable(String),
    pickup_ct2010           Nullable(String),
    pickup_boroct2010       Nullable(String),
    pickup_cdeligibil       Nullable(FixedString(1)),
    pickup_ntacode          Nullable(String),
    pickup_ntaname          Nullable(String),
    pickup_puma             Nullable(String),

    dropoff_nyct2010_gid    Nullable(UInt8),
    dropoff_ctlabel         Nullable(String),
    dropoff_borocode        Nullable(UInt8),
    dropoff_boroname        Nullable(String),
    dropoff_ct2010          Nullable(String),
    dropoff_boroct2010      Nullable(String),
    dropoff_cdeligibil      Nullable(String),
    dropoff_ntacode         Nullable(String),
    dropoff_ntaname         Nullable(String),
    dropoff_puma            Nullable(String)
) ENGINE = MergeTree(pickup_date, pickup_datetime, 8192);

เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™, เบ‚เป‰เบญเบเบˆเบฐเปƒเบซเป‰เปเบ™เปˆเปƒเบˆเบงเปˆเบฒเป€เบ„เบทเปˆเบญเบ‡เปเบกเปˆเบ‚เปˆเบฒเบเบ—เปเบฒเบญเบดเบ”เบชเบฒเบกเบฒเบ”เป€เบšเบดเปˆเบ‡เบ—เบฑเบ‡เบชเบฒเบก nodes เปƒเบ™ cluster.

SELECT *
FROM system.clusters
WHERE cluster = 'perftest_3shards'
FORMAT Vertical;
Row 1:
โ”€โ”€โ”€โ”€โ”€โ”€
cluster:          perftest_3shards
shard_num:        1
shard_weight:     1
replica_num:      1
host_name:        172.30.2.192
host_address:     172.30.2.192
port:             9000
is_local:         1
user:             default
default_database:
Row 2:
โ”€โ”€โ”€โ”€โ”€โ”€
cluster:          perftest_3shards
shard_num:        2
shard_weight:     1
replica_num:      1
host_name:        172.30.2.162
host_address:     172.30.2.162
port:             9000
is_local:         0
user:             default
default_database:

Row 3:
โ”€โ”€โ”€โ”€โ”€โ”€
cluster:          perftest_3shards
shard_num:        3
shard_weight:     1
replica_num:      1
host_name:        172.30.2.36
host_address:     172.30.2.36
port:             9000
is_local:         0
user:             default
default_database:

เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™, เบ‚เป‰เบญเบเบˆเบฐเบเปเบฒเบ™เบปเบ”เบ•เบฒเบ•เบฐเบฅเบฒเบ‡เปƒเบซเบกเปˆเปƒเบ™เป€เบ„เบทเปˆเบญเบ‡เปเบกเปˆเบ‚เปˆเบฒเบเบ—เปเบฒเบญเบดเบ”เบ—เบตเปˆเบญเบตเบ‡เปƒเบชเปˆ schema trips_mergetree_third เปเบฅเบฐเปƒเบŠเป‰เป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบเปเบˆเบเบขเบฒเบ.

CREATE TABLE trips_mergetree_x3
    AS trips_mergetree_third
    ENGINE = Distributed(perftest_3shards,
                         default,
                         trips_mergetree_third,
                         rand());

เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบ‚เป‰เบญเบเบˆเบฐเบ„เบฑเบ”เบฅเบญเบเบ‚เปเป‰เบกเบนเบ™เบˆเบฒเบเบ•เบฒเบ•เบฐเบฅเบฒเบ‡ MergeTree เป„เบ›เบซเบฒเป€เบ„เบทเปˆเบญเบ‡เปเบกเปˆเบ‚เปˆเบฒเบเบ—เบฑเบ‡เบชเบฒเบก. เบ•เปเปˆเป„เบ›เบ™เบตเป‰เปเบกเปˆเบ™เบชเปเบฒเป€เบฅเบฑเบ”เปƒเบ™ 34 เบ™เบฒเบ—เบต 44 เบงเบดเบ™เบฒเบ—เบต.

INSERT INTO trips_mergetree_x3
    SELECT * FROM trips_mergetree;

ะŸะพัะปะต ะฟั€ะธะฒะตะดะตะฝะฝะพะน ะฒั‹ัˆะต ะพะฟะตั€ะฐั†ะธะธ ั ะดะฐะป ClickHouse 15 ะผะธะฝัƒั‚, ั‡ั‚ะพะฑั‹ ะพั‚ะพะนั‚ะธ ะพั‚ ะพั‚ะผะตั‚ะบะธ ะผะฐะบัะธะผะฐะปัŒะฝะพะณะพ ัƒั€ะพะฒะฝั ั…ั€ะฐะฝะธะปะธั‰ะฐ. ะšะฐั‚ะฐะปะพะณะธ ะดะฐะฝะฝั‹ั… ะฒ ะบะพะฝะตั‡ะฝะพะผ ะธั‚ะพะณะต ัะพัั‚ะฐะฒะปัะปะธ 264 ะ“ะ‘, 34 ะ“ะ‘ ะธ 33 ะ“ะ‘ ัะพะพั‚ะฒะตั‚ัั‚ะฒะตะฝะฝะพ ะฝะฐ ะบะฐะถะดะพะผ ะธะท ั‚ั€ะตั… ัะตั€ะฒะตั€ะพะฒ.

เบเบฒเบ™เบ›เบฐเป€เบกเบตเบ™เบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบšเบ‚เบญเบ‡เบเบธเปˆเบก ClickHouse

เบชเบดเปˆเบ‡เบ—เบตเปˆเบ‚เป‰เบญเบเป€เบซเบฑเบ™เบ•เปเปˆเป„เบ›เปเบกเปˆเบ™เป€เบงเบฅเบฒเบ—เบตเปˆเป„เบงเบ—เบตเปˆเบชเบธเบ”เบ—เบตเปˆเบ‚เป‰เบญเบเป„เบ”เป‰เป€เบซเบฑเบ™เปเบฅเปˆเบ™เปเบ•เปˆเบฅเบฐเบ„เปเบฒเบ–เบฒเบกเบขเบนเปˆเปƒเบ™เบ•เบฒเบ•เบฐเบฅเบฒเบ‡เบซเบผเบฒเบเป†เบ„เบฑเป‰เบ‡ trips_mergetree_x3.

$ clickhouse-client --host=0.0.0.0

เบ•เปเปˆเป„เบ›เบ™เบตเป‰เบชเปเบฒเป€เบฅเบฑเบ”เปƒเบ™ 2.449 เบงเบดเบ™เบฒเบ—เบต.

SELECT cab_type, count(*)
FROM trips_mergetree_x3
GROUP BY cab_type;

เบ•เปเปˆเป„เบ›เบ™เบตเป‰เบชเปเบฒเป€เบฅเบฑเบ”เปƒเบ™ 0.691 เบงเบดเบ™เบฒเบ—เบต.

SELECT passenger_count,
       avg(total_amount)
FROM trips_mergetree_x3
GROUP BY passenger_count;

เบ•เปเปˆเป„เบ›เบ™เบตเป‰เบชเปเบฒเป€เบฅเบฑเบ”เปƒเบ™ 0 เบงเบดเบ™เบฒเบ—เบต.

SELECT passenger_count,
       toYear(pickup_date) AS year,
       count(*)
FROM trips_mergetree_x3
GROUP BY passenger_count,
         year;

เบ•เปเปˆเป„เบ›เบ™เบตเป‰เบชเปเบฒเป€เบฅเบฑเบ”เปƒเบ™ 0.983 เบงเบดเบ™เบฒเบ—เบต.

SELECT passenger_count,
       toYear(pickup_date) AS year,
       round(trip_distance) AS distance,
       count(*)
FROM trips_mergetree_x3
GROUP BY passenger_count,
         year,
         distance
ORDER BY year,
         count(*) DESC;

เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ›เบฝเบšเบ—เบฝเบš, เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™เบชเบญเบšเบ–เบฒเบกเบ”เบฝเบงเบเบฑเบ™เบขเบนเปˆเปƒเบ™เบ•เบฒเบ•เบฐเบฅเบฒเบ‡ MergeTree เบ—เบตเปˆเบญเบฒเป„เบชเบขเบนเปˆเปƒเบ™เป€เบ„เบทเปˆเบญเบ‡เปเบกเปˆเบ‚เปˆเบฒเบเบ—เปเบฒเบญเบดเบ”เป€เบ—เบปเปˆเบฒเบ™เบฑเป‰เบ™.

เบเบฒเบ™เบ›เบฐเป€เบกเบตเบ™เบœเบปเบ™เบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบ‚เบญเบ‡เบซเบ™เบถเปˆเบ‡ ClickHouse node

เบชเบดเปˆเบ‡เบ—เบตเปˆเบ‚เป‰เบญเบเป€เบซเบฑเบ™เบ•เปเปˆเป„เบ›เปเบกเปˆเบ™เป€เบงเบฅเบฒเบ—เบตเปˆเป„เบงเบ—เบตเปˆเบชเบธเบ”เบ—เบตเปˆเบ‚เป‰เบญเบเป„เบ”เป‰เป€เบซเบฑเบ™เปเบฅเปˆเบ™เปเบ•เปˆเบฅเบฐเบ„เปเบฒเบ–เบฒเบกเบขเบนเปˆเปƒเบ™เบ•เบฒเบ•เบฐเบฅเบฒเบ‡เบซเบผเบฒเบเป†เบ„เบฑเป‰เบ‡ trips_mergetree_x3.

เบ•เปเปˆเป„เบ›เบ™เบตเป‰เบชเปเบฒเป€เบฅเบฑเบ”เปƒเบ™ 0.241 เบงเบดเบ™เบฒเบ—เบต.

SELECT cab_type, count(*)
FROM trips_mergetree
GROUP BY cab_type;

เบ•เปเปˆเป„เบ›เบ™เบตเป‰เบชเปเบฒเป€เบฅเบฑเบ”เปƒเบ™ 0.826 เบงเบดเบ™เบฒเบ—เบต.

SELECT passenger_count,
       avg(total_amount)
FROM trips_mergetree
GROUP BY passenger_count;

เบ•เปเปˆเป„เบ›เบ™เบตเป‰เบชเปเบฒเป€เบฅเบฑเบ”เปƒเบ™ 1.209 เบงเบดเบ™เบฒเบ—เบต.

SELECT passenger_count,
       toYear(pickup_date) AS year,
       count(*)
FROM trips_mergetree
GROUP BY passenger_count,
         year;

เบ•เปเปˆเป„เบ›เบ™เบตเป‰เบชเปเบฒเป€เบฅเบฑเบ”เปƒเบ™ 1.781 เบงเบดเบ™เบฒเบ—เบต.

SELECT passenger_count,
       toYear(pickup_date) AS year,
       round(trip_distance) AS distance,
       count(*)
FROM trips_mergetree
GROUP BY passenger_count,
         year,
         distance
ORDER BY year,
         count(*) DESC;

เบชเบฐเบ—เป‰เบญเบ™เปƒเบซเป‰เป€เบซเบฑเบ™เบœเบปเบ™เป„เบ”เป‰เบฎเบฑเบš

เบ™เบตเป‰โ€‹เปเบกเปˆเบ™โ€‹เบ„เบฑเป‰เบ‡โ€‹เบ—เปเบฒโ€‹เบญเบดเบ”โ€‹เบ—เบตเปˆโ€‹เบ–เบฒเบ™โ€‹เบ‚เปเป‰โ€‹เบกเบนเบ™โ€‹เบ—เบตเปˆโ€‹เบญเบตเบ‡โ€‹เปƒเบชเปˆ CPU เบŸเบฃเบตโ€‹เบชเบฒโ€‹เบกเบฒเบ”โ€‹เป€เบฎเบฑเบ”โ€‹เปƒเบซเป‰โ€‹เบ”เบตเบโ€‹เบงเปˆเบฒโ€‹เบ–เบฒเบ™โ€‹เบ‚เปเป‰โ€‹เบกเบนเบ™โ€‹เบ—เบตเปˆโ€‹เปƒเบŠเป‰ GPU เปƒเบ™โ€‹เบเบฒเบ™โ€‹เบ—เบปเบ”โ€‹เบชเบญเบšโ€‹เบ‚เบญเบ‡โ€‹เบ‚เป‰เบฒโ€‹เบžเบฐโ€‹เป€เบˆเบปเป‰เบฒโ€‹. เบ–เบฒเบ™เบ‚เปเป‰เบกเบนเบ™เบ—เบตเปˆเบญเบตเบ‡เปƒเบชเปˆ GPU เบ™เบฑเป‰เบ™เป„เบ”เป‰เบœเปˆเบฒเบ™เบเบฒเบ™เบ”เบฑเบ”เปเบเป‰เบชเบญเบ‡เบ„เบฑเป‰เบ‡เบ™เบฑเบšเบ•เบฑเป‰เบ‡เปเบ•เปˆเบ™เบฑเป‰เบ™เบกเบฒ, เปเบ•เปˆเบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบ—เบตเปˆ ClickHouse เบชเบปเปˆเบ‡เบขเบนเปˆเปƒเบ™เป‚เบซเบ™เบ”เบ”เบฝเบงเปเบกเปˆเบ™เบขเปˆเบฒเบ‡เปƒเบ”เบเปเปˆเบ•เบฒเบกเบ—เบตเปˆเบ›เบฐเบ—เบฑเบšเปƒเบˆเบซเบผเบฒเบ.

เปƒเบ™เบ‚เบฐเบ™เบฐเบ”เบฝเบงเบเบฑเบ™, เป€เบกเบทเปˆเบญเบ›เบฐเบ•เบดเบšเบฑเบ” Query 1 เปƒเบ™เป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบเบ—เบตเปˆเปเบˆเบเบขเบฒเบ, เบ„เปˆเบฒเปƒเบŠเป‰เบˆเปˆเบฒเบเบ•เปเปˆเบซเบปเบงเปเบกเปˆเบ™เบ„เปเบฒเบชเบฑเปˆเบ‡เบ—เบตเปˆเบชเบนเบ‡เบเบงเปˆเบฒ. เบ‚เป‰เบญเบเบซเบงเบฑเบ‡เบงเปˆเบฒเบ‚เป‰เบญเบเบžเบฒเบ”เบšเบฒเบ‡เบชเบดเปˆเบ‡เบšเบฒเบ‡เบขเปˆเบฒเบ‡เปƒเบ™เบเบฒเบ™เบ„เบปเป‰เบ™เบ„เบงเป‰เบฒเบ‚เบญเบ‡เบ‚เป‰เบญเบเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ•เบญเบšเบ™เบตเป‰เป€เบžเบฒเบฐเบงเปˆเบฒเบกเบฑเบ™เบˆเบฐเบ”เบตเบ—เบตเปˆเบˆเบฐเป€เบซเบฑเบ™เป€เบงเบฅเบฒเบเบฒเบ™เบชเบญเบšเบ–เบฒเบกเบซเบผเบธเบ”เบฅเบปเบ‡เบเป‰เบญเบ™เบงเปˆเบฒเบ‚เป‰เบญเบเป€เบžเบตเปˆเบกเบ‚เปเป‰เป€เบžเบตเปˆเบกเป€เบ•เบตเบกเปƒเบชเปˆเบเบธเปˆเบก. เบขเปˆเบฒเบ‡เปƒเบ”เบเปเบ•เบฒเบก, เบกเบฑเบ™เป€เบ›เบฑเบ™เบเบฒเบ™เบ”เบตเบ—เบตเปˆเปƒเบ™เป€เบงเบฅเบฒเบ—เบตเปˆเบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™เบชเบญเบšเบ–เบฒเบกเบญเบทเปˆเบ™เป†, เบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบšเป€เบžเบตเปˆเบกเบ‚เบถเป‰เบ™เบ›เบฐเบกเบฒเบ™ 2 เป€เบ—เบปเปˆเบฒ.

เบกเบฑเบ™เบˆเบฐเป€เบ›เบฑเบ™เบเบฒเบ™เบ”เบตเบ—เบตเปˆเบˆเบฐเป€เบซเบฑเบ™ ClickHouse เบžเบฑเบ”เบ—เบฐเบ™เบฒเป„เบ›เบชเบนเปˆเบ„เบงเบฒเบกเบชเบฒเบกเบฒเบ”เปƒเบ™เบเบฒเบ™เปเบเบเบเบฒเบ™เป€เบเบฑเบšเบฎเบฑเบเบชเบฒเปเบฅเบฐเบ„เบญเบกเบžเบดเบงเป€เบ•เบตเป‰เป€เบžเบทเปˆเบญเปƒเบซเป‰เบžเบงเบเป€เบ‚เบปเบฒเบชเบฒเบกเบฒเบ”เบ‚เบฐเบซเบเบฒเบเป„เบ”เป‰เบขเปˆเบฒเบ‡เป€เบ›เบฑเบ™เป€เบญเบเบฐเบฅเบฒเบ”. เบเบฒเบ™เบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™ HDFS, เป€เบŠเบดเปˆเบ‡เป„เบ”เป‰เบ–เบทเบเป€เบžเบตเปˆเบกเปƒเบ™เบ›เบตเบเบฒเบเบ™เบตเป‰, เบชเบฒเบกเบฒเบ”เป€เบ›เบฑเบ™เบšเบฒเบ”เบเป‰เบฒเบงเป„เบ›เบชเบนเปˆเบเบฒเบ™เบ™เบตเป‰. เปƒเบ™เปเบ‡เปˆเบ‚เบญเบ‡เบ„เบญเบกเบžเบดเบงเป€เบ•เบตเป‰, เบ–เป‰เบฒเบเบฒเบ™เบชเบญเบšเบ–เบฒเบกเบ”เบฝเบงเบชเบฒเบกเบฒเบ”เป€เบฅเบฑเปˆเบ‡เป„เบ”เป‰เป‚เบ”เบเบเบฒเบ™เป€เบžเบตเปˆเบกเป‚เบซเบ™เบ”เป€เบžเบตเปˆเบกเป€เบ•เบตเบกเปƒเบซเป‰เบเบฑเบšเบเบธเปˆเบก, เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™, เบญเบฐเบ™เบฒเบ„เบปเบ”เบ‚เบญเบ‡เบŠเบญเบšเปเบงเบ™เบตเป‰เปเบกเปˆเบ™เบชเบปเบ”เปƒเบชเบซเบผเบฒเบ.

เบ‚เปเบ‚เบญเบšเปƒเบˆเบ—เปˆเบฒเบ™เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เปƒเบŠเป‰เป€เบงเบฅเบฒเบญเปˆเบฒเบ™เบ‚เปเป‰เบ„เบงเบฒเบกเบ™เบตเป‰. เบ‚เป‰เบฒโ€‹เบžเบฐโ€‹เป€เบˆเบปเป‰เบฒโ€‹เบชเบฐโ€‹เป€เบซเบ™เบตโ€‹เปƒเบซเป‰โ€‹เบ„เปเบฒโ€‹เบ›เบถเบโ€‹เบชเบฒโ€‹, เบชเบฐโ€‹เบ–เบฒโ€‹เบ›เบฑเบ”โ€‹เบ•เบฐโ€‹, เปเบฅเบฐโ€‹เบเบฒเบ™โ€‹เบ›เบฐโ€‹เบ•เบดโ€‹เบšเบฑเบ”โ€‹เบเบฒเบ™โ€‹เบšเปโ€‹เบฅเบดโ€‹เบเบฒเบ™โ€‹เบžเบฑเบ”โ€‹เบ—เบฐโ€‹เบ™เบฒโ€‹เปƒเบซเป‰โ€‹เบฅเบนเบโ€‹เบ„เป‰เบฒโ€‹เปƒเบ™โ€‹เบญเบฒโ€‹เป€เบกเบฅเบดโ€‹เบเบฒโ€‹เป€เบซเบ™เบทเบญโ€‹เปเบฅเบฐโ€‹เป€เบญเบตโ€‹เบฃเบปเบšโ€‹. เบ–เป‰เบฒเบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เบเบฒเบ™เบชเบปเบ™เบ—เบฐเบ™เบฒเบงเปˆเบฒเบ„เปเบฒเปเบ™เบฐเบ™เปเบฒเบ‚เบญเบ‡เบ‚เป‰เบญเบเบชเบฒเบกเบฒเบ”เบŠเปˆเบงเบเบ—เบธเบฅเบฐเบเบดเบ”เบ‚เบญเบ‡เบ—เปˆเบฒเบ™เป„เบ”เป‰เปเบ™เบงเปƒเบ”, เบเบฐเบฅเบธเบ™เบฒเบ•เบดเบ”เบ•เปเปˆเบ‚เป‰เบญเบเบœเปˆเบฒเบ™เบ—เบฒเบ‡ LinkedIn.

เปเบซเบผเปˆเบ‡เบ‚เปเป‰เบกเบนเบ™: www.habr.com

เป€เบžเบตเปˆเบกเบ„เบงเบฒเบกเบ„เบดเบ”เป€เบซเบฑเบ™