V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
macleek
V2EX  ›  Python

请教大家关于 celery 使用的一个问题

  •  
  •   macleek · 2017-01-17 14:21:30 +08:00 · 2491 次点击
    这是一个创建于 2653 天前的主题,其中的信息可能已经有所发展或是发生改变。

    年末需要在微信公众平台上搞一波活动,对于每个参加活动的微信公众号粉丝,服务器需要依次进行下面一些操作:

    • <=1 次 get 请求,获取获取个人信息
    • 一次 get 请求获取微信头像,用 pillow 处理合成一张海报图片大约 0.03s 每次
    • 1 次 post 上传这张大约 500KB 的图片到微信公众平台的临时素材(最耗时的一步)
    • 1~2 次 post 请求发送给对应的用户消息

    目前使用的软件和硬件

    • django+celery: broker 和 result backend 用的都是 redis 。我测试的时候开了 2 个 celery worker , gevent pool , concurrency 10 。
    • 阿里云配置: 2GB 内存+双核 CPU ,带宽的话可以临时提高比较大的。

    期望

    • 能应对高峰期每秒 30 人的处理

    最开始的时候跑 5 个 worker ,没几分钟服务器直接挂了,在阿里云控制台重启都花了 10 几分钟。。。后面改成 2 个 worker 在测试每秒 10 人的处理时, cpu 占用 100%,内存大约用去 1GB ,而且大约需要近 2s 才能完成,时间久了队列会一直增长,但要是加上 timelimit 的话会导致一些任务失败。

    大家有什么方案建议,能让每个参加活动的用户得到尽量短的时间反馈呢?

    13 条回复    2017-01-17 21:00:51 +08:00
    996635
        1
    996635  
       2017-01-17 16:16:25 +08:00
    只有第二部占 CPU, 粉丝一共多少人? 预先跑好
    macleek
        2
    macleek  
    OP
       2017-01-17 16:20:13 +08:00
    @996635 粉丝既包括已关注了的一部分,更主要的是之前没有关注过的人,所以没法预先跑啊。
    现在准备在阿里云上按量付费一台高配置的云服务器跑 celery 了。
    guyskk
        3
    guyskk  
       2017-01-17 16:23:41 +08:00
    合成图片比较耗 CPU ,需要优化算法或者加 CPU ,上传图片耗 IO ,加带宽或者压缩图片,另外要避免把图片读到内存里。
    996635
        4
    996635  
       2017-01-17 16:33:42 +08:00
    @macleek 你得把这个流程拆开,生成图片要 隔离, 既然已经异步了, 就彻底一些, 否则量大了 还是扛不住.
    另,我之前做过类似的业务,不过量比这个大, 最后生成了 1400W 图片, 有好几层流量过滤
    有一个不错的思路是,你试试用前端 canvas 生成图片.
    macleek
        5
    macleek  
    OP
       2017-01-17 16:56:08 +08:00
    @guyskk 我是把固定要用的海报图片存到了 redis ,避免打开本地文件耗磁盘 io ,但是不读入图片到内存要如何处理图片呢?

    @996635 可是我没有前端网页交互啊,不想用网页因为要避免一些微信规则问题
    guyskk
        6
    guyskk  
       2017-01-17 17:04:33 +08:00
    @macleek 合成之后的图数量多了会占不少内存,可以先存硬盘再 stream 方式上传
    996635
        7
    996635  
       2017-01-17 17:14:50 +08:00
    @macleek 放 redis 还不如存本地文件.至少不要新开 socket. 正确做法是存内存中...
    ryd994
        8
    ryd994  
       2017-01-17 17:38:56 +08:00 via Android
    能不能不要用 pillow 而是在前端用 css ?
    macleek
        9
    macleek  
    OP
       2017-01-17 18:03:52 +08:00
    @996635 是的, redis 存了一个全局的没有新开,读完后还要转换成 Image 对象,确实不如直接存到内存快速。

    @ryd994 因为这个过程不需要用户做任何交互啊,最后直接在微信里面发给他们生成好的图片。
    ryd994
        10
    ryd994  
       2017-01-17 18:25:25 +08:00 via Android
    光来回拷贝就开销不少
    要调优先看计时
    预先生成还是有价值的,毕竟老用户还是不少,能抠一点是一点
    这些请求统计过么,会有重复请求么,有的话优先上缓存
    ryd994
        11
    ryd994  
       2017-01-17 18:30:20 +08:00 via Android
    取决于图片格式,可以考虑利用 iterable 边上传边生成
    robinlovemaggie
        12
    robinlovemaggie  
       2017-01-17 19:58:53 +08:00 via Android
    有个疑问:用阿里主机向腾讯的服务上送东西?楼主这得是有多么博爱?
    macleek
        13
    macleek  
    OP
       2017-01-17 21:00:51 +08:00
    @ryd994 恩,明天把缓存加上试试

    @robinlovemaggie 哈哈哈
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5171 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 03:46 · PVG 11:46 · LAX 20:46 · JFK 23:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.