Ce jeu de données peut être obtenu de deux façons:
- importation à partir de données brutes
- téléchargement de partitions
## Comment importer les données brutes {#how-to-import-the-raw-data}
Tu vois https://github.com/toddwschneider/nyc-taxi-data et http://tech.marksblogg.com/billion-nyc-taxi-rides-redshift.html pour la description d'un ensemble de données et les instructions de téléchargement.
Le téléchargement entraînera environ 227 Go de données non compressées dans des fichiers CSV. Le téléchargement prend environ une heure sur une connexion 1 Gbit (téléchargement parallèle depuis s3.amazonaws.com récupère au moins la moitié d'un canal 1 Gbit).
Certains fichiers peuvent ne pas télécharger entièrement. Vérifiez la taille des fichiers et re-télécharger tout ce qui semble douteux.
Certains fichiers peuvent contenir des lignes invalides. Vous pouvez les corriger comme suit:
``` bash
sed -E '/(.*,){18,}/d' data/yellow_tripdata_2010-02.csv > data/yellow_tripdata_2010-02.csv_
sed -E '/(.*,){18,}/d' data/yellow_tripdata_2010-03.csv > data/yellow_tripdata_2010-03.csv_
Ensuite, les données doivent être pré-traitées dans PostgreSQL. Cela créera des sélections de points dans les polygones (pour faire correspondre les points sur la carte avec les arrondissements de New York) et combinera toutes les données en une seule table plate dénormalisée à l'aide d'une jointure. Pour ce faire, vous devrez installer PostgreSQL avec le support PostGIS.
Soyez prudent lors de l'exécution `initialize_database.sh` et vérifiez à nouveau manuellement que toutes les tables ont été créées correctement.
Il faut environ 20-30 minutes pour traiter la valeur de chaque mois de données dans PostgreSQL, pour un total d'environ 48 heures.
Vous pouvez vérifier le nombre de téléchargé lignes comme suit:
``` bash
$ time psql nyc-taxi-data -c "SELECT count(*) FROM trips;"
## Count
1298979494
(1 row)
real 7m9.164s
```
(C'est un peu plus de 1,1 milliard de lignes rapportées par Mark Litwintschik dans une série de billets de blog.)
Les données de PostgreSQL utilisent 370 GO d'espace.
LEFT JOIN central_park_weather_observations_raw weather
ON weather.date = trips.pickup_datetime::date
LEFT JOIN nyct2010 pick_up
ON pick_up.gid = trips.pickup_nyct2010_gid
LEFT JOIN nyct2010 drop_off
ON drop_off.gid = trips.dropoff_nyct2010_gid
) TO '/opt/milovidov/nyc-taxi-data/trips.tsv';
```
L'instantané de données est créé à une vitesse d'environ 50 Mo par seconde. Lors de la création de l'instantané, PostgreSQL lit à partir du disque à une vitesse d'environ 28 Mo par seconde.
Cela prend environ 5 heures. Le fichier TSV résultant est 590612904969 octets.
Créer une table temporaire dans ClickHouse:
``` sql
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(UInt8),
snow_depth Nullable(UInt8),
snowfall Nullable(UInt8),
max_temperature Nullable(UInt8),
min_temperature Nullable(UInt8),
average_wind_speed Nullable(UInt8),
pickup_nyct2010_gid Nullable(UInt8),
pickup_ctlabel Nullable(String),
pickup_borocode Nullable(UInt8),
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;
```
Il est nécessaire pour convertir les champs en types de données plus corrects et, si possible, pour éliminer les valeurs Null.
``` bash
$ time clickhouse-client --query="INSERT INTO trips FORMAT TabSeparated" <trips.tsv
real 75m56.214s
```
Les données sont lues à une vitesse de 112-140 Mo/seconde.
Le chargement de données dans une table de type de journal dans un flux a pris 76 minutes.
Les données de ce tableau utilisent 142 GO.
(L'importation de données directement depuis Postgres est également possible en utilisant `COPY ... TO PROGRAM`.)
Unfortunately, all the fields associated with the weather (precipitation…average\_wind\_speed) were filled with NULL. Because of this, we will remove them from the final data set.
Pour commencer, nous allons créer une table sur un serveur unique. Plus tard, nous ferons le tableau distribué.
toUInt16(ifNull(dropoff_puma, '0')) AS dropoff_puma
FROM trips
```
Cela prend 3030 secondes à une vitesse d'environ 428 000 lignes par seconde.
Pour le charger plus rapidement, vous pouvez créer la table avec le `Log` le moteur de `MergeTree`. Dans ce cas, le téléchargement fonctionne plus rapidement que 200 secondes.
La table utilise 126 GO d'espace disque.
``` sql
SELECT formatReadableSize(sum(bytes)) FROM system.parts WHERE table = 'trips_mergetree' AND active
```
``` text
┌─formatReadableSize(sum(bytes))─┐
│ 126.18 GiB │
└────────────────────────────────┘
```
Entre autres choses, vous pouvez exécuter la requête OPTIMIZE sur MergeTree. Mais ce n'est pas nécessaire puisque tout ira bien sans elle.
## Téléchargement des Partitions préparées {#download-of-prepared-partitions}
$ tar xvf trips_mergetree.tar -C /var/lib/clickhouse # path to ClickHouse data directory
$ # check permissions of unpacked data, fix if required
$ sudo service clickhouse-server restart
$ clickhouse-client --query "select count(*) from datasets.trips_mergetree"
```
!!! info "Info"
Si vous exécutez les requêtes décrites ci-dessous, vous devez utiliser le nom complet de la table, `datasets.trips_mergetree`.
## Résultats sur un seul serveur {#results-on-single-server}
Q1:
``` sql
SELECT cab_type, count(*) FROM trips_mergetree GROUP BY cab_type
```
0.490 secondes.
Q2:
``` sql
SELECT passenger_count, avg(total_amount) FROM trips_mergetree GROUP BY passenger_count
```
1.224 secondes.
Q3:
``` sql
SELECT passenger_count, toYear(pickup_date) AS year, count(*) FROM trips_mergetree GROUP BY passenger_count, year
```
2.104 secondes.
Q4:
``` sql
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
```
3.593 secondes.
Le serveur suivant a été utilisé:
Deux Intel (R) Xeon (R) CPU E5-2650 v2 @ 2.60 GHz, 16 noyaux physiques total, 128 GiB RAM, 8x6 TB HD sur le matériel RAID-5
Temps d'exécution est le meilleur des trois pistes. Mais à partir de la deuxième exécution, les requêtes lisent les données du cache du système de fichiers. Aucune autre mise en cache ne se produit: les données sont lues et traitées à chaque exécution.
INSERT INTO trips_mergetree_x3 SELECT * FROM trips_mergetree
```
Cela prend 2454 secondes.
Sur les trois serveurs:
Q1: 0.212 secondes.
Q2: 0.438 secondes.
Q3: 0.733 secondes.
Q4: 1.241 secondes.
Pas de surprise ici, depuis les requêtes sont réparties linéairement.
Nous avons également les résultats d'un cluster de 140 serveurs:
Q1: 0,028 sec.
Q2: 0,043 sec.
Q3: 0,051 sec.
Q4: 0,072 sec.
Dans ce cas, le temps de traitement des requêtes est déterminé surtout par la latence du réseau.
Nous avons exécuté des requêtes en utilisant un client situé dans un centre de données Yandex en Finlande sur un cluster en Russie, ce qui a ajouté environ 20 ms de latence.