IO Optimization

磁盘 I/O 优化:css

性能检测前端

而磁盘 I/O 一般都很耗时,咱们要判断 I/O 是不是一个瓶颈,咱们有一些参数指标能够参考:ios

如咱们能够压力测试应用程序看系统的 I/O wait 指标是否正常,例如测试机器有 4 个 CPU,那么理想的 I/O wait 参数不该该超过 25%,若是超过 25% 的话,I/O 极可能成为应用程序的性能瓶颈。Linux 操做系统下能够经过 iostat 命令查看。一般咱们在判断 I/O 性能时还会看另一个参数就是 IOPS,咱们应用程序须要最低的 IOPS 是多少,而咱们的磁盘的 IOPS 能不能达到咱们的要求。每一个磁盘的 IOPS 一般是在一个范围内,这和存储在磁盘的数据块的大小和访问方式也有关。可是主要是由磁盘的转速决定的,磁盘的转速越高磁盘的 IOPS 也越高。数据库

如今为了提升磁盘 I/O 的性能,一般采用一种叫 RAID 的技术,就是将不一样的磁盘组合起来来提升 I/O 性能,目前有多种 RAID 技术,每种 RAID 技术对 I/O 性能提高会有不一样,能够用一个 RAID 因子来表明,磁盘的读写吞吐量能够经过 iostat 命令来获取,因而咱们能够计算出一个理论的 IOPS 值,计算公式以下因此:( 磁盘数 * 每块磁盘的 IOPS)/( 磁盘读的吞吐量 +RAID 因子 * 磁盘写的吞吐量 )=IOPS后端

提高 I/O 性能浏览器

  1. 增长缓存,减小磁盘访问次数
  2. 优化磁盘的管理系统,设计最优的磁盘访问策略,以及磁盘的寻址策略,这里是在底层操做系统层面考虑的。
  3. 设计合理的磁盘存储数据块,以及访问这些数据块的策略,这里是在应用层面考虑的。如咱们能够给存放的数据设计索引,经过寻址索引来加快和减小磁盘的访问,还有能够采用异步和非阻塞的方式加快磁盘的访问效率。
  4. 应用合理的 RAID 策略提高磁盘 IO,每种 RAID 的区别咱们能够用下表所示:

 

磁盘阵列 说明 
RAID 0   数据被平均写到多个磁盘阵列中,写数据和读数据都是并行的,因此磁盘的 IOPS 能够提升一倍。
RAID 1  RAID 1 的主要做用是可以提升数据的安全性,它将一份数据分别复制到多个磁盘阵列中。并不能提高 IOPS 可是相同的数据有多个备份。一般用于对数据安全性较高的场合中。
RAID 5  这中设计方式是前两种的折中方式,它将数据平均写到全部磁盘阵列总数减一的磁盘中,往另一个磁盘中写入这份数据的奇偶校验信息。若是其中一个磁盘损坏,能够经过其它磁盘的数据和这个数据的奇偶校验信息来恢复这份数据。
RAID 0+1  如名字同样,就是根据数据的备份状况进行分组,一份数据同时写到多个备份磁盘分组中,同时多个分组也会并行读写。

 

网络 I/O 优化:缓存

  1. 一个是减小网络交互的次数:要减小网络交互的次数一般咱们在须要网络交互的两端会设置缓存,好比 Oracle 的 JDBC 驱动程序,就提供了对查询的 SQL 结果的缓存,在客户端和数据库端都有,能够有效的减小对数据库的访问。关于 Oracle JDBC 的内存管理能够参考《 Oracle JDBC 内存管理》。除了设置缓存还有一个办法是,合并访问请求:如在查询数据库时,咱们要查 10 个 id,我能够每次查一个 id,也能够一次查 10 个 id。再好比在访问一个页面时经过会有多个 js 或 css 的文件,咱们能够将多个 js 文件合并在一个 HTTP 连接中,每一个文件用逗号隔开,而后发送到后端 Web 服务器根据这个 URL 连接,再拆分出各个文件,而后打包再一并发回给前端浏览器。这些都是经常使用的减小网络 I/O 的办法。
  2. 减小网络传输数据量的大小:减小网络数据量的办法一般是将数据压缩后再传输,如 HTTP 请求中,一般 Web 服务器将请求的 Web 页面 gzip 压缩后在传输给浏览器。还有就是经过设计简单的协议,尽可能经过读取协议头来获取有用的价值信息。好比在代理程序设计时,有 4 层代理和 7 层代理都是来尽可能避免要读取整个通讯数据来取得须要的信息。
  3. 尽可能减小编码:一般在网络 I/O 中数据传输都是以字节形式的,也就是一般要序列化。可是咱们发送要传输的数据都是字符形式的,从字符到字节必须编码。可是这个编码过程是比较耗时的,因此在要通过网络 I/O 传输时,尽可能直接以字节形式发送。也就是尽可能提早将字符转化为字节,或者减小字符到字节的转化过程。
  4. 根据应用场景设计合适的交互方式:所谓的交互场景主要包括同步与异步阻塞与非阻塞方式,下面将详细介绍。

同步与异步安全

所谓同步就是一个任务的完成须要依赖另一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成,这是一种可靠的任务序列。要么成功都成功,失败都失败,两个任务的状态能够保持一致。而异步是不须要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工做,依赖的任务也当即执行,只要本身完成了整个任务就算完成了。至于被依赖的任务最终是否真正完成,依赖它的任务没法肯定,因此它是不可靠的任务序列。咱们能够用打电话和发短信来很好的比喻同步与异步操做。服务器

在设计到 IO 处理时一般都会遇到一个是同步仍是异步的处理方式的选择问题。由于同步与异步的 I/O 处理方式对调用者的影响很大,在数据库产品中都会遇到这个问题。由于 I/O 操做一般是一个很是耗时的操做,在一个任务序列中 I/O 一般都是性能瓶颈。可是同步与异步的处理方式对程序的可靠性影响很是大,同步可以保证程序的可靠性,而异步能够提高程序的性能,必须在可靠性和性能之间作个平衡,没有完美的解决办法。网络

阻塞与非阻塞

阻塞与非阻塞主要是从 CPU 的消耗上来讲的,阻塞就是 CPU 停下来等待一个慢的操做完成 CPU 才接着完成其它的事。非阻塞就是在这个慢的操做在执行时 CPU 去干其它别的事,等这个慢的操做完成时,CPU 再接着完成后续的操做。虽然表面上看非阻塞的方式能够明显的提升 CPU 的利用率,可是也带了另一种后果就是系统的线程切换增长。增长的 CPU 使用时间能不能补偿系统的切换成本须要好好评估。

两种的方式的组合

 

组合方式 性能分析
同步阻塞  最经常使用的一种用法,使用也是最简单的,可是 I/O 性能通常不好,CPU 大部分在空闲状态。
同步非阻塞  提高 I/O 性能的经常使用手段,就是将 I/O 的阻塞改为非阻塞方式,尤为在网络 I/O 是长链接,同时传输数据也不是不少的状况下,提高性能很是有效。这种方式一般能提高 I/O 性能,可是会增长 CPU 消耗,要考虑增长的 I/O 性能能不能补偿 CPU 的消耗,也就是系统的瓶颈是在 I/O 仍是在 CPU 上。
异步阻塞 这种方式在分布式数据库中常常用到,例如在往一个分布式数据库中写一条记录,一般会有一份是同步阻塞的记录,而还有两至三份是备份记录会写到其它机器上,这些备份记录一般都是采用异步阻塞的方式写 I/O。异步阻塞对网络 I/O 可以提高效率,尤为像上面这种同时写多份相同数据的状况。
异步非阻塞 这种组合方式用起来比较复杂,只有在一些很是复杂的分布式状况下使用,像集群之间的消息同步机制通常用这种 I/O 组合方式。如 Cassandra 的 Gossip 通讯机制就是采用异步非阻塞的方式。它适合同时要传多份相同的数据到集群中不一样的机器,同时数据的传输量虽然不大,可是却很是频繁。这种网络 I/O 用这个方式性能能达到最高。

   

虽然异步和非阻塞可以提高 I/O 的性能,可是也会带来一些额外的性能成本,例如会增长线程数量从而增长  CPU 的消耗,同时也会致使程序 设计的复杂度上升。若是设计的不合理的话反而会致使性能降低。在实际设计时要根据应用场景综合评估一下。
相关文章
相关标签/搜索