如何*正确地*从 Tornado 查询 Redis?
我很好奇 Tornado 推荐的查询 Redis(或任何数据库)的方法是什么。
我看过一些例子,例如 https://gist.github.com/357306 但它们似乎都使用阻塞调用 redis。
我的理解是,为了避免 Tornado 停止运行,我需要使用非阻塞数据库库,比如为 Twisted 开发的库。
我错了吗?这应该怎么做?
I'm curious what the recommended method of querying Redis (or any DB for that matter) is from Tornado.
I've seen some examples like https://gist.github.com/357306 but they all appear to be using blocking calls to redis.
My understanding is that to avoid grinding Tornado to a halt, I need to be using non-blocking DB libraries like the ones developed for Twisted.
Am I wrong? How is this supposed to be done?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当涉及到阻止诸如 BLPOP 之类的命令或侦听 Pub/Sub 频道时,您将需要一个异步客户端,例如 tornado-redis 。您可以从此演示开始了解如何tornado-redis 客户端可用于开发一个简单的公共聊天应用程序。
但我建议将同步 redis-py 客户端与 hiredis 对于大多数其他情况。
异步客户端的主要优点是您的服务器可以在等待 Redis 服务器响应的同时处理传入请求。然而,Redis 服务器速度如此之快,以至于在大多数情况下,在 Tornado 应用程序中设置异步回调的开销会增加请求处理的总时间,而不是等待 Redis 服务器响应所花费的时间。
使用异步客户端,您可能会尝试同时向 Redis 服务器发送多个请求,但 Redis 服务器是单线程的(就像 Tornado 服务器一样),因此它会一一响应这些请求,并且你几乎一无所获。而且,事实上,只要有像 MGET/MSET 这样的管道和命令,您就不必同时向同一个 Redis 服务器发送多个 Redis 命令。
当您使用多个 Redis 服务器实例时,异步客户端有一些优势,但我建议使用同步 (redis-py) 客户端和代理,例如 twemproxy< /a> 或 这个(后者支持管道和 MGET/MSET 命令)。
此外,我建议在 Tornado 应用程序中使用 redis-py 客户端时不要使用连接池。只需为应用程序连接到的每个 Redis 数据库创建一个
Redis
对象实例即可。When it comes to blocking commands like BLPOP or listening to a Pub/Sub channel you'll need an asynchronous client like tornado-redis. You may start with this demo to see how the tornado-redis client may be used to develope a simple public chat application.
But I would recommend using the synchronous redis-py client in conjunction with hiredis for most other cases.
The main advantage of asynchronous client is that your server can handle incoming requests while waiting for Redis server response. However, the Redis server is so fast that in most cases an overhead of setting up asynchronous callbacks in your Tornado application adds more to the total time of request processing then the time spent on waiting for Redis server response.
Using an asynchronous client you may try to send multiple requests to the Redis server at the same time, but the Redis server is a single-threaded one (just like Tornado server), so it will answer to these requests one-by-one and you'll gain almost nothing. And, in fact, you don't have to send multiple Redis commands at the same time to the same Redis server as long as there are pipelines and commands like MGET/MSET.
An asynchronous client has some advantages when you use several Redis server instances, but I suggest using a synchronous (redis-py) client and a proxy like twemproxy or this one (the latter supports pipelining and MGET/MSET commands).
Also I suggest not to use the connection pooling when using the redis-py client in Tornado applications. Just create a single
Redis
object instance for each Redis database your application connects to.我建议使用 brukva 这是一个“在 Tornado IO 循环中工作的异步 Redis 客户端”。
I would recommend to use brukva which is an "Asynchronous Redis client that works within Tornado IO loop".
一种选择是使用 Tornado 到 Twisted 的端口,然后使用 Twisted Redis API 与此相关。 Tornado 本身似乎并没有以任意异步操作为目标(尽管如果您想重建为 Twisted 构建的所有类型的东西,您可能可以从 Tornado 中的低级 iostream API,但是 我不会推荐它)。
One option is to use the port of Tornado to Twisted and then use the Twisted Redis API with that. Tornado itself doesn't seem to have arbitrary asynchronous operations as an objective (though if you wanted to rebuild all of the sorts of things that have been built for Twisted, you probably could build them from the low-level iostream APIs in Tornado, but I wouldn't recommend it).