大型互联网公司技术方案与手段浅析

发布于: 2020 年 06 月 28 日
大型互联网公司技术方案与手段浅析

一个典型的大型互联网应用系统使用了哪些技术方案和手段,主要解决什么问题?


问题思考

什么是互联网公司?

互联网公司的准确定义,是没有的(我百度、谷歌了,都是些非权威解答)。

所以我就自己定义了一个:利用互联网提供服务,达到边际效应递减,并通过线上流量获利的企业与公司。

什么是大型?

又是一个很主观的词汇,老规矩,我来定义一个:流量超过1台服务器/数据库承载能力(假设已经优化到极致)时,你就步入某个程度的“大型”领域了。

遇到的挑战有哪些?
  • 高性能

  • 数据存储与一致性

  • 服务与服务之间的关系

  • 高可用与稳定性

下面,我要把题目反转,从有什么问题需要解决来反推解决手段,就是这么任性。


高性能

高并发读

  1. 本地缓存、分布式缓存、CDN静态文件缓存 —— 本质是牺牲一定数据时效与空间换取响应时间

  2. 并发读,串行改并行;异步读,提高吞吐。

  3. Future、RxJava、Spring Flux

  4. 冗余请求(这是Google很有意思的一种处理方式)

  5. 重写轻读,提前异构为读操作友好的数据,以微博\Twitter类型的feeds为例:

  6. 提前为每个用户自备Feeds流收件箱(数据分片、分表、缓存)。

  7. 晓之以理、动之以拳,让产品接收收件箱长度限制(Twitter限制为800)。

  8. 大V只推热粉(比如在线、互动率高的粉丝)。

  9. 作为第三点的补充,推拉结合模式。

  10. 线上查询业务不允许SQL join

  11. 当需要join时,一定可以通过提前准备好宽表或搜索引擎来替代。

无论是加缓存、动静分离、重写轻读的预算,本质上都是读写分离,专业名词就是CQRS(Command Query Responsibility Separation)。

  1. 分别为读与写设计不同的适合高并发读和写的数据结构与数据模型。

  2. DB作为一般大型系统中的最脆弱点,可以通过分库分表分担写压力,通过宽表、搜索引擎、KV缓存抗并发流量穿透DB。

  3. 可以通过消息中间件异步解耦读写数据的构建过程。

  4. 我们一般都保证最终一致而非强一致,需要PK产品经理与运营。

  5. 当有数据客观上确实需要很高的实时性时,进行特殊处理,关键时刻可以单独部署、隔离。

高并发写

  1. 数据分片。

  2. 数据库的分库分表。

  3. Kafka的partition。

  4. ES的索引+数据分块。

  5. 任务分片。

  6. Map/Reduce。

  7. 1+N+M的网络模型(1个监听线程、N个I/O线程、M个Worker线程)。

  8. 消息中间件异步化,削峰填谷。

  9. 批量处理。


高可用

用户就是RMB,我们需要让系统变得更靠谱。

多副本、节点

鸡蛋不放在一个篮子里面,计算机系统要避免单点。

  1. Redis使用Master主从集群模式。

  2. MySQL多副本。

  3. 消息中间件多副本。

  4. LVS/LSB/Nginx集群做负载均衡。

  5. 服务尽量设计为stateless,快速扩容与自愈。

隔离、限流、熔断、降级

  1. 数据隔离、硬件隔离、软件资源隔离。

  2. 网关限流、业务限流、信号量限流。

  3. 失败率熔断、响应时间熔断。

  4. 做好业务上的降级策略做兜底方案。

运维与监控

  1. 监控数据采集

  2. 监控数据告警

  3. 自动扩容与容灾

  4. 灰度发布


数据存储与一致性

事务一致性

  1. 2PC

  2. 消息中间件

  3. TCC

多副本一致性

  1. Paxos\Raft\Zab

  2. CAP\BASE


服务治理

服务尽量是可配置、可观测的。

  1. 服务注册与发现

  2. 外部配置中心

  3. 断路器

  4. 分布式追踪

  5. 日志聚合检索

  6. 健康检查

  7. 应用指标

这些点,其实现在有很多微服务基底可供选择,比如JAVA语言的Spring Cloud、Doubbo, Go语言的Go Kit、Micro。

当然,有条件的话,能直接上ServiceMesh是更好的,主流的服务网格框架有:Istio、Linkerd。


总结

其实,软件架构的进化方向,是一个全方位的平衡行为,做得好不好,就在于“度”的控制。

就好像,每引入一个节点、技术或服务,对于系统整体来说都是变数,都是风险点,怎么权衡利弊收益,怎么奔跑中换轮胎,都是值得思考的。

还有架构、技术选型的过程中,切忌按惯性思维去做抉择,而要进行“数据”的考量,比如社区活跃度、真实案例、压测报告、混沌测试,才能真正的反应真实情况,举几个例子:

  1. Google的The Tail at Scale中提到的解决长尾请求的方法。

  2. 比如服务我们都追求无状态,但有没有想过,某些场景下有状态的服务可能会更好?

  3. 我们当前正在做的一个本地重量级缓存工程。

上面这几点,都是有点与我们的架构思维惯性有点违和的行为,但是很有效果:

  1. 增加2%的请求量,请求平均耗时从1700下降到80。

  2. 让我们在一些推荐、热点计算场景,时耗、时效、一致性得到了极大提升。

  3. 用启动耗时2min增加到10min,换来一台机器的QPS从1,000提升到50,000。

发布于: 2020 年 06 月 28 日 阅读数: 66
用户头像

俊俊哥

关注

还未添加个人签名 2013.06.01 加入

还未添加个人简介

评论

发布
暂无评论
大型互联网公司技术方案与手段浅析