葸文信 14020110016
嵌牛导读:最近对多线程、锁、事务隔离、JVM、数据结构、分布式等方面的知识进行了梳理和思索,对性能优化的常用“伎俩”进行了一些反思和总结提炼,不过受山东大葱哥本人经验和能力所限难免有错误过欠妥之处,如有发现还请不吝指出为盼,看在所有内容全部手机码字的面子上请多多支持。
嵌牛鼻子:应用数据优化,多线程
嵌牛提问:性能优化空间时间有如何辩证关系?
嵌牛正文:性能归结起来是空间和时间的此消彼长,当然再引申下就是空间、时间、可靠性的折中和侧重。受限于空间(存储、资源)和可靠性等的限制,性能在一定阶段不可能无限制的提升,在提升性能的同时我们也需要保证可靠性(去线程安全问题等),不过随着科技的进步过一段时间可能有会产生新的的性能提升空间(如内存、CPU二级缓存、GPU等)。
接下来我将对访问量线性增长的基于web典型应用的性能优化手段进行简述,剖析其中的时间 空间 可靠性关系。
升级到更加强大的资源
主要指性能方面的强大,如内存扩容或升级、CPU升级、GPU运算、固态硬盘、USB2.0到USB3.1等,这些都是随着科技的进度,用更先进的资源来为性能提升提供更好的空间支撑,当然这些先进资源的可靠性是有科技进步来保证的。这是单主机机时代性能优化的第一考量。
如数据库索引,用空间换时间
硬件资源升级后,接下来要优化的自然是io方面,而web应用的io以数据库为主。
数据库最常用的优化手段就是加索引,mysql的索引一般使用B+树,通过动态维护树的平衡和深度来维护索引。而索引就相当于字典的目录,它在增加了存储空间的同时,提高了查询的性能,当然前提是你要能有效使用索引,比如增删改比较多的应用增加索引后会降低性能,比如有些查询语录会是索引失效。
程序层面基本性能优化
主要从sql语句的优化充分利用索引、sql语句的合并或减少、代码优化重构减少冗余逻辑几方面着手。
数据库访问本质是读取的硬盘,所以访问速度肯定低于内存,所以减少sql访问的一种途径就是多条语句所需的数据一次读取到内存中,基于内存中的数据进行计算处理,这也是以更强大空间资源换取时间的方式。
连接池管理
建立数据库链接(建立io链接也是一样)也是一个比较耗费性能的工作,web应用需要频繁的建立链接、访问数据、关闭连接,于是乎就走了连接池(数据库连接池、io连接池等等),连接池顾名思义就是存放连接的池子,当需要访问数据库时,不再是每次都新建连接,而是直接在池子里面取来复用,节省了创建连接的时间,但条件是需要牺牲空间来存放连接。
缓存
在很多情况下,应用会多次访问数据库中的相同数据,而每次都从数据库读取明显是影响性能的。目前主流的ORM框架都有一级缓存、二级缓存用来提供数据缓存功能,通过读取缓存数据进而提高访问性能,很明显这也是空间换取时间的策略。缓存方案需要考虑命中策略,毕竟缓存是有限的,缓存使用代价是比硬盘要贵很多的,不可能无限制的缓存数据,所以尽量缓存命中率高的数据,一般常用的最近最不常使用策略进行缓存的更替。其实这个操作系统层面的内存管理方案是相似的。
web层基本性能优化
web层常用的优化手段有合并js、css,开启内容压缩、减小图片大小(无损压缩)、开启页面缓存、js后加载、图片懒加载。
web层主要涉及浏览器和服务器的网络交互,而网络交互显然是耗费时间的,所以要尽量减少交互次数,降低每次请求或响应数据量。这里面的开启压缩,在服务端是时间换空间的策略,服务端需要牺牲时间(其实是极短的)进行压缩以减小响应数据大小,压缩后的内容可以获得更快的网络传输速度,所以总体上时间是得到了优化的。
应用数据分离
随着性能需求进一步提升,单主机应用已经出现瓶颈,这时我们就需要进行第一步拆分了,将数据库独立出来,用一台单独的服务器来跑数据库。这个总体看是空间换取时间的策略,但在局部看的话却不是,如拆分后原先的本地io操作变成了网络访问,而网络访问速度肯定是低于本机io访问的,从这个角度来看是以牺牲时间来换取原单一主机的空间资源。而效果上来看,通过两台主机对应性能的提升(应用处理和数据访问),山东大葱哥认为肯定超过因网络带来的时间损耗。
多线程:
因大部分web应用都是与基于多线程的,不需要开发人员再单独启动多线程,但多线程作为一种性能优化的方式还是有必要说说。多线程以更加充分的利用cpu资源换取总体时间的节省。这个过程中可能会带来多线程间脏读或者数据不一致的问题,解决办法是加锁来保证串行,实质又是以牺牲时间换取可靠性。
针对锁带来的时间开销又有了悲观锁(同步) 乐观锁的区分,悲观锁是典型的以时间空间换取可靠性的策略,乐观锁有一种方案是cas方式,这又是通过空间开换取时间的方案。(类似于数据库的锁)
java语言中还有一个volitile关键字(其他语言也有类似关键字),该关键字将数据描述为多线程可见,这也算乐观锁的一种方式,牺牲了一点线程安全性、牺牲了比同步要少的时间时间换取的折中方案。