使用 postgresql gem 异步
我正在使用 Goliath (由 eventmachine 提供支持)和 postgres gem pg
,目前我正在以阻塞方式使用 pg gem:conn.exec('SELECT * FROM products')
(例如),我想知道是否有更好的连接到 postgres 的方法 数据库?
I'm using Goliath (which is powered by eventmachine) and the postgres gem pg
, currently I'm using the pg gem in a blocking way: conn.exec('SELECT * FROM products')
(for example) and I'm wondering whether there is a better way to connect to a postgres database?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
pg
库为 PostgreSQL 的异步 API 提供全面支持。我添加了如何使用它的示例到samples/
目录:我建议您阅读 PQconnectStart 函数和
我以前没有使用过 EventMachine,但如果它允许您注册一个套接字并在其变得可读/可写时进行回调,我认为将数据库调用集成到其中会相当容易。
我一直想使用 中的想法Ilya Grigorik 的文章介绍了使用 Fibers 清理事件代码,使异步 API 更易于使用,但这还有很长的路要走。我确实有未结票< /a> 如果您有兴趣/有动力自己做的话,请跟踪它。
The
pg
library provides full support for PostgreSQL's asynchronous API. I've added an example of how to use it to thesamples/
directory:I'd recommend that you read the documentation on the PQconnectStart function and the Asynchronous Command Processing section of the PostgreSQL manual, and then compare that with the sample above.
I haven't used EventMachine before, but if it lets you register a socket and callbacks for when it becomes readable/writable, I'd think it'd be fairly easy to integrate database calls into it.
I've been meaning to use the ideas in Ilya Grigorik's article on using Fibers to clean up evented code to make the async API easier to use, but that's a ways off. I do have a ticket open to track it if you're interested/motivated to do it yourself.
是的,您可以从 goliath 以非阻塞方式访问 postgres。我有同样的需求,并将这个概念证明放在一起: https://github.com/levicook /goliath-postgres-spike
Yes, you can access postgres in a non-blocking fashion from goliath. I had the same need, and put together this proof of concept: https://github.com/levicook/goliath-postgres-spike
我(不再)非常熟悉 Pg,但我还没有听说任何流行的数据库可以异步连接。因此,您仍然需要在查询期间保持与数据库的连接。因此,您仍然需要阻止堆栈中的某些位置。
根据您的应用程序,您可能已经以最佳方式进行了。
但是,当您正在处理某种轮询应用程序(同一客户端在短时间内发送大量请求)并且更重要的是获取响应,即使它是空的,那么您可以编写一个 ruby Fiber 或完整的线程或进程,其寿命较长,代理对数据库的查询并缓存结果。
例如:请求来自客户端 A。Goliath 应用程序使用一些唯一 ID 处理对数据库进程的查询,并使用“尚无数据”响应查询。 DB进程完成查询并将结果与ID一起保存到缓存中。当下一个请求来自同一客户端时,Goliath 发现它已经有等待的查询结果,从缓存中删除结果并响应客户端。同时,它会与数据库进程安排下一个查询,以便更快准备好。如果下一个请求在上一个请求完成之前到达,则不会安排新的查询(不会增加查询)。
这样,您的响应就可以快速且无阻塞,同时仍然可以尽快提供来自数据库的新数据。当然,它们可能与实际数据有点不同步,但同样,根据应用程序,这可能不是问题。
I'm not (anymore) very familiar with Pg, but I haven't heard that any popular database could to async connections. So you still need to maintain a connection to the database for the duration of the query. Therefore you still need to block some where down the stack.
Depending on your application, you might already be doing it the best possible way.
But when you are dealing with some kind of polling app (where same client sends multitude of requests in short time) and it is more important to get the response out, even if it is empty, then you could write a ruby
Fiber
or flull blown thread or process that is long lived and proxies queries to the DB and caches the results.For example: a request comes in from client A. Goliath app handles the query to the DB process with some unique ID and responds to the query with 'no data yet'. The DB process finishes the query and saves results to a cache with the ID. When next request comes in from the same client, Goliath sees that it already has query results waiting, removes the results from the cache and responds to client. At the same time it schedules next query with the DB process so that it would be ready sooner. If the next request comes in before last one is finished, no new query is scheduled (not multiplying the queries).
This way your responses are fast and non-blocking, while still serving fresh data from DB ASAP. Of course they could be a bit out of sync with actual data, but again, depending on the application, this might not be a problem.
这个想法是结合使用数据库(Postgresql)的异步适配器和事件Web服务器(Goliath)来获得性能。 Mike Perham 去年为 Rails 2.3 编写了一个 PG activerecord 适配器。也许你可以用它。
另一个例子是,Ilya Grigorik 发布了异步 Rails 堆栈的此演示。在本例中,事件服务器是 Thin,数据库是 Mysql。安装演示并在使用或不使用 EM 感知驱动程序的情况下尝试基准测试。差异是巨大的。
The idea is to use an async adaptor to the database(Postgresql) in conjunction with an evented web server(Goliath) to gain performance. Mike Perham wrote a PG activerecord adaptor for Rails 2.3 last year. Maybe you can use that.
As another example, Ilya Grigorik released this demo of an async Rails stack. In this case the evented server is Thin, and the database is Mysql. Install the demo and try the benchmark with and without the EM aware driver. The difference is dramatic.