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

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

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

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

    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
       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
       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
       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
       2016-01-21 17:45:52 +08:00
    @felixzhu 目前就是主从,仅少量使用到了分库分表,因为确实碰到了分布式事务的坑。
    谢谢,您的答案是最切题的。
    如果可以容我点 1024 个赞。
    oldcai
        15
    oldcai  
    OP
       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   ·   实用小工具   ·   1125 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 18:39 · PVG 02:39 · LAX 10:39 · JFK 13:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.