Thursday, December 10, 2015

九个月实现破亿用户的可扩展架构



http://www.infoq.com/cn/presentations/9-months-achieve-large-number-users-scalable-architecture
http://segmentfault.com/a/1190000002924334
在不同阶段选择最适合自己的方案
首先先从架构上来说,看下美拍经历的几个阶段:
  1. 极简化设计(快速发布上线)
  2. 保持简单行设计(产品快速迭代)
  3. 可扩展和高可用保证(用户量到一定量级)
  4. 高可扩展和高可用保证
然后我们来看下美拍一路走来遇到的问题:
  1. MySQL慢查询
  2. MySQL写入瓶颈
  3. redis超时
  4. memcached命中率奇低
  5. 服务相互依赖
  6. 监控报警不稳定
  7. CDN服务各种故障
  8. 添加字段成本高
  9. 量级上来后,MySQL继续慢
然后,我们按服务维度把每一个服务拆开,看下每一个服务在美拍架构上的迭代过程。

一、MySQL

MySQL是最重要的一个服务,在美拍架构里经历了多次迭代。在第一版直接就是一个实例,为了保持代码的简单,业务逻辑能在数据库里做的都放到数据库做了,比如Feed功能,直接用MySQL的join查询。
但是后来就出现了一些慢查询的情况,这时候做了主从,做读写分离,多个从库用来做查询。再到后来出现写入也慢的情况,这时候也没有做架构上的优化,而是升级硬件,因为现在正是业务高速发展阶段,需要极简化设计,这个阶段更多精力要放在业务开发上(估计当时也木有招到合适的人:))。
过了一段时间又开始出现写入慢的情况,这时候才开始做分表。但是等到了重心放在扩展性和可用性上时,又遇到了新的问题,一个很大的问题还是写入慢,另外一个就是随着数据量的增大,添加字段成本特别的高。针对这两个问题做了下面两个方案:
  1. 异步写入,做到前端永远可写,后面复杂的事情放到队列里面去异步的做
  2. 索引和数据分离,把需要索引的字段单独拆出来一个表,其他数据用kv存储,value就是所有属性和值的pb二进制数据,解决家字段困难的问题
这个时候针对MySQL的架构优化才告了一段落 :)

二、缓存

缓存主要用到了memcache和redis(redis应该主要是用在队列和计数服务)。在量比较小的时候就是简单粗暴的用,但是很快就遇到了redis超时的问题,这时候对redis扩容,使用多slave架构。然后是rdb dump时影响用户请求的问题,解决方法一是在凌晨访问量低的时候才去dump,二是用不对外服务的机器来做dump。
然后memcached遇到了命中率很低的问题,一个大问题就是容量瓶颈,这没啥好说的,扩容(小军有提到,要随时做好扩容的准备)。另外一个就是slab calcification的问题(又叫slab钙化问题,这个是memcached的内存分配机制导致的,简单来说就是memcached会内存分成N个slab,当新添加一个内存对象时会根据这个对象的大小来选择不同的slab,如果没有合适的就会创建一个slab,那如果这时候剩余内存不足以分配一个slab呢?这时候就出现了钙化问题了),美拍当时的解决办法是核心业务隔离部署,避开这个问题。
到可用性保证阶段,缓存的可用性就更加的非常的重要了,缓存挂了可能就整个系统都挂了,很难收场,所以就要保证缓存的可用性。这时候做了主从的优化,master也承担读查询,以保证缓存热度,slave穿透到master,master穿透到slave,防止单点故障。

三、运维

在初期只是简单的监控告警,有时候出问题了可能收不到告警或者看不到是啥地方出问题,后来逐渐完善监控告警,且监控告警是用配置比较高的服务器,保证监控告警的可用性。然后假如更多监控维度和更多日志,方便定位问题。对依赖的第三方服务和资源做开关,出问题时可以通过服务的开关保证核心路径可用

四、第三方服务

主要提到的是CDN服务。其中一个很大的问题就是DNS被攻击、被劫持,除了和运营商保持沟通外,还做了多服务商配合的策略,比如同样的数据在多个云服务那里做冗余,客户端在访问时如果出现问题就切换到其他的访问地址,并且在客户端做了服务端可用性探测。这也是个非常有价值的经验。

五、技术栈

整个看下来会发现美拍的架构做的非常的稳,小军也有提到,在项目初期高速发展阶段做架构时要克服对完美架构的欲望、克服对新技术的欲望,先让系统跑起来。
但是在整个迭代过程中,美拍也一直在引入新技术,比如在团队不太熟悉时先在部分业务上使用MongoDB,在注重可扩展和可用性阶段,引入java做业务逻辑,引入c做底层基础服务。

http://segmentfault.com/a/1190000000383231

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts