Подтвердить что ты не робот

AWS Redshift JDBC вставляет производительность

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

Я изо всех сил пытаюсь получить что-то вроде производительности, которую некоторые другие утверждают (например, здесь).

Я запускаю кластер с 2 x dw.hs1.xlarge узлами (+ лидер), а машина, выполняющая нагрузку, является экземпляром EC2 m1.xlarge на том же VPC, что и кластер Redshift, работающий на 64-битном Ubuntu 12.04 0,1.

Я использую Java 1.7 (openjdk-7-jdk из репозиториев Ubuntu) и драйвер Postgresql 9.2-1002 (главным образом потому, что он единственный в Maven Central, который упрощает мою сборку!).

Я пробовал все методы, показанные здесь, за исключением последнего.

Я не могу использовать COPY FROM, потому что мы хотим загружать данные в "реальном времени", поэтому установка его через S3 или DynamoDB на самом деле не является вариантом, и Redshift по какой-то причине не поддерживает COPY FROM stdin.

Вот выдержка из моих журналов, показывающая, что отдельные строки вставляются со скоростью около 15 секунд:

2013-05-10 15:05:06,937 [pool-1-thread-2] INFO  uk.co...redshift.DatabaseWriter - Beginning batch of 170
2013-05-10 15:05:18,707 [pool-1-thread-2] INFO  uk.co...redshift.DatabaseWriter - Done
2013-05-10 15:05:18,708 [pool-1-thread-2] INFO  uk.co...redshift.DatabaseWriter - Beginning batch of 712
2013-05-10 15:06:03,078 [pool-1-thread-2] INFO  uk.co...redshift.DatabaseWriter - Done
2013-05-10 15:06:03,078 [pool-1-thread-2] INFO  uk.co...redshift.DatabaseWriter - Beginning batch of 167
2013-05-10 15:06:14,381 [pool-1-thread-2] INFO  uk.co...redshift.DatabaseWriter - Done

Что я делаю неправильно? Какие другие подходы я могу взять?

4b9b3361

Ответ 1

Redshift (aka ParAccel) - это аналитическая база данных. Цель состоит в том, чтобы аналитические запросы могли быстро отвечать на очень большие объемы данных. С этой целью Redshift хранит данные в столбчатом формате. Каждый столбец удерживается отдельно и сжимается от предыдущих значений в столбце. Это сжатие имеет тенденцию быть очень эффективным, поскольку данный столбец обычно содержит много повторяющихся и подобных данных.

Этот подход к хранению обеспечивает много преимуществ во время запроса, потому что нужно читать только запрашиваемые столбцы, а данные, которые нужно читать, очень сжаты. Однако стоимость этого заключается в том, что вставки, как правило, медленнее и требуют гораздо больших усилий. Кроме того, вставки, которые не идеально упорядочены, могут привести к низкой производительности запроса, пока таблицы не будут VACUUM'ed.

Итак, вставляя одну строку за раз, вы полностью работаете против того, как работает Redshift. База данных должна добавлять ваши данные в каждый столбец подряд и вычислять сжатие. Это немного (но не совсем), как добавление одного значения в большое количество zip-архивов. Кроме того, даже после того, как ваши данные вставлены, вы все равно не получите оптимальной производительности, пока не запустите VACUUM для реорганизации таблиц.

Если вы хотите проанализировать свои данные в режиме реального времени, тогда для всех практических целей вам, вероятно, следует выбрать другую базу данных и/или подход. В верхней части моей головы находятся 3:

  • Примите "маленькое" пакетное окно (5-15 минут) и планируйте запускать ВАКУУМ по крайней мере ежедневно.
  • Выберите аналитическую базу данных (больше $), которая обрабатывает небольшие вставки, например Vertica.
  • Эксперимент с базами данных "NoSQL", которые позволяют анализировать один путь, например, Acunu Cassandra.

Ответ 2

Мы смогли вставить 1000 строк/сек в Redshift, объединив несколько запросов вместе в одном и том же заявлении INSERT (в нашем случае нам пришлось выставлять ~ 200 значений кортежей в каждом INSERT). Если вы используете слой ORM, например Hibernate, его можно настроить для пакетной обработки (например, см. http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/batch.html)

Ответ 3

Мне удалось достичь 2400 вставок в секунду путем пакетной записи в транзакции по 75 000 записей за транзакцию. Каждая запись невелика, как и следовало ожидать, всего около 300 байт на запись.

Я запрашиваю MariaDB, установленный на экземпляре EC2, и вставляя записи в RedShift из того же экземпляра EC2, на который установлена ​​Мария.

UPDATE

Я изменил способ записи, так что он загружает данные из MariaDB в 5 параллельных потоках и записывает в RedShift из каждого потока. Это увеличило производительность до 12 000+ записей в секунду.

Итак, если вы правильно спланируете, вы можете получить отличную производительность при записи RedShift.