访问日志IO性能优化
在高并发量的场景下磁盘IO往往是性能的瓶颈所在,访问日志涉及到频繁的写操作,所以这部分要尽可能地优化,不然将拖累系统的整体性能。针对文件记录及数据库记录两种方式可以有以下措施提高写性能,
l 避免频繁的打开关闭文件。将日志写入文件的一般操作步骤是打开-写入-关闭,但假如在需要频繁写入日志的场景下,这种方式在性能上肯定会存在问题,因为每次打开关闭都是需要成本开销的,所以必须要想想是否有别的更好的方式,竟然问题出现在打开关闭的次数,那么解决问题思路就从这里下手,可以在第一次打开写入日志后不进行关闭操作,保持打开的状态,下一次写入则无需再次打开可直接写入。而由于实际过程中访问日志产生的量非常大,肯定不可能只往一个文件中写入数据,可能会按时间间隔每天写一个文件或按文件大小每50M写一个文件,所以在实际设计中会涉及到更换文件的操作,更换时需要把原来的文件流关闭。通过上述措施避免了文件频繁的打开关闭操作,但它同时也存在一些缺点,文件流不关闭会一直占用操作系统资源,且如果不及时关闭可能在程序运行过程中发生异常未正确处理而导致文件流未能关闭,进而将会导致内存泄漏。
l 添加缓冲区:添加缓冲区的作用简单地说应该是减少文件真实写入磁盘的次数,一般将文件写入的方式是每执行一次写入操作就把此次需要写入的数据写入磁盘介质中,而缓冲区模式则是把要写入的数据先写入内存中,当缓冲区内存量达到一定程度才写入磁盘,所以添加了缓冲区的文件操作并非每次写入都是存储介质中,缓冲区对于IO操作是一个十分重要的概念,缓冲区具体的实现可以参考我前面相关的章节,当然jdk已经提供了相关的缓冲类并不用我们重复制造轮子。缓冲区的添加无疑提高了操作性能,但它同样存在缺点,它无法百分之百保证所有数据都成功记录到存储介质中,可能在系统发生意外时导致缓冲区无法写入文件,而丢失的仅仅是缓冲区的数据。
l 利用“池”技术优化连接避免每次创建连接,池技术更多的是针对以数据库做为存储端的方案,即是我们最熟悉的连接池了,JDBC每次创建连接都需要很大的成本开销,如果每次写入都重新建立连接这对系统来说简直无法忍受,于是可以在系统初始化时就创建一个连接池,池内包含了很多建立好的连接,每次使用时只需往池里取出,使用完不关闭连接而是把连接重新放回池里即可。此种方式的好处显而易见,操作性能大大地提高,而如果真要说有哪些缺点的话估计只能说连接池需要占用一些操作系统资源,即使没有被使用。但对于现在的机器这点成本消耗基本可以忽略不计。
l 优化锁竞争,首先,在一个高并发的场景中日志的写入肯定是多线程的,多线程的使用在提高系统性能的作用是毋庸置疑的;其次,竟然在文件流的写入操作是多线程的,那必然涉及到锁竞争的问题,因为如果没有锁的保护文件可能被写得乱七八糟且正确性无法得到保证,所以线程一定是在写入前先尝试竞争写入锁,只有成功获取锁的线程才能执行写入操作,一旦写完就释放锁;最后,这种锁的竞争跟JDK的实现及JVM的实现相关,可能是所有竞争的线程采用自旋方式获取锁,也可能是采用线程挂起方式,对于自旋方式及挂起方式在不同场景有各自的优势,线程自旋模式可能会消耗资源,同样挂起恢复也可能会消耗资源,在实际使用中可通过性能测试比较决定使用哪种方式。在JDK的自带的并发包是先尝试自旋获取,若干次失败后进行挂起操作。
l 考虑使用非阻塞模式,所谓非阻塞(NIO)是指在进行IO操作时当执行写入操作时不等待执行结果而是直接放弃对CPU的使用,这种模式基于事件驱动,不同的事件由某一或若干线程处理,在实际中NIO模式被证实在某些场景中是性能提升的利器。它的唯一缺点估计是让你程序变得更加复杂。
使用异步IO,异步IO(AIO)是JDK1.7后提供的一种新IO模式,它主要是针对CPU的优化,是CPU级别的优化尝试,在实际中使用需要对系统使用场景做性能测试对比再决定是否进行AIO改造。
喜欢研究java的同学可以交个朋友,下面是本人的微信号:
访问日志IO性能优化的更多相关文章
- 性能调优之访问日志IO性能优化
性能调优之访问日志IO性能优化 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908821 ...
- 按日期切割nginx访问日志--及性能优化
先谈下我们需求,一个比较大的nginx访问日志,根据访问日期切割日志,保存在/tmp目录下. 测试机器为腾讯云机子,单核1G内存.测试日志大小80M. 不使用多线程版: #!/usr/bin/env ...
- log4j日志输出性能优化-缓存、异步
转载 1.log4j已成为大型系统必不可少的一部分,log4j可以很方便的帮助我们在程序的任何位置输出所要打印的信息,便于我们对系统在调试阶段和正式运行阶段对问题分析和定位.由于日志级别的不同,对系 ...
- ELK Stack 日志平台性能优化
转载自: https://mp.weixin.qq.com/s?__biz=MzAwNTM5Njk3Mw==&mid=2247487789&idx=1&sn=def0d8c2e ...
- MySQL数据库在IO性能优化方面的设置选择(硬件)
提起MySQL数据库在硬件方面的优化无非是CPU.内存和IO.下面我们着重梳理一下关于磁盘I/O方面的优化. 1.磁盘冗余阵列RAID RAID(Redundant Array of Inexpens ...
- Linux 文件系统IO性能优化【转】
转自:https://blog.csdn.net/doitsjz/article/details/50837569 对于LINUX SA来说,服务器性能是需要我们特别关注的,包括CPU.IO.内存等等 ...
- Linux 文件系统IO性能优化
对于LINUX SA来说,服务器性能是需要我们特别关注的,包括CPU.IO.内存等等系统的优化变得至关重要,这里转载一篇非常不错的关于IO优化的文章,供大家参考和学习: 一.关于页面缓存的信息,可以用 ...
- 磁盘IO性能优化-实践
RAID卡缓存策略调整 原因详解 操作实例 I/O 调度算法 文件系统journal 磁盘挂载参数 操作实例 性能数据对比 RAID卡缓存策略调整 可以将RAID卡缓存策略由No Write Cach ...
- OpenStack入门篇(五)之KVM性能优化及IO缓存介绍
1.KVM的性能优化,介绍CPU,内存,IO性能优化 KVM CPU-->qemu进行模拟ring 3-->用户应用 (用户态,用户空间)ring 0-->操作系统 (内核态,内核空 ...
随机推荐
- HashSet<T>的妙用
HashSet<int> hs = new HashSet<int>(); var ret = hs.Add(1); //ret==true var ret2 = hs.Ad ...
- git使用之错误分析及解决(持续更新)
错误一: 使用 $ git push -u origin master 出现如下错误: error: src refspec master does not match any. error: fai ...
- JavaScript Date(日期)对象
返回当日的日期和时间 如何使用 Date() 方法获得当日的日期. getFullYear() 使用 getFullYear() 获取年份. getTime() getTime() 返回从 1970 ...
- 23 广播服务结合音乐Demo5
MainActivity.java package com.dmy.demo5; import android.app.Activity; import android.content.Broadca ...
- Android必知必会-App 常用图标尺寸规范汇总
若移动端访问不佳,请使用 –> Github版 内容持续更新中,更新日期:2016-08-11 1. 程序启动图标(icon launcher) 放在mipmap-*dpi下,文件名为ic_la ...
- [Mysql]由Data truncated for column联想到的sql_mode配置
系统日志中出现了 ata truncated for column 'agent' at row 1 mysql出现这个问题的原因,无非就是字符集设置 或者是 字段过长导致的. mysql在初始化的时 ...
- Android系统剪切板
Android系统剪贴板 复制字符串到系统剪切板 /** * 复制文本到剪切板 * * @param text * @return */ @SuppressWarnings("depreca ...
- Android四大组件之一Service介绍-android学习之旅(十二)
基本概念: service是android四大组件之一,运行在后台执行耗时操作,并不提供用户界面.其他组件如acticity可以通过startService启动该组件,也可以通过bindService ...
- 05 利用Appliction 传值Activity
步骤一:新建一个类继承Application必须是public class 不然直接奔溃 步骤二:在清单文件AndroidManifest.xml的application添加name属性 值为com. ...
- (一〇三)静态库(.a)的调试
上节介绍的方法,只能创建静态库而不能调试,因为直接创建静态库工程并非可执行文件. 本文介绍的方法创建的静态库断点能够在调试时起作用. 为了能够调试静态库,应该在一个可执行工程(例如Single Vie ...