推荐学习书目
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 · Jan 17, 2017 · 3066 views
    This topic created in 3487 days ago, the information mentioned may be changed or developed.

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

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

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

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

    @robinlovemaggie 哈哈哈
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1107 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 18:15 · PVG 02:15 · LAX 11:15 · JFK 14:15
    ♥ Do have faith in what you're doing.