1,1 milliard de trajets en taxi: cluster ClickHouse à 108 cƓurs

Une traduction de l'article a été préparée spécialement pour les étudiants du cours Data Engineer .





ClickHouse est une base de donnĂ©es de colonnes open source. Il s'agit d'un environnement idĂ©al oĂč des centaines d'analystes peuvent demander rapidement des donnĂ©es dĂ©taillĂ©es, mĂȘme lorsque des dizaines de milliards de nouvelles entrĂ©es sont introduites par jour. Les coĂ»ts d'infrastructure pour prendre en charge un tel systĂšme peuvent atteindre 100 000 dollars par an, et potentiellement la moitiĂ©, selon l'utilisation. À un moment donnĂ©, l'installation de Yandex.Metrica ClickHouse contenait 10 billions d'entrĂ©es. En plus de Yandex, ClickHouse a Ă©galement remportĂ© du succĂšs avec Bloomberg et Cloudflare.

Il y a deux ans, j'ai fait une analyse comparative des bases de donnĂ©es Ă  l'aide d'une seule machine, et c'est devenu le logiciel de base de donnĂ©es gratuit le plus rapide que j'aie jamais vu. Depuis lors, les dĂ©veloppeurs n'ont cessĂ© d'ajouter des fonctionnalitĂ©s, notamment la prise en charge de la compression Kafka, HDFS et ZStandard. L'annĂ©e derniĂšre, ils ont ajoutĂ© la prise en charge des mĂ©thodes de compression en cascade et le codage delta-delta est devenu possible. Lors de la compression des donnĂ©es de sĂ©ries chronologiques, les valeurs de jauge peuvent ĂȘtre bien compressĂ©es Ă  l'aide du codage delta, mais il sera prĂ©fĂ©rable d'utiliser le codage delta-delta pour les compteurs. Une bonne compression est devenue la clĂ© des performances de ClickHouse.

ClickHouse se compose de 170 000 lignes de code C ++, Ă  l'exception des bibliothĂšques tierces, et est l'une des plus petites bases de donnĂ©es de code pour les bases de donnĂ©es distribuĂ©es. À titre de comparaison, SQLite ne prend pas en charge la distribution et se compose de 235 000 lignes de code en langage C. Au moment d'Ă©crire ces lignes, 207 ingĂ©nieurs ont contribuĂ© Ă  ClickHouse, et l'intensitĂ© des commits a rĂ©cemment augmentĂ©.

En mars 2017, ClickHouse a commencé un journal des modifications comme moyen facile de suivre le développement. Ils ont également divisé le fichier de documentation monolithique en une hiérarchie de fichiers basée sur Markdown. Les problÚmes et les fonctionnalités sont suivis via GitHub, et dans l'ensemble, ce logiciel est devenu beaucoup plus accessible au cours des derniÚres années.

Dans cet article, je vais jeter un Ɠil aux performances du cluster ClickHouse sur AWS EC2 en utilisant des processeurs 36 cƓurs et un lecteur NVMe.
MISE À JOUR: Une semaine aprĂšs la publication initiale de cet article, j'ai relancĂ© le test avec une configuration amĂ©liorĂ©e et obtenu de bien meilleurs rĂ©sultats. Ce message a Ă©tĂ© mis Ă  jour pour reflĂ©ter ces changements.

Démarrage d'un cluster AWS EC2


J'utiliserai trois instances de c5d.9xlarge EC2 pour ce message. Chacun d'eux contient 36 CPU virtuels, 72 Go de RAM, 900 Go de SSD NVMe et prend en charge un réseau de 10 gigabits. Ils coûtent 1 962 $ / heure chacun dans la région eu-west-1 lorsqu'ils sont lancés sur demande. J'utiliserai Ubuntu Server 16.04 LTS comme systÚme d'exploitation.

Le pare-feu est configuré pour que chaque machine puisse communiquer entre elles sans restrictions, et seule mon adresse IPv4 est mise en liste blanche dans le cluster SSH.

NVMe prĂȘt Ă  l'emploi


Pour que ClickHouse fonctionne, je vais créer un systÚme de fichiers EXT4 sur chaque serveur du lecteur NVMe.

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

Une fois que tout est configuré, vous pouvez voir le point de montage et 783 Go d'espace disponible dans chacun des systÚmes.

 $ 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 

L'ensemble de données que j'utiliserai dans ce test est un vidage de données que j'ai généré à partir de 1,1 milliard de trajets en taxi effectués à New York en six ans. Le blog Billion Taxi sur Redshift explique comment j'ai collecté cet ensemble de données. Ils sont stockés dans AWS S3, je vais donc configurer l'interface de ligne de commande AWS à l'aide de mes clés d'accÚs et privées.

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

Je définirai la limite du nombre de demandes de clients simultanées à 100 afin que les fichiers se chargent plus rapidement qu'avec les paramÚtres standard.

 $ aws configure set \ default.s3.max_concurrent_requests \ 100 

Je vais télécharger l'ensemble de données sur les trajets en taxi depuis AWS S3 et l'enregistrer sur le lecteur NVMe sur le premier serveur. Cet ensemble de données fait ~ 104 Go au format CSV compressé GZIP.

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

Installer ClickHouse


J'installerai la distribution OpenJDK pour Java 8, car elle est nécessaire pour exécuter Apache ZooKeeper, qui est nécessaire pour l'installation distribuée de ClickHouse sur les trois machines.

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

Ensuite, j'ai défini la variable d'environnement JAVA_HOME .

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

Ensuite, j'utiliserai le systĂšme de gestion des packages dans Ubuntu pour installer ClickHouse 18.16.1, les regards et ZooKeeper sur les trois machines.

 $ 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 

Je vais créer un répertoire pour ClickHouse et également effectuer des remplacements de configuration sur les trois serveurs.

 $ 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 

Ce sont les remplacements de configuration que j'utiliserai.

 <?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> 

Ensuite, je vais exécuter ZooKeeper et le serveur ClickHouse sur les trois machines.

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

Chargement de données dans ClickHouse


Sur le premier serveur, je vais créer une table de trajets, qui stockera un ensemble de données de trajets en taxi à l'aide du moteur 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; 

Ensuite, je décompresse et charge chacun des fichiers CSV dans une table de voyages. Ce qui suit se fait en 55 minutes et 10 secondes. AprÚs cette opération, la taille du répertoire de données était de 134 Go.

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

La vitesse d'importation Ă©tait de 155 Mo de contenu CSV non compressĂ© par seconde. Je soupçonne que cela Ă©tait dĂ» Ă  un goulot d'Ă©tranglement dans la dĂ©compression GZIP. Il aurait peut-ĂȘtre Ă©tĂ© plus rapide de dĂ©compresser tous les fichiers gzip en parallĂšle Ă  l'aide de xargs, puis de charger les donnĂ©es dĂ©compressĂ©es. Ce qui suit est une description de ce qui a Ă©tĂ© signalĂ© lors du processus d'importation 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/OR/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 

Je vais libérer de l'espace sur le lecteur NVMe en supprimant les fichiers CSV source avant de continuer.

 $ sudo rm -fr /ch/csv 

Convertir en forme de colonne


Le moteur Log ClickHouse stockera les données dans un format orienté lignes. Pour demander des données plus rapidement, je les convertis au format de colonne à l'aide du moteur MergeTree.

 $ clickhouse-client --host=0.0.0.0 

Ce qui suit se fait en 34 minutes et 50 secondes. AprÚs cette opération, la taille du répertoire de données était de 237 Go.

 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; 

Voici Ă  quoi ressemblait la sortie de coup d'Ɠil pendant l'opĂ©ration:

 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/OR/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) 

Lors du dernier test, plusieurs colonnes ont été converties et recomptées. J'ai constaté que certaines de ces fonctions ne fonctionnent plus correctement dans cet ensemble de données. Pour résoudre ce problÚme, j'ai supprimé les fonctions inappropriées et téléchargé les données sans conversion vers des types plus détaillés.

Distribution des données de cluster


Je distribuerai les donnĂ©es sur les trois nƓuds du cluster. Pour commencer, je vais crĂ©er un tableau sur les trois machines.

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

Ensuite, je m'assurerai que le premier serveur peut voir les trois nƓuds du 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: 

Ensuite, je définirai une nouvelle table sur le premier serveur, qui est basée sur le trips_mergetree_third et utilise le moteur distribué.

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

Ensuite, je vais copier les données de la table basée sur MergeTree sur les trois serveurs. Ce qui suit se fait en 34 minutes et 44 secondes.

 INSERT INTO trips_mergetree_x3 SELECT * FROM trips_mergetree; 

AprÚs l'opération ci-dessus, j'ai donné à ClickHouse 15 minutes pour s'éloigner de la marque de niveau de stockage maximum. Les répertoires de données ont fini par atteindre 264 Go, 34 Go et 33 Go, respectivement, sur chacun des trois serveurs.

Évaluation des performances du cluster ClickHouse


Ce que j'ai vu ensuite Ă©tait le temps le plus rapide que j'ai vu lors de l'exĂ©cution de chaque requĂȘte plusieurs fois dans la table trips_mergetree_x3 .

 $ clickhouse-client --host=0.0.0.0 

Ce qui suit s'est terminé en 2,449 secondes.

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

Ce qui suit s'est terminé en 0,691 seconde.

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

Ce qui suit s'est terminé en 0. 582 secondes.

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

Ce qui suit est terminé en 0,983 secondes.

 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; 

À titre de comparaison, j'ai effectuĂ© les mĂȘmes requĂȘtes dans une table basĂ©e sur MergeTree, qui se trouve exclusivement sur le premier serveur.

Évaluation des performances d'un nƓud ClickHouse


Ce que j'ai vu ensuite Ă©tait le temps le plus rapide que j'ai vu lors de l'exĂ©cution de chaque requĂȘte plusieurs fois dans la table trips_mergetree_x3 .

Ce qui suit est terminé en 0,241 secondes.

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

Ce qui suit est terminé en 0,826 secondes.

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

Ce qui suit est terminé en 1,209 secondes.

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

Ce qui suit s'est terminé en 1,781 secondes.

 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; 

Réflexions sur les résultats


C'est la premiĂšre fois qu'une base de donnĂ©es basĂ©e sur un processeur gratuit a pu surpasser la base de donnĂ©es GPU dans mes tests. Cette base de donnĂ©es basĂ©e sur GPU a subi deux rĂ©visions depuis lors, mais, nĂ©anmoins, les performances que ClickHouse a montrĂ©es sur un nƓud sont trĂšs impressionnantes.

Dans le mĂȘme temps, lors de l'exĂ©cution de la requĂȘte 1 sur un moteur distribuĂ©, la surcharge est d'un ordre de grandeur supĂ©rieur. J'espĂšre que j'ai ratĂ© quelque chose dans mes recherches pour ce post, car ce serait bien de voir comment le temps de requĂȘte diminue lorsque j'ajoute plus de nƓuds au cluster. Cependant, il est remarquable que lors de l'exĂ©cution d'autres requĂȘtes, la productivitĂ© ait augmentĂ© d'environ 2 fois.

Ce serait bien si ClickHouse Ă©voluait pour qu'il soit possible de sĂ©parer le stockage et l'informatique afin qu'ils puissent Ă©voluer indĂ©pendamment. Le support HDFS, qui a Ă©tĂ© ajoutĂ© l'annĂ©e derniĂšre, pourrait ĂȘtre un pas dans cette direction. En ce qui concerne l'informatique, si une seule demande peut ĂȘtre accĂ©lĂ©rĂ©e en ajoutant plus de nƓuds au cluster, l'avenir de ce logiciel sera trĂšs prometteur.

Merci d'avoir pris le temps de lire ce post. J'offre des services de conseil, d'architecture et de développement pratique pour des clients en Amérique du Nord et en Europe. Si vous souhaitez discuter de la façon dont mes suggestions peuvent aider votre entreprise, contactez-moi via LinkedIn .

Source: https://habr.com/ru/post/fr463665/


All Articles