线上高并发应用重构(写)填坑经验分享(一)

今年在公司重构(写)了一个老项目,踩了无数的坑。

中间好几次遇到问题,甚至感觉项目可能要失败了,好在最后终于成功上线了。

虽然被坑的不要不要的,但也从中领悟到了不少东西,在这里记录一下,顺便分享给大家乐呵乐呵。

先简单介绍下项目,一个面向C端用户的服务,主要提供包括动态、评论、圈子、好友、关注、Feed等常见的社区功能,另外还有其他一些个性化的功能。

日活比较高,整个服务QPS上万。高频业务,单个接口QPS上千。单项业务数据量过亿,比如评论。

图1.接口qps监控图

在上述高并发、海量数据的情况下,整个系统设计时需要注意的坑,和我总结的一些经验:

数据库层面

MySQL分库分表

因为是重写整个项目,包括重新设计底层数据库,必然要考虑到分库分表。

最初在网上参考了一些分库分表的原则,实际操作中,发现大部分资料都有些缥缈。

如果是简单的应用怎么分表,甚至不分都可以。所以这些原则你也不能说它是错的,但在你最需要参考的时候,这些原则往往不够深入。

分享下我个人总结的一些经验:

先说分库, 分库的主要目标,应该是缓解主库(Master)的压力。

绝大部分服务都是读多写少,在读写分离,1主1备N从的情况下,即便为了保证一致性,部分读请求路由到主库,主库压力依旧很低。

通过监控服务的写请求量和数据库服务器的CPU压力等性能指标,只要主库压力不大,就没必要分库。读库如果压力大,直接加从库实例即可。

一种极端的情况,就是分表数量过多了,一个库里表数量递增,成万上亿了,那还是分库的好。

还有一点,从运维的角度考虑,单库冷备,数据不应该超过500GB。如果单库数据量达到1个TB,运维也不好备份,为了正常备份也要分库。

图2.数据库监控图(图中蓝色线条代表主库,基本上是趴着不动躺平的)

再说分表, 在请求量不大 或 数据量不大的情况下,分不分表都无所谓。

考虑mysql的性能、树的深度等,可以简单的认为单表500W左右即可。

但实际中往往需要结合具体的业务设计和查询场景。

比如,1张几千万数据量的订单表,如果业务上,只需要根据主键或唯一索引,每次查询一条记录,那么不分表也是完全可行的。

但有时出于运维需要,分表会更方便一些,比如研发人员可能会想手写一些SQL上去进行一些范围查询,为排查问题提供一些方便。(这里说的方便是指相对单表几千万,如果查询字段没有索引,范围查询基本不可用。当然从操作步骤上看,肯定比查1个表繁琐了)

特别需要注意的是,如果一项业务数据需要高频的用到 count语句查询总数 或 order by进行排序,我建议分的表越多越好,管他3721先分1000张表再说。

多分表的好处就是,只要表中的数据量足够少,即便你索引设计的不好,甚至查询完全不走索引,也不容易产生慢查询。哈哈哈!

小结:这次重构就被老系统的1000张表给坑了,因为每张表只有几万条数据,我觉得太浪费了, 想当然的缩到了20张表。

但又没有很好的去分析查询场景,设计索引。导致上线时,只放了1%的量,就崩了,看监控全部都是慢查询。

当然,最终我是通过优化索引来解决慢查询,而不是加分表数量。但在有些情况下,这也是一种思路。

MySQL索引、字段设计

之前自己设计表,总喜欢加些固定字段,比如create_time, create_user, is_delete等,因为运维方便。

重构了这个系统之后发现,在高并发海量数据的情况下,性能是首要问题,有时候多加这些字段反而成了负担。(当然,大部分情况下,create_time还是必要的)

字段能少则少,名字能短则短,类型能用tinyint就不要用int。

索引这块查询低频少量数据无所谓,高频海量数据务必所有查询走索引。
再看一些实际例子,
1. is_delete 字段(逻辑删除)
假设以评论为例,单表500w,单条动态下平均上万条评论。
业务场景中要查询动态下的所有评论,where 子句要加上条件 is_delete = 0。
如果查询出符合条件的结果集,有几万甚至十几万条,不把 is_delete 字段加到联合索引中,这必将是一条慢查询,再加上高并发,只要几百的qps,很容易把服务打崩。
每个查询加上这么一个条件又有点画蛇添足,除非运维需要,基本上不会有业务要查询 is_delete = 1的情况。
索性直接物理删除,再加个归档表,要找回时,去归档表里找。
这样就不用在每个联合索引里多加一个字段了。
2. tinyint 和 int
tinyint 主要用于一些状态标志位,比如 审核状态:0-未审核 1-审核通过 2-审核未通过。
使用tinyint 一是节约空间,二是方便识别,一看就知道是标志位。
另外这种标志位经常出现在查询条件中,但又不会单独作为查询条件,因此建立索引时,必然是在联合索引中出现。
而联合索引是有长度限制的,虽然大部分时候都不会遇到,但还是值得注意。
有的人标志位喜欢用byte,但在代码里要转型就很蛋疼了。
3.联合索引的设计
就一个原则:查询条件里有的,都加进去。
除了要把 where 子句中的条件字段加进去外,在有order by 的情况下,还要把 order by 的字段加到最后。
比如:查询动态id是123,状态是审核通过且上线的20条评论,按时间倒序排列。
select * from comment where news_id = 123 and audit_status = 1 and online_status = 1 order by ctime desc limit 20
那我们应该建立联合索引 (news_id, audit_status, online_status, ctime)
注意:在网上参考资料时,很多都说索引的建立原则,字段的区分度要高。
个人感觉这个原则并没什么道理,至少在建立联合索引时不适用。
在建立单一索引时,也没有想到适用的具体场景。
比如有单表5千万条身份信息,其中20条gender=1,5千万条gender=0。
如果你就是要查询gender=1的列表,如果不在gender列建立索引,即便只有20条数据,也必然是个慢查询。 小结:索引的建立,必须针对具体的查询语句。结合实际查询场景,去考虑如何创建索引。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,928评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,192评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,468评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,186评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,295评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,374评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,403评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,186评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,610评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,906评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,075评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,755评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,393评论 3 320
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,079评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,313评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,934评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,963评论 2 351

推荐阅读更多精彩内容