我正在尝试弄清楚如何在使用actor系统时最好地处理数据库操作。事实上,当我们尝试不阻止AKKA时,数据库操作正在阻塞。
我在主文档中用红色表示,处理这种方法的一种方法是在路由器后面创建一个actor池,可能在一个单独的executionContext上,它将处理数据库访问。
因此我有以下问题:
1 - databaseActors是否始终保持连接打开状态?
2 - 它如何与许多数据库提供的连接池一起工作?
3 - 我们应该将两者结合起来,并让DatabaseActors在每次请求时都从池中请求一个新的连接。如果没有,是不是一直保持连接打开是一件坏事?
4 - 有人可以向我解释微妙的事情,使其成为一种避免线程饥饿的方法。例如,使用Play或spray,请求的处理是异步任务,但是如果该任务需要数据库访问并且我们向DatabaseActor发送请求,那么数据库Actor上的块(如果它发生)不会导致,异步任务中的一个块,导致可能的线程不足?
5 - 是否100%确定DB ACID属性确保多次读写的安全性,因此在关系之前就会发生。
6 - 我正在使用也称为三重存储的语义数据库,并在我的请求中大量使用语义推理功能。我还执行了大量的写访问,任何建议,关于池和actor编号的调整参数或专用执行上下文?
最佳,
中号
答案 0 :(得分:21)
1 - databaseActors是否始终保持连接打开?
Akka演员有状态即,您可以安全地在演员内部存储状态(在这种情况下为DB连接)。您可以编写自己的连接管理逻辑,也可以使用数据库驱动程序提供的逻辑。
2 - 它如何与许多数据库提供的连接池一起工作?
3 - 我们应该将两者结合起来,并让DatabaseActors在每次请求时都从池中请求一个新的连接。如果没有,是不是一直保持连接打开是一件坏事?
你可以将两者结合起来。为池中的每个连接都有一个actor。为什么你认为拥有一个连接是一件坏事?连接池的重点不在于重用资源(连接)而不是每次都要付出创建/销毁它们的代价。
4 - 有人可以向我解释微妙的事情,使其成为一种避免线程饥饿的方法。例如,使用Play或spray,请求的处理是异步任务,但是如果该任务需要数据库访问并且我们向DatabaseActor发送请求,那么数据库Actor上的块(如果它发生)不会导致,异步任务中的一个块,导致可能的线程不足?
如果您的数据库驱动程序阻塞,那么最终也必须阻止。建议的做法是在单独的执行上下文/线程池中执行此阻塞代码段。或者,如果您可以选择具有反应式数据库驱动程序的数据存储区(例如,针对MongoDB的ReactiveMongo),该数据存储区完全是异步和非阻塞的。
5 - 是否100%确定DB ACID属性确保多次读写的安全性,因此在关系之前就会发生。
我不明白你的意思。
6 - 我使用的语义数据库也称为三重存储,并在我的请求中大量使用语义推理功能。我还执行了大量的写访问,任何建议,关于池和actor编号的调整参数或专用执行上下文?
您绝对应该使用不同的执行上下文。参数的转换实际上取决于您的硬件配置和软件的其他细节(数据库类型,远程数据库与嵌入式数据库,请求/秒等)。
对于Akka调度员来说,我认为没有一个适合所有人。它更像是一门艺术。我唯一的建议是确保您阻止 代码中的任何地方阻止。
答案 1 :(得分:1)
This blog post有一些非常好的观点,为什么不使用每个数据库连接的Actor。
特别是,它意味着您需要管理并发级别,而不是让本机连接池为您处理它。 它也可能误导您认为您的代码并行运行,而实际上您的代码是串行运行的。