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
aisensiy
V2EX  ›  Python

如何处理短期高并发写的问题,比如在一个消息刚刚发布的时候会有大量的点赞

  •  
  •   aisensiy ·
    aisensiy · 2014-01-09 01:50:36 +08:00 · 7655 次点击
    这是一个创建于 4003 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如题所述,如果我使用的是 flask 这样的框架,需要如何调优这样的性能问题呢
    17 条回复    2014-07-27 14:05:49 +08:00
    helone
        1
    helone  
       2014-01-09 01:58:43 +08:00
    压力来自数据库吧?
    virushuo
        2
    virushuo  
       2014-01-09 02:46:42 +08:00 via iPad
    把热点放在内存通常都能解决,大到内存解决不了的问题考虑mapreduce方式分布。
    beordle
        3
    beordle  
       2014-01-09 02:56:00 +08:00   ❤️ 5
    这种需求本来最好在python里面完成,加上一个计数变量x,定时写入数据库。不过稍微大一些的python项目可以说是类似tornado的那样多个进程的架构了,进程间内存不能共享,所以python本身基本不能解决或者说代价比较大。必须使用memcache和redis这样的有独立进程的缓存程序。

    如果直接操作数据库,点赞300次。就要 读 锁 写 各300次。性能非常差。如果加一个redis 的话。其中有一个定时dump机制,非常适合高并发。读写都在内存中。每隔一段时间才会写入硬盘。性能高2个数量级。

    具体的实现 可以这样,写一个 给 get set都弄上一个 装饰器。连接到 redis的 incr就行了
    beordle
        4
    beordle  
       2014-01-09 02:59:19 +08:00
    说的是具体实现,可能不太详细 把 python函数装饰器实现cache python的redis库 redis的incr文档 这些关键字google一下就行了。
    chenniaoc
        5
    chenniaoc  
       2014-01-09 06:57:22 +08:00
    redis弱点是单线程,是个瓶颈.
    cloudzhou
        6
    cloudzhou  
       2014-01-09 09:51:03 +08:00
    @chenniaoc 单线程不会成为瓶颈的,这个和网络复用有关,nginx也是单进程模式,当然你可以开启多个。
    这个问题应该不难,redis生成临时计数器,按照一定时间回写到数据库。
    emohacker
        7
    emohacker  
       2014-01-09 10:04:20 +08:00
    @chenniaoc 多线程也有多线程的弊病,线程间的切换也是有开销滴,开发也没单线程来得纯粹,总之单线程也有单线程的好处,木有绝对完美滴解决方案,性能的优化都是基于实际需求遇到的困难为出发点的。
    vietor
        8
    vietor  
       2014-01-09 10:18:07 +08:00
    做一个Command队列,牺牲实时性
    akira
        9
    akira  
       2014-01-09 10:34:51 +08:00
    队列+内存数据库
    est
        10
    est  
       2014-01-09 12:28:58 +08:00
    统计多少次赞容易,但是每个人点一下一条行为记录就麻烦了。
    Livid
        11
    Livid  
    MOD
       2014-01-09 13:20:57 +08:00 via iPhone
    @est 可以用 Redis 的 SET 类型。
    aisensiy
        12
    aisensiy  
    OP
       2014-01-09 14:31:09 +08:00
    @est 这个是要记录的呀
    arzusyume
        13
    arzusyume  
       2014-01-09 19:42:27 +08:00
    前阵子在解决某站点高并发投票的问题
    程序本身是 PHP+MySQL.所有的写操作(投票/PV/验证码session)都完全交给了 memcache,
    IP日志的分析交给nginx去拦截刷票.
    大概是每2分钟用 crontab 触发一个 php 把 memcache 的内容写入 MySQL 中.(一开始想直接全部读出写入,结果抛了个事务锁错误OTL, 改成每次读写XX条)
    此外验证码也可以优化成预生成,不过考虑成本没去做

    好吧说了半天和python无关的,总之就是尽可能的减少IO次数,多用缓存,减少计算量
    aisensiy
        14
    aisensiy  
    OP
       2014-01-09 20:08:20 +08:00
    @arzusyume 谢谢你的回复,这个解决方案确实和 web 开发的语言关系不是很大。不过你说的 一开始想直接全部读出写入的事物锁错误OTL 我没懂...
    arzusyume
        15
    arzusyume  
       2014-01-10 09:27:41 +08:00
    @aisensiy 当时犯的2...直接把缓存的数据全部入库结果数据库挂了,后来改成类似队列的方式了
    aisensiy
        16
    aisensiy  
    OP
       2014-01-10 19:31:58 +08:00
    @arzusyume 你缓存的数据很多的样子
    no13bus
        17
    no13bus  
       2014-07-27 14:05:49 +08:00
    @akira celery+redis?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3097 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 13:27 · PVG 21:27 · LAX 05:27 · JFK 08:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.