速度与性能·系统优化之道

速度与性能·系统优化之道

系统优化

七牛云存储(牛小七) · 2015-09-28 17:47

速度与性能·系统优化之道

速度与性能,是系统优化最重要的指标,在网站和移动业务快速成长的今天,无论在系统搭建之初,还是在规模扩大阶段,都要充分考虑到系统架构的优化和性能的维护,以应对未来在稳定性、扩展性以及响应速度方面的要求。在七牛“开发者最佳实践日·第16期-速度与性能·系统优化之道”上,OneAPM技术总监刘秋岐,七牛云技术总监李瑞奇,华为资深架构师、《Netty权威指南》作者李林锋,分别从移动应用、CDN、高性能架构等不同业务领域的成功实践进行分析,为系统构架师、运维工程师和开发者带来了系统优化的思考和启发。


大中型网站数据库架构设计和优化之道


针对缓存解决不了的事务操作和逻辑运算复杂的高并发访问,数据库的伸缩性架构设计以及横向的扩展能力非常重要。OneAPM技术总监刘秋岐介绍了他在数据库架构的演变过程中遇到的坑,以及解决这些问题的经验,并分享了如何从整体上优化后端的架构。


数据库架构的演进、问题及解决办法


随着网站用户量和数据量的增长,MySQL数据库架构的演进一般为主从架构、一主多从、分库分表到分布式架构。




主从架构


问题:主从延迟,从库单 slave_sql_thread 跟不上主库并发写数据,主从同步产生延时。


解决方案:

  • 升级MySQL 至 版本5.6.3,支持多线程的主从复制;

  • 使用MariaDB-10,优点是可以实现并行复制;

  • 主库使用机械硬盘,从库可以使用SSD盘或者PCIe Flash,尽量使主从库一个机房;

  • sync_binlog=0 , innodb_flush_log_at_trx_commit= 0/2;

  • 拆主库,拆一个主库为两个主库,变相减少单个主库上的写的量。


一主多从


问题:一主多从(读写分离)的高可用实现,对读和写都要做高可用。


解决方案:一个主库,多个从库,主库写,从库负责查询,主库的HA通过Keepalived实现,从库读的高可用通过LVS或者HAProxy实现。现在很多中小型公司都喜欢用HAProxy,因为它比较成熟,LVS毕竟是四层的转化,配置也稍微复杂一点。


分库分表


问题:怎样合理分库分表?


解决:合理地分库分表需要遵循的要点:

  • 一般按照业务来分库,避免跨库查询;

  • 分表有多种分法,大多按照主键ID分表或者有区分度的主键字段分表,如一些用户表的用户注册ID是邮箱号,按照ID做MD5值,然后根据MD5串的第一位分16张表,按照第二位可以分16*16=256张表等。


分布式DB


问题:怎样设计分布式的MySQL DB集群,高性能高可用的实现DB路由?


解决:做到分布式DB的时候引入Proxy,可以做到自动切换,也可以根据前端的流量对读写进行分离,读请求负载均衡,分表读写。DBProxy的产品,除了官方的MySQL Proxy,还有淘宝的Cobar,360的Atlas,都较稳定,也都有各自的社区。


数据库优化的四个方面


数据库优化有四个方面:软、硬、监、施,分别是软件层次、硬件层次,怎么做好数据库的监控,以及后面的一些运维过程中的经验。

数据库软件层次的优化主要包括MySQL优化调整和MySQL操作系统优化。参数的不断优化是DBA需要掌握的,如下图所示。




操作系统层面,文件系统推荐用XFS(横向对比发现XFS的写表现出色),挂载设置noatime、nodiratime、nobarrier提高I/O的一些属性;运维的机器基本都带读的卡,本身已有数据,所以将操作系统的数据关闭(numa=off),可以适当地减小数据库里的量,包括增加队列的连接数。


在硬件选型上,因为数据库是三高(高CPU、高MEM、高I/O)系统,在一定预算下,建议尽量选择大的内存,选择大内存好于选提升I/O的方案。之后是提升I/O,一般把数据库的数据放在SSD盘上,日志放在普通的磁盘上。


在监控层面,设置合理的监控报警和预警机制。监控的过程中要指标先行,根据整个系统制定合理的监控指标,包括MySQL服务可用、当前连接数、InnoDB每秒读写量、MyISAM读写次数等等,然后以此为基准进行一些优化比较。


刘秋岐分享了黑盒监控和白盒监控的经验。前者监控的是可用性,首先做一个test库,实时往里面放数据,然后再放出来看对不对,判断数据库在哪个环节有问题。然后白盒监控,包括网络流量、日志、临时表、MyISAM等。此外,还要一些辅助性的监控,例如Slowlog,对每五分钟的数据进行监控,当Slowlog非常多的时候就要报警,然后对Slowlog进行分析。成熟的公司一般都会对Slowlog进行审核,但小的移动互联网公司可能上线之后才发现Slowlog业务设计有问题。所以,对Slowlog的监控非常有必要。另外,是对Binlog的一些定制化统计曲线,比如对订单表的更新做监控,看订单数是不是猛涨了。


监控工具主要是Nagios和Zabbix。Nagios是基本数值型监控,监控MySQL服务可用性、当前连接数等。Zabbix可以根据监控数值绘图,保留历史数据,根据收集的数值做逻辑运算,符合报警的条件即报警。


最后一个层面是施——运维中的经验。首先,任何对表的操作都要提前备份表,误操作时可以补救。其次是上线前对SQL做审核,查看SQL的执行计划,检查索引。MySQL Server上线之前文件系统最好做LVM,可以做一个磁盘的快速备份和快速搭建存库。此外,还要定期做主从一致性检验,因为主从之间同步会出现丢数据的情况,一旦从库不经常做主从校对,则会影响用户的感受。最后,Slowlog最好每天做一下工具报表,定期验证备份的可用性。


CDN运营优化实战


七牛云技术总监李瑞奇从被动处理、简单调优和运营优化三个方面介绍了CDN运营优化实战。


被动处理


被动处理就是基于用户反馈来处理。


存在的问题:

  • case-by-case,一对一解决的价值非常小,整个处理问题的方式也非常低效,客户自己的用户、客户、中间平台、上游CDN厂商四层的沟通,整个流水线非常长。

  • 每个环节人员表现都不够专业,没法给出一个全面的答案。

  • 通过这个用户反馈的方式运作优化CDN的时候,不知道全局的CDN状态。


简单调优


比较流行的第三方监测,往往只看到总体的数据、可用性、性能、故障等,这样的监测图谱很有可能掩盖住细节问题,并且很难发掘出故障原因,也不符合运营规律。


总之,工具能起到一定作用,但很难用,虽然他们也推出了一些新的服务,但并未站在为用户解决问题、如何使用该产品的角度上看问题。CDN调优专员使用这样的第三方监测工具,80%的时间都在该系统里找客户有什么问题,然后调节点,解决问题。这套系统非常低效,也很难快速定位问题。


CDN运营优化不仅仅是使用一个第三方监测工具那么简单。应该做一个辅助CDN优化的产品,专门针对使用者的需求,考虑运营优化的规律及日常使用运作的方式。第三方监测工具有时会掩盖住问题,很难挖掘,看上去趋势不错,图上跟别人比只有几个点的差别,但这两三个点的差别可以导致对应的用户反馈量增加,比如移动的区域不好,在总体的用户比例里面只有10%,但是就会有不断的投诉,用户反馈就会很多。


李瑞奇认为,CDN优化需要一个系统能够显示出问题所在,并且可以自动发掘问题原因,而不是去第三方工具里面搜集、查看,通过很长时间总结得出。因此,七牛做了一套质量系统,并提供以下五种功能:

  • 最优竞品对比;

  • 多维度对比:可用性、响应时间、中位速度、覆盖;

  • 运营优化力度精确到运营商省份;

  • 一眼看出异常运营商省份的能力;

  • 快速定位具体问题原因的能力。


李瑞奇通过一系列的案例说明了五种功能的体现。例如客户希望做一下CDN的质量对比,七牛质量系统把客户正在使用的CDN数据汇到一起做对比。




如上图,第一点,竞品对比,竞品对比非常有用。如果差距不是很大,就不用优化,即使数据不好看,也可能是当地网络质量较差造成。第二点,多维度的分析,如上图的响应时间的分析。第三点,优化粒度精细到运营商省份,与国内实际网络拓扑结构配置。第四点,从上图可一眼看出哪里有问题,效率可以提升几十倍,用第三方工具则无法达到这点。


在质量系统中,一眼看出异常运营商省份的能力和快速定位具体问题原因的能力非常重要。该系统能告诉你哪里出现了问题,打开系统后,任何一种检测或者评估指标,都可以快速呈现;它还可以告诉你是什么原因导致了这些问题。做到这两点以后,效率会提升很多倍。


CDN优化=技术+运营


运营不能解决所有CDN优化的问题。CDN优化包括两件事,第一是运营,第二是技术。运营里面有一套系统作为辅助很重要。技术方面,除了CDN厂商建节点的技术,还有调度、其它协议、防劫持等。这里要注意以下四点。


第一,小用户无运营。即便这些用户拿数据跟CDN厂商指出问题,CDN厂商也不会帮他调。小用户拿到的单价最高,CDN厂商会给他随意调度,由于CDN厂商要服务大客户,小用户被分配的资源会是最差的,出问题的时候也会第一个被忽视。


第二,协议缺陷(DNS多线出口、缓存、劫持)。CDN调度其实有很多缺陷,DNS查询需要时间,很多区域每次生效的时间一般是五分钟,但仍有很多区域是好几天,比如移动区域就会缓存好几天。另一个缺陷是DNS劫持,运营商把请求劫持到内网服务器,这样就减少了网间结算成本,可以节约大量的钱。当然,还有一些恶意劫持。


第三,用户的使用习惯是非标准的。用户很多时候用CDN并没有考虑CDN的运作方式。CDN厂商可能有多种平台,如网页平台、下载平台、点播平台,这些平台的使用并未考虑用户习惯,基本是用户适应厂商。七牛的做法则提供了一套解决方案,解决了这种非标准的接入。


第四,CDN厂商资源质量参差不齐。由于每家CDN厂商有着不一样的优势,就需要把各CDN的厂商融合在一起,还要对CDN厂商进行监督,告诉他哪里出了问题,这需要较强的技术才能做到。


李瑞奇最后介绍,为让天下没有难用的CDN,七牛推出了FUSION融合CDN管理平台。该平台支持多家CDN的平滑接入、具有较全面的功能、质量可视、虚拟线路、调度可控。七牛会帮助用户做CDN的运营优化,也会让用户实时看到自己的CDN质量。


基于Netty构建高性能RPC通信框架


华为资深架构师李林锋为大家分享了基于Netty构建高性能RPC通信框架,包括I/O模型选择、序列化框架选型、高效线程模型、反射优化和异步调用五个方面。


I/O模型选择


同步阻塞I/O的性能问题是伸缩性差、效率低。电信行业采用的这种模型的核心计费系统非常慢,平时三秒以内处理完,超时大概三十多秒。2004年首次出现的非阻塞I/O,优势主要体现两点:第一是多路复用,一个线程可以同时处理多条链接,这就解决了一个线路独占一个链接的问题。第二是I/O操作均不会阻塞I/O线程,如果是阻塞I/O,线程会挂在这里,你并不知道会等待多长时间,这时,超时设置会非常困难,超时太短失败率会比较高,但超时太长就会挂资源。采用非阻塞I/O以后不用担心挂线程,可以用更少的线程处理海量的链接。




I/O通信框架选择,一是开发纯Java NIO,Java的类库,但研发成本比较高。二是Mina,Mina在2011年以后非常流行,做游戏的用的非常多,但版本更新慢,最近几年社区不太活跃。三是基于Mina构建的Netty,其性能高、资料丰富、版本更新节奏非常快,社区也非常活跃,现在很多开源项目都已接到Netty上。


序列化框架选型


影响序列化性能的关键因素:

  • 第一,码流的大小。持久化会占磁盘,即占整个网络带宽资源。

  • 第二,序列化和反序列化的性能。它反应在每秒可以序列化和反序列化的次数,以及在序列化和反序列化的过程中CPU和内存的占用。

  • 第三,并发调用的性能表现。线程基本上会动态地增加线程或者调大线程,并发调用非常高就有不稳定的现象,有一些消息,正常情况下是一毫秒以下,但是有一些时延会达到100毫秒以上。


如果抛开性能,序列化框架的选型主要看实际的项目和应用场景。第一点,如果量不是很大,建议可以用文本方式。第二点,如果对性能的要求较高,或者预估未来的性能增长非常厉害,建议用二进制序列化框架ProtocolBuf。第三点,码流的压缩,文本类使用GZIP,二进制类就是通过Zig-Zag。需要注意的是,压缩会占用整个CPU资源,如果应用对CPU时间非常敏感,建议做性能对比。


高效线程模型

下图是非常典型的一个多路复用的I/O线路模型,前端相当于是一个线程,可以接N个客户端的连接进来,分到后端的连接I/O线程池里,由它来处理I/O的读写,这种设计理念的好处是可以实现I/O的接入线程和读写线程的分离。




线程的设计理念很重要,但有几类错误是大家较容易犯的。第一类是几乎所有的产品都会犯的错误,即通讯线程和业务逻辑线程都在一个线程里面。第二类是一条消息用一个线程做独立处理,用一个线程池来配核心线程数、最大线程数,整个节点或者一个进程里面只有一个大而全的线程池,N个线程抢一个资源,并发调度性能非常差。


高效线程模型


Netty纠正了线程的理念,核心理念就是要串行不要做并行,把消息读进来以后,往后端传递的时候,在整个调度的流程里面不做线程的切换。并发性能怎么切换?这里面有两点,第一,在整个Netty里面,通常只做跟I/O相关的事情,比如序列化和反序列化、编解码,或者日志。第二,前端其实是一个I/O的线程池,相当于一个线是串行的,但是因为都是在一个线程池里面,也是一个并行的处理。




李林锋最早做I/O框架的时候,也是采用的这种模式。在开发过程中,他不建议配一个大的线程池,而是针对不同的业务和模块,用N个线程组,尽量让每个线程组的池降到最低。


反射优化


网络传输以外,反射对性能的影响也非常大。RPC框架中反射影响体现在两个方面:第一,序列化和反序列化;第二,反射的调度和接口的回调。


解决的对策:第一,定一个结构,不用任何接口,POJO对象自编解码,消除反射。第二,IDE自编解代码自动生成小工具,批量生成编码或者修改代码。


反射的其它优化,一是解决类、方法和字段缓存机制;二是通过setAccessible(true)的方式关闭安全检查,提升反射性能(20倍的性能提升);三是直接用Field代替反射,性能提升会非常明显,风险是内存越界JVM就会core dump,追求极致性能可以使用;最后是使用ASM等字节码框架动态生成字节码代替 JAVA 反射提高性能。


异步调用


异步调用对开发者而言争议比较大,像使用本地方法一样使用远程,对于接口的使用会有要求,所以大部分开发者会排斥异步调用。


华为终端RPC框架,现在机器已经超过一万台,服务框架很早就已支持异步调用,但很难说服每个客户使用,大多数的开发者不愿意使用,而且不知道它的调用结果,通过Listener监听,影响体验。


华为终端最大的差异是独立运营,对所有时延非常敏感的人都可以做异步调用。发起调用的时候,消息进行序列化以后要走路由,如果同步调用,线程会在等结果,但是采用异步不会等,把消息序列化投入到序列框架以后,会创建一个上下文,这个上下文会缓存一些ID信息,然后把上下文返回,通常情况下会做一个监听,当接收到最终处理完,应答返回以后,就可以重新唤醒,继续拿到上下文往下走,被动地执行。




当我们在某一个节点要调N个服务,如要调A服务、B服务、C服务、D服务,同步调用就是A+B+C+D,这时最后唤醒的可能时间最大,而异步调用会降低整个端到端的时延,这是提升整个RPC框架非常重要的一个措施。


以上内容根据开发者最佳实践日·第16期讲师演讲整理而成,如需获取详细的演讲信息和往期内容回顾,可访问「七牛开发者最佳实践日」活动专题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值