jdbc - HikariCP: низкая производительность при вставке, в то время как% процессора DB / App все еще низок - PullRequest
0 голосов
/ 20 сентября 2019

Я установил doobie + hikaricp с настройками, аналогичными настройкам по умолчанию.С помощью журнала отладки я вижу, сколько соединений активно / неактивно, и это также отражает то, что pg_stat_activity возвращает с этим запросом

SELECT
  pid,
  query,
  query_start,
  state
FROM pg_stat_activity;

HikariPool-1 - Pool stats (total=10, active=4, idle=6, waiting=0)

Мое приложение в основном обрабатывает сообщения из потока, сохраняя их в БД с помощью транзакциикоторый состоит из 3-х вставок и 2-х выборок перед фиксацией.

Ниже описывается, как транзакция создается с помощью hikariCP:

val hikariConfig = new HikariConfig()
hikariConfig.setJdbcUrl(dbUrl)
hikariConfig.setDriverClassName("org.postgresql.Driver")
hikariConfig.setUsername(dbUser)
hikariConfig.setPassword(dbPassword)
hikariConfig.setMaximumPoolSize(10)
hikariConfig.setAutoCommit(false)
hikariConfig.addDataSourceProperty("socketTimeout", "30")

val dataSource: HikariDataSource     = new HikariDataSource(hikariConfig)
val transactor: HikariTransactor[IO] = HikariTransactor[IO](dataSource)

, а затем этот транзактор передается повсеместно для обработки транзакций базы данных:

import doobie._
import doobie.implicits._
import doobie.postgres.implicits._

val query = for {
  _ <- sql"insert into foo (id, value) values (fooId, 'b')".update.run
  _ <- sql"insert into bar (id, value) values (barId, 'b')".update.run
  _ <- sql"select * from bar where id = $barId".query[Bar].unique
  _ <- sql"insert into bazz (id, value1, value2) values (bazzId, fooId, barId)".update.run
  _ <- sql"select * from bazz where id = $barId".query[Bazz].unique
} yield ()

query.transact(transactor).unsafeToFuture()

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

Некоторые моменты, которые я заметил:

  1. Проверка pg_stat_activity,Я вижу много запросов COMMIT (больше, чем вставки), где каждый занимает от ~ 90 мс до 200 мс.

    SELECT pid, now () - pg_stat_activity.query_start AS длительность, запрос, query_start, состояние FROM pg_stat_activity, где состояние <> «бездействующий» порядок по длительности desc;

  2. Вышеупомянутый запрос pg_stat_activity возвращает только 4-8 строк за раз, большинство результатов - запрос = 'COMMIT'.

  3. Начиная с пустого потока, пропускная способность может достигать30 тыс. Сообщений в минуту.Однако через 15-20 минут пропускная способность падает до 3 тыс. Сообщений в минуту и ​​не сбрасывается при восстановлении до тех пор, пока поток не станет пустым в течение многих часов, где перезапуск приложения или масштабирование большего числа экземпляров приложения не улучшают пропускную способность.

Низкий уровень использования процессора и базы данных (10%) / памяти (16%) базы данных и приложения, поэтому теоретически пропускная способность должна быть намного выше, что стоит исследовать в некоторых областях.?

в настоящее время использует doobie 0.5.4, hikariCP 0.5.4

ОБНОВЛЕНИЕ: Увеличены настройки commit_delay и commit_siblings в базе данных rds по предложению Лоренца, что продлило период высокой пропускной способности с30 минут -> 60 минут до продолжительного снижения пропускной способности, как и ранее.Я начал тестировать повышение max_wal_size, но, похоже, это приводит к скачкообразной пропускной способности (иногда очень низкой), не близкой к исходной скорости запуска.

1 Ответ

3 голосов
/ 20 сентября 2019

Если COMMIT занимает много времени, это явный признак того, что ваша система ввода / вывода перегружена.

Если проблема не в томе ввода / вывода, это, вероятно, синхронизация многих WALзапросы от множества транзакций.

Некоторые параметры:

  • Выполните работу с меньшим количеством более крупных транзакций.

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

  • Если потерять совершенные транзакции невозможно, настройте commit_delay и commit_siblings.Это сделает транзакции немного дольше, но может уменьшить нагрузку ввода-вывода.

...