广告
返回顶部
首页 > 资讯 > 数据库 >使用spark分析mysql慢日志
  • 198
分享到

使用spark分析mysql慢日志

2024-04-02 19:04:59 198人浏览 独家记忆
摘要

熟悉oracle的童鞋都知道,在oracle中,有很多视图记录着sql执行的各项指标,我们可以根据自己的需求编写相应脚本,从oracle中获取sql的性能开销。作为开源数据库,Mysql不比oracle,分

熟悉oracle的童鞋都知道,在oracle中,有很多视图记录着sql执行的各项指标,我们可以根据自己的需求编写相应脚本,从oracle中获取sql的性能开销。作为开源数据库Mysql不比oracle,分析慢sql只能通过slow.log。slow.log看起来不够直观,而且同一条慢sql执行多次的话就会在slow.log中被记录多次,可阅读性较差。
最近,部门开发数据库审计平台上线mysql审计模块,需要为客户提供一键化提取slow.log中慢sql的功能。由于本人之前研究过spark,在分析慢日志的文本结构后,使用Scala语言,利用spark core相关技术,编写了能够去重slow.log中重复sql,并将按执行时间排序的top sql输入到Hive表中的小程序
话不多说,上菜!

开发环境:
1、Centos 6.5
2、jdk 1.7
3、hadoop 2.4.1
4、Hive 0.13
5、Spark 1.5.1
6、scala 2.11.4
hadoop及spark集群环境的搭建方法就不多说了哈,网上资料很多,对大数据感兴趣的童鞋可以尝试搭建。

step 1 使用scala ide for eclipse编写应用程序
analyzeSlowLog.scala:

package cn.spark.study.sql

import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import scala.util.matching.Regex
import scala.collection.mutable.ArrayBuffer
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.types.StructField
import org.apache.spark.sql.types.StringType
import org.apache.spark.sql.types.DoubleType
import org.apache.spark.sql.SQLContext
import org.apache.spark.sql.Row
import org.apache.spark.sql.hive.HiveContext

object SlowLogAnalyze {
  def main(args: Array[String]): Unit = {
    //创建SparkConf,SparkContext和HiveContext
    val conf=new SparkConf()
      .setAppName("SlowLogAnalyze");
    val sc=new SparkContext(conf)
    val hiveContext=new HiveContext(sc)

    //读取hdfs文件,获取logRDD
    val logRDD=sc.textFile("hdfs://spark1:9000/files/slow.log", 5)

    //创建正则表达式,用来过滤slow.log中的无效信息
    val pattern1="# Time:".r
    val pattern2="# User@Host:".r
    val pattern3="SET timestamp=".r 

    //对logRDD进行filter,过滤无效信息
    val filteredLogRDD=logRDD.filter { str => 
          //正则返回的是option类型,只有Some和None两种类型
          if(pattern1.findFirstIn(str)!=None){
            false
          }else if(pattern2.findFirstIn(str)!=None){
            false
          }else if(pattern3.findFirstIn(str)!=None){
            false
          }else{
            true
          }
         }
    

    //将filteredLogRDD转换为数组
    val logArray=filteredLogRDD.toArray()

    //定义正则表达式pattern,用于识别Query_time
    val pattern="# Query_time:".r 

    //定义数组KV_Array,用于存放循环映射后的tuple,tuple为(query_time所在行,sql_text)
    val KV_Array=ArrayBuffer[(String,String)]()
          for (i<-0 until logArray.length){
             if(pattern.findFirstIn(logArray(i))!=None){
               val key=logArray(i)
               var flag=true 
               var value=""
               if(i<logArray.length-1){
                 for(k<-i+1 until logArray.length if flag ){
                   if(pattern.findFirstIn(logArray(k))!=None){
                     flag=false
                   }else{
                     value=value+logArray(k)
                   }
                 } 
               }
               KV_Array+=((key,value))
             }
           }

     //并行化集合获取KV_RDD
     val KV_RDD=sc.parallelize(KV_Array, 1)

     //执行map,将KV_RDD映射为(execute_time,sql_text)的tuple类RDD time_sql_RDD
     val sql_time_RDD=KV_RDD
         .map{tuple=>
             val timeSplit=tuple._1.split(" ")
             //注意这里是toDouble,不是toInt!!!!因为日志中的时间是Double类型!!!!
             (tuple._2,timeSplit(2).toDouble)
         }

     

     val groupBySqlRDD=sql_time_RDD.groupByKey()
         .map{tuple=>
             val timeArray=tuple._2.toArray
             var totalTime=0.0
             for(i<-0 until timeArray.length){
               totalTime=totalTime + timeArray(i)
             }
             val avgTime=totalTime/timeArray.length
             (tuple._1,avgTime)
         }

     val sortedRowRDD=groupBySqlRDD
         .map{tuple=>(tuple._2,tuple._1)}
         .sortByKey(false, 1)
         .map{tuple=>Row(tuple._2,tuple._1)}
     val top10Array=sortedRowRDD.take(10)
     val top10RDD=sc.parallelize(top10Array, 1)
     //将sortedRDD转换为dataframe 
     val structType=new StructType(Array(
           StructField("sql_text",StringType,true),
           StructField("executed_time",DoubleType,true)
           )
         )
     val top10DF=hiveContext.createDataFrame(top10RDD, structType) 
     hiveContext.sql("drop table if exists sql_top10")
     top10DF.saveAsTable("sql_top10")
  }
}

将代码打成jar包并上传至linux
step 2 编写执行脚本
analyzeSlowLog.sh:

/var/software/spark-1.5.1-bin-hadoop2.4/bin/spark-submit \
--class cn.spark.study.sql.SlowLogAnalyze \
--num-executors 3 \
--driver-memory 100m \
--executor-memory 100m \
--executor-cores 3 \
--files /var/software/hive/conf/hive-site.xml \
--driver-class-path /var/software/hive/lib/mysql-connector-java-5.1.17.jar \
/var/software/spark_study/scala/SlowLogAnalyze.jar

step 3 执行analyzeSlowLog.sh,并进入hive查看分析结果:
hive> show tables;
OK
daily_top3_keyWords_uvs
Good_students
sql_top10 -- 这张表就是scala程序中定义的表名,程序运行时会在hive中创建
student_infos
student_scores
Time taken: 0.042 seconds, Fetched: 5 row(s)

查看sql_top10中的内容:
这里由于长度限制,截断了sql文本,所以看起来部分sql是一样的,实际是两条不同的sql(where 条件不同)。
hive> select substr(sql_text,1,50),executed_time from sql_top10;
Total jobs = 1
Launching Job 1 out of 1
Number of reduce tasks is set to 0 since there's no reduce operator
...
Execution completed successfully
MapredLocal task succeeded
OK
select 'true' as QUERYID, ID_GARAG 0.0252804
select count() from pms_garage_vitri_info 0.0048902
select count(
) from infORMation_schema.PROCESSLIS 3.626E-4
select 'true' as QUERYID, e_survey 2.39E-4
select 'true' as QUERYID, e_survey 2.34E-4
SELECT account_code AS um 2.2360000000000001E-4
select 'true' as QUERYID, e_survey 2.19E-4
select 'true' as QUERYID, e_survey 2.18E-4
select 'true' as QUERYID, e_survey 2.15E-4
SELECT account_code AS um 2.1419999999999998E-4
Time taken: 8.501 seconds, Fetched: 10 row(s)

至此,对mysql slow.log的提取完毕!

关于在mysql中创建相关视图的思考:
hadoop和spark一般用于处理大数据,这里用来处理mysql的慢日志实在是大材小用。不过,要想在mysql中提供查看数据库top sql的v$Topsql视图,对slow.log的实时分析是必须的,此时,spark streaming便可派上用场。
思路如下:
1.编写crontab定时任务以定时拷贝slow.log至hdfs
2.编写crontab定时任务以调用spark streaming程序分析hdfs上的最新slow.log ->通过jdbc将将top sql输出到对应mysql数据库中的v$Topsql视图中,并覆盖之前的数据。
ps:在分析slow.log时,可在程序中executor,timestamp等字段(本文中并未提取这两个字段),以提供更详细的信息。

您可能感兴趣的文档:

--结束END--

本文标题: 使用spark分析mysql慢日志

本文链接: https://www.lsjlt.com/news/40589.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 使用spark分析mysql慢日志
    熟悉oracle的童鞋都知道,在oracle中,有很多视图记录着sql执行的各项指标,我们可以根据自己的需求编写相应脚本,从oracle中获取sql的性能开销。作为开源数据库,mysql不比oracle,分...
    99+
    2022-10-18
  • 性能分析之MySQL慢查询日志分析(慢查询日志)
    一、背景            MySQL的慢查询日志是MySQL提供的一种日志记录,他用来记录在MySQL中响应的时间超过阈值的语句,具体指运行时间超过long_query_time(默认是10秒)值的SQL,会被记录到慢查询日志中。  ...
    99+
    2023-10-20
    mysql 数据库 慢日志分析 性能优化 慢查询日志
  • MySQL慢查询日志举例分析
    这篇文章主要介绍“MySQL慢查询日志举例分析”,在日常操作中,相信很多人在MySQL慢查询日志举例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MySQL慢查询日志举例...
    99+
    2022-10-19
  • MySQL慢日志查询实例分析
    本篇内容介绍了“MySQL慢日志查询实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、慢查询日志概...
    99+
    2022-10-19
  • mysql慢查询和错误日志分析
    mysql慢查询和错误日志分析和告警查看比较麻烦,目前的慢查询告警都是仅仅反应慢查询数量的。 我们做了一个慢查询日志告警和分析的程序 后台使用filebeat日志文件托运工具,将日志传输到redis数据库。...
    99+
    2022-10-18
  • Mysql通用查询日志和慢查询日志的示例分析
    小编给大家分享一下Mysql通用查询日志和慢查询日志的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!MySQL中的日志包...
    99+
    2022-10-18
  • 使用logrotate工具切割MySQL日志与慢日志分析发送到邮箱
    1.安装logrotate与percona-toolkityum install logrotate -yyum install https://www.percona.com/redir/download...
    99+
    2022-10-18
  • 【MySQL】数据库慢查询日志分析--Lepus
    [root@wallet04 ~]# wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm [root@wa...
    99+
    2022-10-18
  • 【MYSQL高级】Mysql找出执行慢的SQL【慢查询日志使用与分析】
    文章目录 分析慢SQL的步骤慢查询日志(定位慢sql)基本介绍慢查询日志是什么?特别说明 查看慢查询日志是否开以及如何开启设置慢SQL的时间阈值查看阈值设置阈值 查询慢查询日志文件...
    99+
    2023-09-18
    mysql sql adb
  • MySQL慢日志分析工具pt-query-digest怎么用
    小编给大家分享一下MySQL慢日志分析工具pt-query-digest怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、...
    99+
    2022-10-18
  • MySQL中如何启用并分析慢查询日志
    MySQL中如何启用并分析慢查询日志,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Mysql有一...
    99+
    2022-10-18
  • MySQL慢日志查询分析方法与工具
    MySQL中的日志包括:错误日志、二进制日志、通用查询日志、慢查询日志等等。这里主要介绍下比较常用的两个功能:通用查询日志和慢查询日志。 1)通用查询日志:记录建立的客户端连接和执行的语句。 2)慢查询日志:记录所有执行时间超过long...
    99+
    2017-05-29
    MySQL慢日志查询分析方法与工具
  • MySQL慢日志优化的案例分析过程
    这期内容当中小编将会给大家带来有关MySQL慢日志优化的案例分析过程,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。最近在分析一个问题的时候,...
    99+
    2022-10-18
  • MySQL优化之慢查询日志实例分析
    本篇内容主要讲解“MySQL优化之慢查询日志实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MySQL优化之慢查询日志实例分析”吧!一、慢查询日志概念对于SQL和索引的优化问题,我们会使用...
    99+
    2023-07-02
  • mysql日志分析
    由于日志文件是掌握数据库运行状态的重要参考,因此日志文件的维护也有十分重要的意义。 mysql的日志类型有二进制日志,错误日志,通用日志,慢查询日志。 模块中添加日志分析log-bin=mysql_b...
    99+
    2022-10-18
  • MySQL SQL性能分析之慢查询日志、explain使用详解
    目录SQL执行频率慢查询日志profileexplainSQL执行频率 mysql 客户端连接成功后,通过 show [session|global] status 命令可以提供服务器状态信息。通过如下指令,可以查看当前...
    99+
    2023-04-14
    MySQL 慢查询日志 MySQL explain使用
  • MySQL SQL性能分析之慢查询日志、explain使用详解
    目录SQL执行频率慢查询日志profileexplainSQL执行频率 MySQL 客户端连接成功后,通过 show [session|global] status 命令可以提供服务...
    99+
    2023-05-16
    MySQL 慢查询日志 MySQL explain使用
  • mysql 开启慢查询及其用mysqldumpslow做日志分析
    mysql慢查询日志是mysql提供的一种日志记录,它是用来记录在mysql中相应时间超过阈值的语句,就是指运行时间超过long_query_time值的sql,会被记录在慢查询日志中。long_query...
    99+
    2022-10-18
  • MySQL慢查询日志不打印的示例分析
    这篇文章给大家分享的是有关MySQL慢查询日志不打印的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 测试环境修改 long_query_t...
    99+
    2022-10-18
  • Spark网站日志过滤分析实例讲解
    目录日志过滤日志分析日志过滤 对于一个网站日志,首先要对它进行过滤,删除一些不必要的信息,我们通过scala语言来实现,清洗代码如下,代码要通过别的软件打包为jar包,此次实验所用需...
    99+
    2023-02-01
    Spark日志分析 Spark日志过滤
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作