Phantom vs Quill для Playframework (Scala) и Cassandra

В настоящее время я рассматриваю возможность использования Cassandra в качестве моей базы данных в проекте PlayFramework. Я искал реактивный драйвер, и, кажется, мой выбор ограничен Phantom и Quill. Мой опыт работы с базами данных nosql ограничен MongoDB, и я раньше не работал ни с Quill, ни с Phantom.

Глядя на сравнение, кажется, что в конечном итоге можно написать больше кода в Фантоме. Более того, использование DSL для описания моделей кажется нелогичным (исходя из тяжелого фона спящего режима / JPA), но это может быть только я.

Мне было интересно, может ли кто-нибудь дать практические советы/примеры использования, в которых один будет превосходить другой, и на что следует обратить внимание в каждом из них?


person MojoJojo    schedule 21.06.2016    source источник


Ответы (2)


С несколько предвзятой точки зрения, как автора фантома, я очень хорошо понимаю цели дизайна в фантоме. Существует существующее сравнение между Quill и Phantom, доступное на веб-сайте библиотеки Quill, которое, естественно, смещено в другую сторону.

Phantom стремится быть идеальным выбором для уровня приложения, тогда как Quill стремится быть самым причудливым генератором строк, что не очень полезно для сравнения, когда вы создаете большие приложения поверх Cassandra.

Плюсы использования фантома

  • Что касается безопасности типов и того, насколько хорошо DSL модернизирован для функций Cassandra, на самом деле нет никаких сомнений. DSL обладает очень "глубоким" знанием ваших структур данных и обеспечивает полную поддержку функций Cassandra. Во время компиляции он знает, что возможно в отношении Cassandra, а что нет.

  • Разработчики Quill утверждают, что у фантома гораздо больше зависимостей, но это не совсем точно, поскольку большинство из них являются необязательными, включая такие вещи, как итерации Play и поддержка потоков. То, чего вы не хотите, вы не получите, вот и все.

  • Сравнение Quill просто гласит: «Вы можете расширить Phantom, расширив DSL, чтобы добавить новые функции, хотя это может быть непростым процессом», что немного неточно. Будучи очень новым игроком в игре, Quill — это игрушка, когда дело доходит до поддержки функций Cassandra, и вы часто будете нуждаться в добавлении функций. У Phantom, без сомнения, есть свои пробелы, но это гораздо более зрелая альтернатива, и количество раз, когда требуется расширение, значительно реже.

  • Мы исправили большинство ошибок в течение нескольких дней или недель для более сложных функций, но, как правило, все, что вам может понадобиться, уже есть, а ряд функций, которых в настоящее время нет в Quill, даже на то, чтобы записать их, у меня ушли бы часы.

  • Я не очень хорошо разбираюсь в JPA, но сопоставление между Cassandra и phantom является чрезвычайно мощным уровнем, поскольку оно позволяет автоматически генерировать всю схему таблиц непосредственно из DSL сопоставления. Это также позволяет DSL полностью имитировать поведение Cassandra во время компиляции, он будет знать, какие запросы возможны в отношении вашего выбора первичного ключа и так далее, quill вообще не поддерживает такую ​​поддержку.

  • Phantom имеет очень мощные уровни абстракции на уровне приложений, такие как коннекторы, базы данных, автоматическое создание баз данных, вещи, которые помогают запускать приложения в продакшене.

  • Код, лежащий в основе Quill, намного сложнее, и хотя я был бы первым, кто воздал должное инженерным возможностям, стоящим за ним, когда я думаю, что с удобством для пользователя история не так хороша.

  • Квилл пытается сделать гораздо больше за один раз. Это мини-движок для генерации, что-то, что scalaquery пытались сделать несколько лет назад, прежде чем они решили полностью сосредоточиться на базах данных SQL и отказались от поддержки чего-либо еще. Это предшественник современного Slick, в котором используется аналогичный подход с кавычками QDSL.

  • Quill — это текущая абстракция. Поскольку они нацелены на поддержку более широкого спектра баз данных, они значительно хуже поддерживают особенности специфики БД. Пример ниже:

Из самых простых примеров в сравнении вы читаете:

val getAllByCountry = quote {
  (country: String) => query[WeatherStation]
     .filter(_.country == country)
  }
}

Пока все отлично, предположительно менее многословно, чем фантомный эквивалент, если мы включим необходимый код отображения.

select.where(_.country eqs country).fetch()

Но давайте рассмотрим это дальше. Что, если вы пытаетесь получить одну такую ​​страну? Или что, если вы пытаетесь получить PagingState информацию? Или добавьте существующий PagingState, чтобы отобразить вещи через пользовательский интерфейс.

Именно здесь Quill, по крайней мере, в сравнении, не может дать пользователю реальный предварительный просмотр того, каким в конечном итоге будет его опыт. Естественно предположить, что всякий раз, когда вы переходите на страницу инструмента, он описывает себя как лучший инструмент в своей категории, как, конечно же, мы, создатели фантома, но это еще не все.

Чтобы быть более кратким, еще несколько интересных вещей:

select.where(_.country eqs country).fetchRecord()
select.where(_.country eqs country).one()

Как насчет частичного выбора?

select(_.country, _.city).where(_.country eqs country)

Phantom семантически различает все, что возможно во время выполнения с помощью Cassandra, и прежде всего пытается предотвратить ошибки во время выполнения, используя хитрость во время компиляции и знание предметной области. Как вы можете получить эквивалент Quill?

Кроме того, Quill прекрасно способен генерировать запросы непосредственно из файла case class.

  case class WeatherStation(
    country: String,
    city: String,
    stationId: String,
    entry: Int,
    value: Int
  )

  object WeatherStation {

    val getAllByCountry = quote {
      (country: String) =>
        query[WeatherStation].filter(_.country == country)
    }

    val getAllByCountryAndCity = quote {
      (country: String, city: String) =>
        getAllByCountry(country).filter(_.city == city)
    }

    val getAllByCountryCityAndId = quote {
      (country: String, city: String, stationId: String) =>
        getAllByCountryAndCity(country, city).filter(_.stationId == stationId)
    }
  }

Но ему не хватает каких-либо знаний о вашей схеме. Что делать, если страна не является частью первичной? Этот запрос недействителен, фантом не позволит вам его скомпилировать, и это только самый простой пример.

Phantom может автоматически генерировать ваш CQL непосредственно из таблицы, он может генерировать целые базы данных на лету, профессиональная версия может даже автоматически переносить таблицы и помогать вам справляться с несоответствиями схемы, а также предоставляет вам очень продвинутый пользовательский интерфейс и интерфейс мониторинга, где вы можете может обновлять и понижать схемы на лету.

Минусы

  • Phantom действительно сделал расширение таких вещей, как TypeCodec, немного менее подробным, но начиная с phantom 2.9.0 мы представили чрезвычайно мощный механизм макросов для кодирования типов в Cassandra, который вообще не зависит от TypeCodec!

  • Phantom требует минимального шаблона для определения DSL таблицы и по своей природе не очень хорошо работает с общими столбцами таблицы. Это можно сделать, но это не самый красивый код и не самый плохой.

В целом

  • Quill — очень хорошая программа, написанная очень талантливыми ребятами, в этом нет никаких сомнений.
  • It's better than phantom strictly at query generation, there's boilerplate that can be reduced through QDSLs that cannot be reduced through an EDSL, if we are fighting who's the leanest meanest string generator Quill wins.
    • It's a vastly inferior tool at the application layer, and it's even more unnatural for most people. Slick popularised the concepts to some extent, but some of the most basic functionalities you would want as part of your application lifecycle are not as easily addressable through a QDSL or at least it has yet to happen.
    • Phantom гораздо более зрелый и широко распространенный, с большим количеством ресурсов и вкладом команды основателей, долгосрочной дорожной картой и ключевым партнерством с Datastax, которое помогает нам оставаться в курсе всех функций.
person flavian    schedule 21.06.2016
comment
Ух ты. Отличный ответ. Спасибо, что нашли время написать и так подробно описать. Очень признателен. Не могли бы вы также указать мне на документацию по использованию Phatom с PlayFramework? - person MojoJojo; 22.06.2016
comment
Последний вопрос. Поддерживает ли фантом определяемые пользователем типы и составные ключи разделов? Или я должен использовать JSONColumn для пользовательских типов? Как насчет составных ключей разделов? Как определить ключ раздела, который использует поле пользовательского типа? - person MojoJojo; 25.06.2016
comment
Хорошо, я разобрался с проблемой составного первичного ключа. Все еще ищет проблему пользовательского типа с JSONColumn.. - person MojoJojo; 25.06.2016
comment
Я настоятельно рекомендую использовать Phantom. - person Rhys Bradbury; 27.09.2016

Мы начали с Quill, а затем перешли на Phantom из-за особенностей Phantom и простоты изменения. Однако мы столкнулись с серьезными проблемами при нагрузочном тестировании и обнаружили, что он не освобождает потоки ЦП и сетевые подключения. Мы тестировали на моей локальной машине Mac, а также на AWS EC2-Cluster серверов AMI Linux. По сути, ресурсы не освобождались, и возникало исключение нехватки памяти. Если бы эта проблема была исправлена, Phantom был бы великолепен. В нынешнем виде я не могу рекомендовать использование Phantom всем, у кого есть производственная система, требующая высокой производительности.

В самую последнюю минуту перед производством нам пришлось изменить весь наш код и вернуться к Quill, что было для меня мучением.

Я открыл проблему с Phantom и надеюсь, что они смогут решить эту проблему как можно скорее. Прилагается проект, в котором проверяется нагрузка между Quill и Phantom путем одновременного запуска простого проекта JSON/REST scala во время игры.

https://github.com/yleun/cassandra-loadtest

Если Phantom сможет исправить это исключение нехватки памяти, он, вероятно, будет лучшим клиентом БД по сравнению с Quill, но в его нынешнем виде он не готов к работе, и я надеюсь, что другие не столкнутся с моими проблемами, потратив много времени здание с Фантомом.

person YP Leung    schedule 10.06.2017
comment
Для всех, кто читает это, нагрузочный тест основан на схеме, которая содержит недопустимый запрос Cassandra, который приводит к сбою тестов, нет никаких следов того, чтобы какие-либо потоки не были выпущены. В нагрузочном тесте нет OOM, и мы работали над созданием PR, чтобы исправить нагрузочный тест, чтобы дать реальное представление, где и фантом, и перо имеют 100% -ную скорость отклика. - person flavian; 18.06.2017