如何处理短期高并发写的问题,比如在一个消息刚刚发布的时候会有大量的点赞 - V2EX
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 8025 次点击
    这是一个创建于 4299 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如题所述,如果我使用的是 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
    PRO
       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     Solana     1408 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 00:00 PVG 08:00 LAX 17:00 JFK 20:00
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86