架构篇之阿里十亿并发项目

目录

(1)高并发系统通用解决方案:

(2)架构分层

(3)系统设计目标一:怎样做到高性能

(4)系统设计目标二:怎样做到高可用

(5)系统设计目标三:怎样做到易于扩展

(7)池化技术

(8)数据库优化方案(一)读写分离

(9)数据库优化方案(二)分库分表

(10)分布式ID唯一性

(11)NoSQL与数据库互补

(12)缓存



(1)高并发系统通用解决方案:

1.横向扩展:分而治之,分布式部署分散流量
    方案:数据库一主多从,分库分表,存储分片
2.缓存
3.异步

摩尔定律:Intel创始人之一戈登·摩尔1965年提出,定律提到集成电路上可容纳的晶体管的数量约每两年增加一倍,后来大卫·豪斯提出18个月,目前已经做到了10nm级别

(2)架构分层

优点:
分层的设计可以简化系统设计,让不同的人专注做某一层次的事情,分层后可以做到很高的复用
分层架构可以让我们更容易做横向扩展:比如某个业务逻辑里面包含复杂计算,导致CPU成为性能瓶颈。可以抽离逻辑层单独部署,针对性扩展,相比整体扩展代价小的多
缺点:
增加了代码的复杂度,某一层单独抽离会增加链路长度以及耗时
总结:作决策的时候不可以以偏概全,因噎废食
扩展:我们熟知的一些设计原则都在分层架构中有所体现。比方说,单一职责原则规定每个类只有单一的功能,在这里可以引申为每一层拥有单一职责,且层与层之间边界清晰;迪米特法则原意是一个对象应当对其它对象有尽可能少的了解,在分层架构的体现是数据的交互不能跨层,只能在相邻层之间进行;而开闭原则要求软件对扩展开放,对修改关闭。它的含义其实就是将抽象层和实现层分离,抽象层是对 实现层共有特征的归纳总结,不可以修改,但是具体的实现是可以无限扩展,随意替换的。

(3)系统设计目标一:怎样做到高性能

性能优化原则:
1.首先性能优化不能盲从,一定是问题导向
2.其实是遵循二八原则,用20%的精力解决80%的性能问题。抓住主要矛盾点,优先优化性能瓶颈
3.再次要有数据支撑,时刻了解你的优化让响应时间较少了多少,提升了多少吞吐量
4.性能优化是持续的,复杂系统中性能问题可能会多方面,持续寻找定位解决
性能优化思路:
1.提高系统的处理核心数
也就是增加系统的并行处理能力
缺点:似乎是找到了解决问题的银弹,然而锁着并发进程的增加,并发任务对系统的资源抢占也更严重,甚至到了某个拐点后性能会下降
2.减少单次任务的响应时间
首先要了解系统是CPU密集型还是IO密集型
01.CPU密集型:选择更高效的算法或者减少运算次数,可以通过一些Profile工具找到消耗CPU时间最多的方法或者模块
02.IO密集型:指大部分操作在等待IO完成(磁盘IO/网络IO)。可以采用工具或者通过监控找到性能瓶颈,不同的瓶颈有不同的解决方案。如果是数据库要看看是不是有锁表的情况/全表扫描/索引加的是否合适,join操作等。如果是网络问题要看看网络参数是否有优化空间,抓包来看是否有大量超时重传,网卡是否有大量丢包

(4)系统设计目标二:怎样做到高可用

通常来讲一个高并发大流量的系统,出现故障比性能低更加损伤用户体验
Availability = MTBF /(MTBF平均故障时间间隔 + MTTR故障平均恢复时间)
99.99% = 1年故障52分钟
99.999% = 1年故障5分钟
一个成熟系统的可用性需要从【系统设计】和【系统运维】两方面保障,缺一不可
1.【系统设计】集群中成百上千的机器出现单点异常的概率很高,需要学会failover故障转移,超时控制,限流降级熔断
01.failover的节点可能有两种情况
对等节点:所有机器都承担读写流量且不保存状态,每个节点都是另一个节点的镜像(问题时:nginx发现超时转发请求即可)
不对等节点:热备节点(同样在线提供服务),冷节点(只是备份使用)
代码如何发现机器故障,通过心跳机制,如果是主节点出问题,需要使用分布式一致性算法Paxos,Raft来选主
02.设置超时
03.降级:为了保证核心服务而牺牲非核心服务的做法
04.限流:通过对并发请求进行限速来保护系统
2.【系统运维】
灰度发布+故障演练

(5)系统设计目标三:怎样做到易于扩展

从架构设计上来说,高可扩展性是一个设计指标,表示可以通过增加机器的方式来现行的提高系统的处理能力
1.为什么提升扩展性会很复杂?因为增加机器后数据库,网络宽带都可能变成瓶颈。无状态的服务和组件易于扩展,mysql存储服务是有状态的,在集群中添加/减少机器会涉及到大量数据的迁移。所以说应该站在架构的角度而不仅仅是业务服务器的角度考虑可扩展性,数据库 缓存 依赖第三方 负载均衡 交换机宽带等等都是系统扩展需要考虑的因素
2.设计思路
01.拆分:复杂问题简单化
存储层的扩展性:一个服务的各个模块的数据量是不一样的,访问频率也不一样
业务层的扩展性:三个维度考虑 如下所示
001.业务维度 把相同业务的服务拆成单独的业务池
002.重要性维度 划分为核心池和非核心池,流量上升优先保障核心池性能,降级部分非核心池的接口,从而保障整体稳定性
003.请求来源维度 服务于客户端接口 服务于小程序 服务于H5等

(7)池化技术

例子:tcpdump发现每次执行sql前需要三次握手+验证密码,数据库建立连接占总耗时的4/5
线程池执行:任务提交-->线程数是否超过coreThreadCount(没有就创建线程)-->任务队列是否满了(没有则写入队列)-->线程数是否超过maxThreadCount(没有则创建新线程)-->执行拒绝策略-->结束
易忽略点:线程池中队列的堆积数量也是重要监控指标,对于实时性比较高的任务特别重要

(8)数据库优化方案(一)读写分离

1.主从复制:首先从库连接到主节点时会传建一个IO线程,用以请求主库更新的binlog,并且把接收的binlog信息写入一个叫relay log的日志文件中。同时主库也会传建一个log dump线程来发送binlog给从库。同时从库还会创建一个sql线程读取relay log的内容并在从库中回放,最终实现主从一致性。
01.这个方案中独立的log dump线程是异步方式,避免对主库流程产生影响
02.从库接收到信息后不是直接写入从库存储中,二十写入relay log 是避免写入从库耗时长,最终造成主从库延迟长
缺点:主从延迟,受限于主节点宽带,不能无限制的增加从节点一般3~5个,部署复杂度
主从延迟解决方案:
01.数据冗余,主库的数据直接传递给需要数据的人
02.使用缓存,同步到数据库的同事写入到缓存中
03.查询主库
2.如何访问数据库
客户端负载负载均衡&服务端负载均衡

(9)数据库优化方案(二)分库分表

垂直拆分:业务相关性
水平拆分:将单一数据表按照某个策略拆分到多个数据库或者表中关注数据的特点,根据字段的哈希值或者区间来拆分
分库分表引入的问题:非拆分键全表扫描。
解决方案:
1.ID存储的分库分表,当使用昵称查询的时候可以创建ID和昵称的映射关系表,然后也分库分表。
2.使用另外一个拆分键,冗余一份存储
3.使用其他方式存储,hbase/es/mongoDB

(10)分布式ID唯一性

主键的选择:1业务字段(用户表的手机号或者email或者身份证号。但是可能会变或者一对多)2.生成唯一ID最合适
优点:
1.ID有序提升有助于数据的写性能
2.UUID没有业务含义,生成的ID可以被反破解,知道哪个机房生成,为哪个业务服务等

(11)NoSQL与数据库互补

不使用SQL作为查询语言,提供优秀的横向扩展能力和读写性能,非常契合互联网项目高并发大数据的特点
举例:
redis LevelDB这样的KV存储,优势是极高的读写性能
Hbase Cassandra列式存储,适用于离线数据统计
MongoDB CouchDB文档型数据库,特点是模式自有,表中字段任意扩展
优点:
1.弥补了传统数据库的性能不足
2.数据库变更方便 不需要更改原来的数据结构
3.适合互联网项目常见的大数据量场景
不过这个看法是个误区,因为慢慢的我们发现业务开发的场景下还是需要利用SQL语句的强大查询功能以及传统数据库事务和灵活的索引等
传统数据库使用机械磁盘,两种访问方式 随机IO和顺序IO InnoDB更新binlog redolog undolog都是顺序IO,而更新dataFile和索引文件就是在做随机IO。为了减少随机IO和发生,关系型数据库做了很多优化,比如写入时先写入内存,再批量刷新到磁盘上,但随机IO还是会发生(页分裂会极大地损耗写入性能)
NoSQL是如何解决的呢:基于LSM树和存储引擎,牺牲了一定的读性能获取高效的写性能。核心思想是数据先写入一个叫做MemTable的内存结构中,menTable中数据是按照写入的key来排序的,为了防止MenTable里面的数据因为机器掉电或者重启而丢失,一般会通过写Write Ahead log的方式将数据备份到磁盘中。积累到一定的规模后会被刷新成一个新文件SSTable(Sorted String table)当SSTable达到一定数量的时候会进行合并,减少文件的数量,因为SSTable是有序的,所以合并速度很快。
当从LSM树里面读取数据时,首先会从MemTable中查找数据。如果没有则从SSTable中查找数据,因为存储的数据都是有序的,所以查找效率很高,但是因为数据被拆分成多个SSTable,所以读取效率会低于B+树索引
MongoDB有三个扩展性方面的特性:
1.副本集,可以理解为主从分离,冗余数据,分担读请求,主节点挂了可以补上
2.分片 可以理解为分库分表,数据按照某种规则拆分成多份,存储在不同的机器上面
3.负载均衡。当发现Shard质检的数据分布不均匀,会启动Balancer进程对数据进行重新的分配

(12)缓存

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值