在芹菜工人中存储数据的常见且明显的方法是什么?

时间:2012-08-09 04:22:52

标签: python sqlalchemy celery

我使用Celery来运行抓取一些数据的网络蜘蛛,然后我需要将这些数据保存在数据库的某个地方(例如SQLite),但据我所知,我无法在Celery工作者之间共享SQLAlchemy会话。你怎么解决这个问题?哪种方式很常见?

目前我正在尝试将Redis用作数据的中间存储。

@celery.task
def run_spider(spider, task):
    # setup worker
    logger = logging.getLogger('Spider: %s' % spider.url)
    spider.meta.update({'logger': logger, 'task_id': int(task.id)})

    # push task data inside worker
    spider.meta.update({'task_request': run_spider.request})

    spider.run()

    task.state = "inactive"
    task.resolved = datetime.datetime.now()
    db.session.add(task)
    db.session.commit()

编辑:其实我错了,我不需要分享会话,我需要为每个芹菜流程/任务创建新的数据库连接。

2 个答案:

答案 0 :(得分:4)

我也使用redis在大型芹菜应用程序中持久化。

我的任务通常看起来像这样:

@task
def MyTask(sink, *args, **kwargs):
    data_store = sharded_redis.ShardedRedis(sink)
    key_helper = helpers.KeyHelper()
    my_dictionary = do_work()
    data_store.hmset(key_helper.key_for_my_hash(), my_dictionary)
  • sharded_redis只是通过客户端处理分片密钥的几个redis分片的抽象。
  • sink(host, port)元组的列表,用于在确定分片后进行适当的连接。

基本上,您正在使用每个任务(非常便宜)连接和断开redis,而不是创建连接池。

使用连接池可以工作,但是你真的会使用celery(运行很多并发任务)然后你会更好(在我看来)使用这种方法,因为你冒着耗尽连接的风险池,特别是如果你在redis中做任何需要更长时间的事情(比如将大数据集读入内存)。

与redis的连接非常便宜,所以这应该可以很好地扩展。我们在几个实例上每分钟处理几十万个任务。

答案 1 :(得分:0)

其实我错了,我不需要分享会话,我需要为每个芹菜流程/任务创建新的数据库连接