Тест на 1,7 млрд поездок на такси в Нью-Йорке: Clickhouse vs Elasticsearch vs Manticore Search


Введение

NYC Taxi rides — это, вероятно, наиболее часто используемый бенчмарк в области аналитики данных.

Все началось с того, что в 2015 году Тодд В. Шнайдер решил первым подготовить коллекцию для анализа 1,1 миллиарда поездок на такси NYC и Uber. Затем Марк Литвинчик продолжил, протестировав множество баз данных и поисковых систем с использованием этой коллекции данных.

Теперь мы на https://db-benchmarks.com/:

  • докеризировали подготовку коллекции данных, чтобы упростить ее использование
  • сделали его доступным как часть самого прозрачного и открытого набора бенчмарков баз данных.

Коллекция данных

Коллекция данных включает в себя 1,7 млрд. поездок на такси и попутных машинах (Uber, Lyft и т.д.), совершенных в Нью-Йорке с 2009 года. Большая часть исходных данных поступает из NYC Taxi & Limousine Commission.

Запись сбора данных включает множество различных атрибутов поездки на такси:

  • дата и время посадки
  • координаты места посадки и высадки
  • названия пунктов приема и сдачи
  • размер оплаты и чаевых
  • скорость ветра, высота снежного покрова
  • и многие другие поля

Он может быть использован в основном для тестирования аналитических запросов, но также включает пару полнотекстовых полей, которые можно использовать для тестирования возможностей баз данных по работе со свободным текстом.

Весь список полей и их типов данных:

       "properties": {
         "vendor_id": {"type": "keyword"},
         "pickup_datetime": {"type": "date", "format": "epoch_second"},
         "dropoff_datetime": {"type": "date", "format": "epoch_second"},
         "store_and_fwd_flag": {"type": "keyword"},
         "rate_code_id": {"type": "integer"},
         "pickup_longitude": {"type": "float"},
         "pickup_latitude": {"type": "float"},
         "dropoff_longitude": {"type": "float"},
         "dropoff_latitude": {"type": "float"},
         "passenger_count": {"type": "integer"},
         "trip_distance": {"type": "float"},
         "fare_amount": {"type": "float"},
         "extra": {"type": "float"},
         "mta_tax": {"type": "float"},
         "tip_amount": {"type": "float"},
         "tolls_amount": {"type": "float"},
         "ehail_fee": {"type": "float"},
         "improvement_surcharge": {"type": "float"},
         "total_amount": {"type": "float"},
         "payment_type": {"type": "keyword"},
         "trip_type": {"type": "byte"},
         "pickup": {"type": "keyword"},
         "dropoff": {"type": "keyword"},
         "cab_type": {"type": "keyword"},
         "rain": {"type": "float"},
         "snow_depth": {"type": "float"},
         "snowfall": {"type": "float"},
         "max_temp": {"type": "byte"},
         "min_temp": {"type": "byte"},
         "wind": {"type": "float"},
         "pickup_nyct2010_gid": {"type": "integer"},
         "pickup_ctlabel": {"type": "keyword"},
         "pickup_borocode": {"type": "byte"},
         "pickup_boroname": {"type": "keyword"},
         "pickup_ct2010": {"type": "keyword"},
         "pickup_boroct2010": {"type": "keyword"},
         "pickup_cdeligibil": {"type": "keyword"},
         "pickup_ntacode": {"type": "keyword"},
         "pickup_ntaname": {"type": "text", "fields": {"raw": {"type":"keyword"}}},
         "pickup_puma": {"type": "keyword"},
         "dropoff_nyct2010_gid": {"type": "integer"},
         "dropoff_ctlabel": {"type": "keyword"},
         "dropoff_borocode": {"type": "byte"},
         "dropoff_boroname": {"type": "keyword"},
         "dropoff_ct2010": {"type": "keyword"},
         "dropoff_boroct2010": {"type": "keyword"},
         "dropoff_cdeligibil": {"type": "keyword"},
         "dropoff_ntacode": {"type": "keyword"},
         "dropoff_ntaname": {"type": "text", "fields": {"raw": {"type":"keyword"}}},
         "dropoff_puma": {"type": "keyword"}
       }
Войти в полноэкранный режим Выйти из полноэкранного режима

Базы данных

На данный момент мы сделали этот тест доступным для 3 баз данных:

  • Clickhouse — мощная OLAP база данных,
  • Elasticsearch — «поисково-аналитический движок» общего назначения,
  • Manticore Search — «база данных для поиска», альтернатива Elasticsearch.

В этом тесте мы вносим как можно меньше изменений в настройки баз данных по умолчанию, чтобы не дать ни одной из них несправедливого преимущества. Тестирование при максимальной настройке не менее важно, но это тема для другого бенчмарка. Здесь мы хотим понять, какую задержку может получить обычный неопытный пользователь после простой установки базы данных и запуска ее с настройками по умолчанию. Но чтобы сравнение было честным, нам все же пришлось изменить несколько настроек:

  • Clickhouse: никаких настроек, просто CREATE TABLE ... ENGINE = MergeTree() ORDER BY id и стандартный докер-образ clickhouse-server.
  • Elasticsearch: здесь, чтобы сравнение с другими базами данных было справедливым, нам пришлось помочь Elasticsearch следующим образом:

-позволить ему сделать 32 шарда: ("number_of_shards": 32), иначе он не смог бы использовать процессор, который имеет 32 ядра на сервере, поскольку, как сказано в официальном руководстве Elasticsearch, «каждый шард выполняет поиск на одном потоке процессора».

  • образ docker является стандартным
    • Manticore Search также используется в виде их собственного образа docker + предоставляемая ими библиотека columnar:
  • как и в Elasticsearch, мы также используем 32 шарда в виде 32 простых индексов
  • и мы используем колоночное хранилище Manticore, поскольку сравнение стандартного хранилища Manticore, построчного по умолчанию, с колоночными хранилищами Clickhouse и Elasticsearch было бы нечестным для такой большой коллекции данных.

О кэшах

Мы также настроили базы данных так, чтобы они не использовали никаких внутренних кэшей. Почему это важно:

  1. В этом бенчмарке мы проводим точное измерение задержки, чтобы узнать, какое время отклика может ожидать пользователь, если он запустит один из тестируемых запросов в случайный момент, а не после многократного выполнения одного и того же запроса.
  2. Любой кэш — это короткий путь к низкой задержке. Как написано в Википедии, «кэш хранит данные, чтобы будущие запросы на эти данные обслуживались быстрее». Но кэши бывают разные, их можно разделить на 2 основные группы:

    • 👌 те, которые просто кэшируют необработанные данные, хранящиеся на диске. Например, многие базы данных используют mmap() для отображения данных, хранящихся на диске, в память, легкого доступа к ним и предоставления операционной системе заботиться об остальном (чтение с диска, когда есть свободная память, удаление из памяти, когда она нужна для чего-то более важного и т.д.). Это нормально с точки зрения тестирования производительности, потому что мы позволяем каждой базе данных использовать преимущества использования страничного кэша ОС (или ее внутреннего аналогичного кэша, который просто считывает данные с диска) Именно это мы и делаем в этом бенчмарке.
    • ❗ те, которые используются для сохранения результатов предыдущих вычислений. И это хорошо во многих случаях, но с точки зрения этого бенчмарка позволить базе данных включить такой кэш — плохая идея, потому что:
      • это нарушает правильное измерение: вместо измерения времени вычисления вы начинаете измерять, сколько времени требуется, чтобы найти значение по ключу в памяти. Это не то, что мы хотим сделать в данном тесте (но это интересно в целом, и мы, возможно, сделаем это в будущем и опубликуем статью «Бенчмарк кэшей»).
      • Даже если они сохраняют не полный результат конкретного запроса, а результаты его подвычислений, это нехорошо, потому что нарушает идею теста — «какое время отклика может ожидать пользователь, если он запустит один из тестируемых запросов в случайный момент времени».
      • некоторые базы данных имеют такой кэш (обычно он называется «кэш запросов»), другие нет, поэтому если мы не отключим внутренний кэш базы данных, мы дадим несправедливое преимущество тем, у кого он есть.

    Поэтому мы делаем все, чтобы убедиться, что ни одна из баз данных не делает такого кэширования.

Что именно мы делаем для достижения этой цели:

  • Clickhouse:

  • Elasticsearch:

  • Manticore Search (в конфигурационном файле):

    • qcache_max_bytes = 0
    • docstore_cache_size = 0
  • Операционная система:

  • мы делаем echo 3 > /proc/sys/vm/drop_caches; sync перед каждым НОВЫМ запросом (НЕ перед каждой попыткой). Т.е. для каждого нового запроса мы:

    • останавливаем базу данных
    • сбрасываем кэш ОС
    • запускаем её снова
    • делаем самый первый холодный запрос и измеряем его время
    • и делаем еще десятки попыток (до 100 или пока коэффициент вариации не станет достаточно низким, чтобы считать результаты тестирования качественными).

Запросы

Запросы в основном аналитические, выполняющие фильтрацию, сортировку и группировку. Мы также включили один полнотекстовый запрос:

[
"SELECT count(*) FROM taxi where pickup_ntaname = '0'",
"SELECT pickup_ntaname, count(*) c FROM taxi GROUP BY pickup_ntaname ORDER BY c desc limit 20",
"SELECT cab_type, count(*) c FROM taxi GROUP BY cab_type order by c desc LIMIT 20",
"SELECT passenger_count, avg(total_amount) a FROM taxi GROUP BY passenger_count order by a desc LIMIT 20",
"SELECT count(*) FROM taxi WHERE tip_amount > 1.5",
"SELECT avg(tip_amount) FROM taxi WHERE tip_amount > 1.5 AND tip_amount < 5",
"SELECT rain, avg(trip_distance) a FROM taxi GROUP BY rain order by a desc LIMIT 20",
{
  "manticoresearch": "SELECT * FROM taxi where match('harlem east') LIMIT 20",
  "clickhouse": "SELECT * FROM taxi where match(dropoff_ntaname, '(?i)\WHarlem\WEast\W') or match(pickup_ntaname, '(?i)\WHarlem\WEast\W') LIMIT 20",
  "elasticsearch": "SELECT * FROM taxi where query('harlem east') LIMIT 20"
},
"SELECT avg(total_amount) FROM taxi WHERE trip_distance = 5",
"SELECT avg(total_amount), count(*) FROM taxi WHERE trip_distance > 0 AND trip_distance < 5",
"SELECT count(*) FROM taxi where pickup_ntaname != '0'",
"select passenger_count, count(*) c from taxi group by passenger_count order by c desc limit 20",
"select rain, count(*) c from taxi group by rain order by c desc limit 20",
"SELECT count(*) from taxi where pickup_ntaname='Upper West Side'",
"SELECT * from taxi limit 5",
"SELECT count(*) FROM taxi WHERE tip_amount = 5",
"SELECT avg(total_amount) FROM taxi"
]
Войти в полноэкранный режим Выйти из полноэкранного режима

Результаты

Вы можете найти все результаты на странице результатов, выбрав «Тест: такси».

Помните, что единственной метрикой высокого качества является «Fast avg», поскольку она гарантирует низкий коэффициент вариации и высокое количество запросов, проведенных по каждому запросу. Две другие («Fastest» и «Slowest») не дают никаких гарантий, поскольку:

  • Slowest — это результат одной попытки, в большинстве случаев самый первый холодный запрос. Несмотря на то, что мы очищаем кэш ОС перед каждым холодным запросом, его нельзя считать стабильным. Поэтому его можно использовать только в информационных целях (несмотря на то, что многие авторы бенчмарков публикуют такие результаты без каких-либо оговорок).

  • Fastest — только самый быстрый результат, в большинстве случаев он должен быть похож на метрику «Fast avg», но может быть более изменчив от прогона к прогону.
    Помните, что тесты, включая результаты, на 100% прозрачны, как и все в этом проекте, поэтому:

  • вы можете использовать структуру тестов, чтобы узнать, как они были сделаны

  • и найти необработанные результаты тестов в каталоге результатов.

В отличие от других менее прозрачных и менее объективных бенчмарков, мы не делаем никаких выводов, мы просто оставляем здесь скриншоты результатов:

3 конкурента одновременно

Clickhouse vs Elasticsearch

Manticore Search vs Elasticsearch

Manticore Search vs Clickhouse

Отказ от ответственности

Автор данного теста и тестовой схемы является членом основной команды Manticore Search, и тест изначально был сделан для сравнения Manticore Search с Elasticsearch, но, как показано выше и можно убедиться в открытом исходном коде и при самостоятельном выполнении того же теста, Manticore Search не получил никакого несправедливого преимущества, поэтому тест можно считать непредвзятым. Тем не менее, если в тесте что-то упущено или неправильно (т.е. не объективно), не стесняйтесь сделать запрос на исправление или проблему на Github. Ваше мнение будет оценено по достоинству! Спасибо, что потратили свое время на прочтение этой статьи!

Оцените статью
Procodings.ru
Добавить комментарий