首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用异步和redis创建全局连接

如何使用异步和redis创建全局连接
EN

Stack Overflow用户
提问于 2017-08-10 13:59:24
回答 1查看 1.5K关注 0票数 5

我是刚接触python 3和异步的gevent和2.7 .

如何创建一个将被所有人用于reids的全局连接?例如,我将有一个进程,例如10个异步线程,但我不希望每个线程有单独的连接。例如,Why?..will有100个内核,每个核心有10个线程,并且不希望有那么多连接到redis

代码语言:javascript
复制
import asyncio
import asyncio_redis

async def worker():
    while True:
        data = await connection.brpop(['queue'], timeout=0)
        print(data)
        res = blocking_code(data)
        await connection.set('test',res)

#Process raw data here and all code is blocking
def blocking_code(data):
    results = {}
    return results

if __name__ == '__main__':
    connection = asyncio_redis.Connection.create(host='127.0.0.1', port=6379, poolsize=2)
    loop = asyncio.get_event_loop()
    tasks = [asyncio.ensure_future(worker()), asyncio.ensure_future(worker())]
    loop.run_until_complete(asyncio.gather(*tasks))
    connection.close()


    Traceback (most recent call last):
      File "/Users//worker.py", line 14, in <module>
        loop.run_until_complete(example())
      File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 466, in run_until_complete
        return future.result()
      File "/Users//worker.py", line 7, in example
        data = yield from connection.brpop(['queue'], timeout=0)
    AttributeError: 'generator' object has no attribute 'brpop'

所以在上面我有两个任务,但是我只想要一个redis连接

EN

回答 1

Stack Overflow用户

发布于 2017-08-10 14:34:01

10个异步线程

以防万一- asyncio协同器在一个线程中运行。通过在I/O操作时在协同器之间切换来实现并发性。

为什么你的代码不起作用?

asyncio_redis.Connection.create -是一个协同机制,您应该使用yield from等待此操作以获得结果:

代码语言:javascript
复制
connection = yield from asyncio_redis.Connection.create(host='127.0.0.1', port=6379)

如何创建全局连接

如果您只有一个连接,那么您可能不会从使用异步得到任何好处。并发请求可能需要可用的连接池。例如,asyncio_redis 简单的方法:

代码语言:javascript
复制
import asyncio
import asyncio_redis


@asyncio.coroutine
def main():
    connection = yield from asyncio_redis.Pool.create(host='127.0.0.1', port=6379, poolsize=10)
    try:
        # 3 requests running concurrently in single thread using connections from pool: 
        yield from asyncio.gather(
            connection.brpop(['queue:pixel'], timeout=0),
            connection.brpop(['queue:pixel'], timeout=0),
            connection.brpop(['queue:pixel'], timeout=0),
        )
    finally:
        connection.close()



if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close() 

Python 3.5+

如果您正在使用Python,请考虑使用3.5+来定义和等待协同。

Upd:

阻塞代码(例如,需要大量CPU时间的代码)不能直接在协同器中使用:它会冻结事件循环,您将得不到异步的好处。这与连接的数量无关。

您可以使用遗嘱执行人在不阻塞事件循环的情况下在单独的进程中运行此代码:

代码语言:javascript
复制
from concurrent.futures import ProcessPoolExecutor


executor = ProcessPoolExecutor(max_workers=10)  # use number of cores here


async def worker():
    while True:
        data = await connection.brpop(['queue'], timeout=0)
        print(data)

        # await blocking_code from separate process:
        loop = asyncio.get_event_loop()
        result = await loop.run_in_executor(executor, blocking_code, data)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45615883

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档