Wrap Slick запросы в фьючерсах
Я пытаюсь запросить базу данных MySQL асинхронно, используя Slick. Следующий шаблон кода, который я использую для запроса примерно 90 тыс. Строк в понимании, кажется, работает изначально, но программа потребляет несколько гигабайт оперативной памяти и выходит из строя без предупреждения после примерно 200 запросов.
import scala.slick.jdbc.{StaticQuery => Q}
def doQuery(): Future[List[String]] = future {
val q = "select name from person"
db withSession {
Q.query[String](q).list
}
}
Я попытался настроить соединения как с помощью метода fromURL
, так и с помощью пула соединений c3p0. Мой вопрос: это способ сделать асинхронные вызовы в базу данных?
Ответы
Ответ 1
Async по-прежнему является открытой проблемой для Slick.
Вы можете попробовать использовать Iterables и данные потока вместо хранения в памяти с помощью решения, аналогичного этому: Обработка SQL ResultSet, как поток Scala
p > Хотя, пожалуйста, опустите вызов .toStream в конце. Он будет кэшировать данные в памяти, в то время как Iterable не будет.
Если вы хотите асинхронную версию итерации, вы можете посмотреть Observables.
Ответ 2
Оказывается, что это не проблема (на самом деле ошибка в моем коде, которая открыла новое соединение с базой данных для каждого запроса). По моему опыту, вы можете обернуть запросы БД в Futures, как показано выше, и скомпилировать их позже Scala Async или Rx, как показано здесь. Все, что требуется для хорошей производительности, - это большой пул потоков (x2 CPU в моем случае) и одинаково большой пул соединений.
Ответ 3
Slick 3 (Reactive Slick) выглядит так, как будто он может решить эту проблему.