请问如何构架一个高负载的系统? - 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
oldcai
0.01D
V2EX    Python

请问如何构架一个高负载的系统?

  •  
  •   oldcai
    PRO
    oldcai 2016-01-21 13:01:05 +08:00 6040 次点击
    这是一个创建于 3573 天前的主题,其中的信息可能已经有所发展或是发生改变。

    请问如何构架一个高负载的系统?

    1. 高负载的系统构架的时候主要考虑哪几个因素?
    2. 如果需要独立出功能单独做服务以降低复杂性,多系统拆分或集成一般用什么原则来划分
    3. 多个系统之间一般用什么方式和方法通信
    4. 什么时候考虑数据库分布式,它除了演进和维护变得更复杂还有没有什么弊端
    5. 目前有没有什么成熟高可用的 postgresql 分布式集群构架推荐

    我现在用的构架是 nginx+django(python)+redis+postgresql

    之前用的 rabbitmq 通信,后来为了降低系统的复杂程度,就直接用 redis 了,现在暂时还没有碰到 redis 瓶颈

    在日高峰已经遇到 8 核心单独做数据库的服务器 CPU 占用 100%的情况。
    慢查询主要在第三方的 oauth2 库和 taggit 库的查询。

    第 1 条附言    2016-01-21 17:41:03 +08:00

    有心帮忙的同学,回答请参看我列出的 5 个问题。谢谢。

    28 条回复    2016-01-22 14:43:21 +08:00
    jerkzhang
        1
    jerkzhang  
       2016-01-21 15:20:39 +08:00   1
    看需求吧,总之 python 的 web 框架别用 django ,用 tornado 或者 flask ,耦合性会低一些。
    至于消息通信,建议直接使用第三方云服务,省心。我平时的框架是 nginx+tornado ( python) + mongodb + redis/memcached 不过看需求吧,如果不会太有压力,甚至数据库都别用,直接用 yaml 作为数据存储挺好。至于慢查询那就用异步吧

    我觉得早期能通过花钱解决的问题,就通过花钱买更高的性能的机器来解决。
    jerkzhang
        2
    jerkzhang  
       2016-01-21 15:23:27 +08:00
    不好意思,没注意到你数据库 cpu 已经到 100%了,我觉得可以从哪些查询最慢,是瓶颈问题的数据库查询,然后优化那里,能用 redis 储存同样的查询结果,而避免多次查询最好。
    oldcai
        3
    oldcai  
    OP
    PRO
       2016-01-21 15:34:34 +08:00
    @jerkzhang 项目中的实现基本都用了缓存,开发的时候就对性能比较注意的。
    所以现在慢查询里面基本都是第三方的库。
    tornado 和 flask 也用来做过项目,但是总体而言,每个部件的成熟度不及 django 。

    对于耦合性,其实 django 还算好,使用 tornado 和 flask 因为都是自己挑选一些第三方库,可定制性较高,所以会有耦合性低的感觉。
    但是想升级的时候,会发现依赖项的不兼容问题。

    希望能更针对我的问题解答。谢谢。
    wph95
        4
    wph95  
       2016-01-21 15:37:49 +08:00   1
    这跟用不用 Django 没什么关系。
    ---
    既然瓶颈在数据库,那就对数据库这一块进行分析( django-debug-toolbar)
    该索引的做索引,处理掉 slow sql 。
    然后再看看哪些内容经常数据库操作的,多多移到 Redis ,减少压力。
    还不行,看看是不是读多写少,搞读写分离。
    taggit 库没用过, tag 功能都是自己实现的。
    oauth2 库可以弃用,自己照着改,把存储从 sql 换成 redis ,压力会小的。
    ---
    从 rq 换成 redis ,如果异步消息大的话,这个是隐患,但 celery 和 rq 的库 会有几率出现 内存泄露。。都是坑。。。
    noahzh
        5
    noahzh  
       2016-01-21 15:45:08 +08:00   1
    数据库的 cpu 占用 100%,如果 io 很低的话,说明数据量很少.就是没有索引,或者 sql 有大量的计算,优化一下就完了.
    如果 io 高更是索引问题.
    你的系统根本不可能是高负载,只是数据库优化没有做好.
    我建议你不要把问题想的太复杂,真正有机会遇到高负载系统的人很少.
    oldcai
        6
    oldcai  
    OP
    PRO
       2016-01-21 15:54:35 +08:00
    @wph95 感谢建议。
    确实是打算将 oauth2 重构。
    异步消息大的时候, rq 也不会太轻松,有一次几台机器开了 3 天才处理完队列,影响了很多实时性强的任务。
    @noahzh 感谢回复。
    可能关于『根本不可能』的一篇文章:
    http://mp.weixin.qq.com/s?__biz=MzA3MzI4MjgzMw==&mid=401922498&idx=1&sn=a3a504707222ae0b0c51b8762f18f862&scene=23&srcid=0119NhnwcCGR2YdkkgSxNwIn#rd
    mckelvin
        7
    mckelvin  
       2016-01-21 16:03:53 +08:00 via iPhone   1
    可以参考 https://www.nylas.com/blog/performance 加上 stack sampler 确认下 CPU 时间花在了什么地方
    oldcai
        8
    oldcai  
    OP
    PRO
       2016-01-21 16:13:20 +08:00
    @mckelvin 感谢,看起来比我用命令行调优好看的多。
    但是问题不是 python 的 CPU 消耗,而是数据库的。
    onlyshit
        9
    onlyshit  
       2016-01-21 16:27:53 +08:00   1
    数据库做分表分库
    jprovim
        10
    jprovim  
       2016-01-21 17:10:53 +08:00   1
    微信上看到的, 你可以看看这个


    [Weekly Project] 负载均衡器 (Load balancer) 原理与实现
    http://t.cn/R4R7V96

    这个周六就会讲.

    简介

    很多人都知道,负载均衡器在负载均衡设备中的作用非常地重要。那么什么是负载均衡器?为什么需要负载均衡器?如何实现负载均衡?负载均衡器的指标又是什么?关于这个话题曾经出现过哪些经典题目呢?
    本期线上实战项目通过实战练习带你一一解开这些疑惑。

    介绍负载均衡器 (Load balancer) 的功能、内部架构、以及工作原理;
    在本次的实战当中,我们将带领大家用 Python socket programming 来实现一个简易的负载均衡器,以深入了解体会负载均衡器的核心概念和工作原理。
    julyclyde
        11
    julyclyde  
       2016-01-21 17:31:50 +08:00   1
    @jprovim 这个根本不沾边
    wy315700
        12
    wy315700  
       2016-01-21 17:33:07 +08:00
    加索引 买机器
    felixzhu
        13
    felixzhu  
       2016-01-21 17:39:30 +08:00   1
    在日高峰已经遇到 8 核心单独做数据库的服务器 CPU 占用 100%的情况。
    如果主要的查询都是有索引的,那应该应该是一个不小的站了。第一优化的肯定就是慢查询,然后主要接口加缓存,这是最简单的。然后就是加从库,云服务加从库很简单,读写分离基本又能解决很多问题。

    2. 单独做服务这种事情,如果楼主是独立开发慎重。如果是团队,一般来说也就是用户、交易这样来拆分相互之间尽量单独人维护这样。
    3. 通信一般是找一个开源的 RPC 框架, thrift 、 protobuf 之类的。当然了 http 也是可以的。。
    4. 如果系统确实很大了迟早是要做分库分表的。早做规划,分布式事务之类的坑也是很多的,很多之前直接用索引的地方要注意拆表之后怎么冗余存储之类的。分表一定要多分,拆分成 1000 张表之类的,以后再做拓展就没什么问题,
    5. postgreSQL 不熟,但是阿里云是有分布式数据库服务的
    oldcai
        14
    oldcai  
    OP
    PRO
       2016-01-21 17:45:52 +08:00
    @felixzhu 目前就是主从,仅少量使用到了分库分表,因为确实碰到了分布式事务的坑。
    谢谢,您的答案是最切题的。
    如果可以容我点 1024 个赞。
    oldcai
        15
    oldcai  
    OP
    PRO
       2016-01-21 17:46:59 +08:00
    @felixzhu 另外,阿里云的分布式数据库只有 mysql 的, postgresql 的是提供数据库服务,而非分布式的。
    再次感谢。
    felixzhu
        16
    felixzhu  
       2016-01-21 17:55:59 +08:00   1
    @oldcai 额那其实好像也没帮上什么忙。

    这样我没注意。。因为我一直都是工作在 MySQL 上。。其实人少的话你用数据库中间件要是出问题了更麻烦。。不如直接在应用端处理这个事情,这样最简单也在自己的掌握中。
    latyas
        17
    latyas  
       2016-01-21 18:07:08 +08:00
    @jerkzhang 在用 tornado 的第三方库一堆坑之后,我回到了 django 的怀抱。
    yueyoum
        18
    yueyoum  
       2016-01-21 18:36:34 +08:00
    @jerkzhang
    > 看需求吧,总之 python 的 web 框架别用 django ,用 tornado 或者 flask ,耦合性会低一些。

    不懂装懂,一派胡言!
    ethego
        19
    ethego  
       2016-01-21 18:38:55 +08:00
    多级缓存, django 的 memcached 缓存可以直接缓存查询结果
    Andy1999
        20
    Andy1999  
       2016-01-21 18:43:53 +08:00 via iPhone
    试试看用内存缓存数据
    如果有条件使用 Nginx 分流 多台对应多后端处理
    wph95
        21
    wph95  
       2016-01-21 20:19:04 +08:00   1
    @oldcai
    我感觉还是数据库没优化好的原因
    最快捷的办法还是去找个 DBA 把,做做分析,要分库的分库,要优化的优化,要分离的分离。
    & Rabbitmq 的性能是靠谱的,百万级别的没问题的。 我说的大小是指每个消息的大小,数据大小超过了 4K , Redis 会慢的一塌糊涂。。。这是个坑点。

    // 我只用过 青云的 postgresql , 简单的读写分离。 供参考。
    strwei
        22
    strwei  
       2016-01-21 20:59:30 +08:00
    用了 redis 为何还要 pgsql
    bobuick
        23
    bobuick  
       2016-01-21 21:19:36 +08:00
    @strwei redis 和 pg 不是一回事吧, 也不冲突。
    稍微有点事务需求的数据, 用 redis 行不通。
    bobuick
        24
    bobuick  
       2016-01-21 21:24:07 +08:00   1
    ”什么时候考虑数据库分布式?“
    这个, 大概是等到你数据事务写很多,然后需要库分表,分库到一定阶段, 且在应用层这样分,已经很明显出现维护成本过高, 而且很多数据读写之间还有比较强的一致性要求(这导致不能从库来读),写入数据并发量较大, 从库的同步已经有过大的延迟, 且这个延迟已经超出业务容忍度。
    就需要分布式了, 比较常见的做法是自己有一个数据中间件, 按业务或其他逻辑,分布到不同的数据节点去, Uber 就有类似案例, 可以学习一下。
    bobuick
        25
    bobuick  
       2016-01-21 21:30:32 +08:00   1
    “多个系统之间用什么通信”
    通常比较简单的做法就是 http 协议了, 写起来快, 且有成熟的负载均衡方法。微服务之间很多时候一开始都这样干
    然后就是 RPC 了, 没有大规模 rpc 应用过, 只说自己的感觉应该是两个服务之间频率很高,接口之间有比较明显的逻辑调用式的场景,另外可能一些有状态的逻辑, 用 rpc 可以明显提升效率, 因为 http 协议太重了, rpc 的二进制流又非常高效,不过多节点的负载问题比 http 麻烦点吧。
    laotaitai
        26
    laotaitai  
       2016-01-21 22:47:05 +08:00
    请教如何写好代码, 谢谢!
    stevenkang
        27
    stevenkang  
       2016-01-22 14:42:01 +08:00
    在日高峰已经遇到 8 核心单独做数据库的服务器 CPU 占用 100%的情况。
    stevenkang
        28
    stevenkang  
       2016-01-22 14:43:21 +08:00   1
    @stevenkang 不小心点了回车,如果日高峰数据库服务器负载很高的话,可以使用消息队列进行异步处理一些数据,达到削峰填谷的效果。这样整个系统就比较稳定,也会因为某个时间段导致系统出现性能瓶颈了。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3578 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 04:17 PVG 12:17 LAX 20:17 JFK 23:17
    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