1.1 тэрбум таксины аялал: 108 цөмт ClickHouse кластер

Өгүүллийн орчуулгыг тус курсын оюутнуудад зориулж тусгайлан бэлтгэсэн "Өгөгдлийн инженер".

1.1 тэрбум таксины аялал: 108 цөмт ClickHouse кластер

clickhouse нь нээлттэй эхийн багана мэдээллийн сан юм. Энэ нь өдөрт хэдэн арван тэрбум шинэ бичлэг оруулдаг ч гэсэн хэдэн зуун шинжээч нарийвчилсан мэдээллийг хурдан шуурхай авах боломжтой орчин юм. Ийм системийг дэмжих дэд бүтцийн зардал нь жилд 100 доллар хүртэл өндөр байж болох бөгөөд ашиглалтаас хамаарч түүний тал хувь нь байж болно. Нэгэн цагт Yandex Metrics-ийн ClickHouse суулгац нь 10 их наяд бичлэгийг агуулж байсан. Yandex-ээс гадна ClickHouse нь Bloomberg болон Cloudflare-тэй амжилтанд хүрсэн.

Хоёр жилийн өмнө би зарцуулсан харьцуулсан шинжилгээ нэг машин ашиглан мэдээллийн сан, мөн энэ нь болсон хамгийн хурдан Миний харж байсан үнэгүй мэдээллийн сангийн програм хангамж. Түүнээс хойш хөгжүүлэгчид Кафка, HDFS болон ZStandard шахалтыг дэмжих зэрэг функцуудыг нэмэхээ зогсоосонгүй. Өнгөрсөн жил тэд каскадын шахалтын аргуудын дэмжлэгийг нэмсэн, мөн дельта-аас-дельта кодлох боломжтой болсон. Цагийн цувааны өгөгдлийг шахахдаа хэмжигч утгыг гурвалжин кодчилол ашиглан сайн шахаж болох боловч тоолуурын хувьд гурвалжин кодчилол ашиглах нь дээр. Сайн шахалт нь ClickHouse-ийн гүйцэтгэлийн түлхүүр болсон.

ClickHouse нь гуравдагч этгээдийн номын санг эс тооцвол 170 мянган мөр C++ кодоос бүрдэх ба тархсан мэдээллийн сангийн хамгийн жижиг кодын нэг юм. Харьцуулбал, SQLite нь түгээлтийг дэмждэггүй бөгөөд 235 мянган мөр C кодоос бүрддэг.Энэ бичвэрийг бичиж байх хугацаанд 207 инженер ClickHouse-д хувь нэмрээ оруулсан бөгөөд сүүлийн үед commit-ийн эрч хүч нэмэгдэж байна.

2017 оны XNUMX-р сард ClickHouse үйл ажиллагаагаа явуулж эхэлсэн өөрчлөлтийн бүртгэл хөгжлийг хянах хялбар арга юм. Тэд мөн цул баримт бичгийн файлыг Markdown-д суурилсан файлын шатлал болгон задалсан. Асуудал, боломжуудыг GitHub-ээр хянадаг бөгөөд ерөнхийдөө програм хангамж нь сүүлийн хэдэн жилд илүү хүртээмжтэй болсон.

Энэ нийтлэлд би 2 цөмт процессор болон NVMe санах ой ашиглан AWS EC36 дээрх ClickHouse кластерын гүйцэтгэлийг авч үзэх болно.

ШИНЭЧЛЭЛ: Энэ нийтлэлийг анх нийтэлснээс хойш долоо хоногийн дараа би сайжруулсан тохиргоотой тестийг дахин хийж, илүү сайн үр дүнд хүрсэн. Эдгээр өөрчлөлтийг тусгахын тулд энэ нийтлэлийг шинэчилсэн.

AWS EC2 кластерыг эхлүүлж байна

Би энэ нийтлэлд гурван c5d.9xlarge EC2 жишээ ашиглах болно. Тус бүр нь 36 виртуал CPU, 72 ГБ RAM, 900 ГБ NVMe SSD санах ойтой бөгөөд 10 Гигабит сүлжээг дэмждэг. Тэд эрэлт хэрэгцээтэй ажиллах үед Европын баруун-1,962 бүсэд тус бүр нь 1 долларын үнэтэй байдаг. Би Ubuntu Server 16.04 LTS-ийг үйлдлийн систем болгон ашиглах болно.

Галт ханыг машин бүр өөр хоорондоо ямар ч хязгаарлалтгүйгээр харилцаж чадахаар тохируулсан бөгөөд зөвхөн миний IPv4 хаягийг кластерт SSH-ийн жагсаалтад оруулсан болно.

NVMe хөтөч ажиллахад бэлэн байдалд байна

ClickHouse-г ажиллуулахын тулд би сервер бүр дээр NVMe диск дээр EXT4 форматтай файлын системийг үүсгэх болно.

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

Бүх зүйлийг тохируулсны дараа та холбох цэг болон систем бүр дээр байгаа 783 ГБ зайг харж болно.

$ 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 жилийн хугацаанд Нью-Йорк хотод XNUMX тэрбум такси унасны үр дүнд бий болгосон мэдээллийн сан юм. Блог дээр Redshift дахь нэг тэрбум таксины аялал Би энэ өгөгдлийн багцыг хэрхэн цуглуулсан тухай дэлгэрэнгүй. Тэдгээр нь AWS S3-д хадгалагдсан тул би өөрийн нэвтрэх эрх болон нууц түлхүүрүүдээр AWS CLI-г тохируулах болно.

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

Файлуудыг анхдагч тохиргооноос хурдан татаж авахын тулд би үйлчлүүлэгчийн нэгэн зэрэг хүсэлтийн хязгаарыг 100 болгож тохируулах болно.

$ aws configure set 
    default.s3.max_concurrent_requests 
    100

Би таксины өгөгдлийн багцыг AWS S3-аас татаж аваад эхний сервер дээрх NVMe драйв дээр хадгалах болно. Энэ өгөгдлийн багц GZIP шахагдсан CSV форматтай ~104 ГБ байна.

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

ClickHouse суулгац

Бүх гурван машин дээр ClickHouse-г түгээх суулгахад шаардлагатай Apache ZooKeeper-ийг ажиллуулах шаардлагатай тул би Java 8-д зориулсан OpenJDK түгээлтийг суулгах болно.

$ 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-д зориулсан лавлах үүсгэх бөгөөд мөн бүх гурван сервер дээр зарим тохиргоог хүчингүй болгох болно.

$ 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

Эдгээр нь миний ашиглах тохиргооны тохиргоонууд юм.

<?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), Лог хөдөлгүүрийг ашиглан таксины аяллын мэдээллийн багцыг хадгалах болно.

$ 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 ГБ болсон.

$ 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 МБ шахагдаагүй CSV контент байсан. Энэ нь GZIP задлах гацаанаас болсон гэж би сэжиглэж байна. Бүх gzip файлуудыг xargs ашиглан зэрэгцээ задлаад задалсан өгөгдлийг ачаалах нь илүү хурдан байсан байж магадгүй юм. 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

Би үргэлжлүүлэхээсээ өмнө эх CSV файлуудыг устгаснаар NVMe драйв дээр зай гаргах болно.

$ sudo rm -fr /ch/csv

Баганын маягт руу хөрвүүлэх

Log ClickHouse хөдөлгүүр нь өгөгдлийг мөр рүү чиглэсэн форматаар хадгалах болно. Өгөгдлийг илүү хурдан хайхын тулд би MergeTree хөдөлгүүрийг ашиглан багана хэлбэрт хөрвүүлдэг.

$ clickhouse-client --host=0.0.0.0

Дараахь ажлыг 34 минут 50 секундэд дуусгасан. Энэ үйлдлийн дараа мэдээллийн сангийн хэмжээ 237 ГБ болсон.

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;

Үйл ажиллагааны явцад харцны гаралт дараах байдалтай байв.

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);

Дараа нь би эхний сервер кластерын бүх гурван зангилааг харж чадах эсэхийг шалгах болно.

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:

Дараа нь би схем дээр суурилсан эхний сервер дээр шинэ хүснэгтийг тодорхойлох болно trips_mergetree_third бөгөөд Distributed хөдөлгүүрийг ашигладаг.

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 зангилааны гүйцэтгэлийн үнэлгээ

Дараа нь харсан зүйл бол асуулга бүрийг ширээн дээр олон удаа ажиллуулж байхыг харсан хамгийн хурдан үе юм 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

сэтгэгдэл нэмэх