思路:
- 1.从presto 中找出查询慢的sql(>10s) 大约1.4w条,放入mysql 中(具体问什么会放入mysql 后面说该问题)
- 2.使用Jmeter 连接 presto 进行查询 ,查询sql从mysql中随机获取 ;
遇到的问题:
- 将sql放入csv文件,presto 的查询sql从csv文件中获取,发现Jmeter自带的${__CSVRead(,)} 是按行读取的 ,因为查询sql有换行,我就把csv文件中的每条sql 拉成了1行,结果又发现sql 中有注释符("--") ,这样又会有问题 注释符导致sql抛错,解决方案:就放入mysql 当中了 (当然放入excel中也是可以的,这样的话就的使用python/java 写读取excel方法了 然后打包再放入Jmeter 的lib 比较麻烦 我就懒得写了 );
- Jmeter 获取到 从mysql 中的sql 后 返回的是"[{query_sql=select ...}]" 这种结果,而且sql 中有 双引号(")和 换行符号( )在Jmeter 的BeanShell 中都会抛错 ,然后我就通过sql 将这些字符给进行了处理 (因为在Jmeter 中无法直接通过beanshell 处理sql中的换行符和双引号,就选择直接处理原始SQL了 );
- 同样的sql 通过 DBeaver 连接 presto 是可以查询成功的,但在 Jmeter 中的 JDBC Request 组件中查询提示 : "Error executing query " ,后来通过百度 得知是 presto-jdbc jar 包的版本不匹配导致的 ;
- presto 查询时部分sql 返回结果集比较大 导致 jmeter 内存溢出,为了解决这个问题,使用dml 语句批量在末尾添加 limit 10,如果在csv 、excel 文件中这种批量操作就不好进行 ;
将csv文件写入mysql:
1 import com.opencsv.CSVReader; 2 import java.io.FileInputStream; 3 import java.io.InputStreamReader; 4 import java.nio.charset.StandardCharsets; 5 import java.sql.*; 6 public class prestoRl { 7 static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; 8 static final String DB_URL = "jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai"; 9 static final String USER = "root"; 10 static final String PASS = "123"; 11 public static void main(String[] args) { 12 Connection conn = null; 13 Statement stmt = null; 14 try{ 15 Class.forName(JDBC_DRIVER); 16 conn = DriverManager.getConnection(DB_URL,USER,PASS); 17 conn.setAutoCommit(false); 18 stmt = conn.createStatement(); 19 String str = "INSERT t_prestoRl VALUES (?,?,?,?,?,?,?)"; 20 PreparedStatement ps = null; 21 ps = conn.prepareStatement(str); 22 23 FileInputStream fis = new FileInputStream("D:/linbo.yang/bigData/prestoLR/aa/20210924.csv"); 24 InputStreamReader isr = new InputStreamReader(fis,StandardCharsets.UTF_8); 25 CSVReader reader = new CSVReader(isr); 26 String[] nextLine; 27 int i =0 ; 28 int index=0 ; 29 while ((nextLine = reader.readNext()) != null) { 30 31 i++ ; 32 index++; 33 String query_user=nextLine[0] ; 34 String start_time=nextLine[1] ; 35 String query_sql=nextLine[2] ; 36 String elapsed_time_s=nextLine[3] ; 37 // System.out.println(query_user+'|'+start_time+'|'+query_sql+'|'+elapsed_time_s); 38 ps.setString(1,String.valueOf(index)); 39 ps.setString(2,query_user); 40 ps.setString(3,start_time); 41 ps.setString(4,query_sql); 42 ps.setString(5,elapsed_time_s); 43 ps.setString(6,null); 44 ps.setString(7,null); 45 ps.addBatch(); 46 if (i == 1000) { 47 i=0; 48 ps.executeBatch(); 49 conn.commit(); 50 } 51 } 52 conn.commit(); 53 stmt.close(); 54 ps.close(); 55 conn.close(); 56 }catch(SQLException se){ 57 se.printStackTrace(); 58 }catch(Exception e){ 59 e.printStackTrace(); 60 }finally{ 61 try{ 62 if(stmt!=null) stmt.close(); 63 }catch(SQLException se2){ 64 } 65 try{ 66 if(conn!=null) conn.close(); 67 }catch(SQLException se){ 68 se.printStackTrace(); 69 } 70 } 71 72 } 73 74 }
将 SQL 中的换行符和双引号处理掉:
1 UPDATE t_prestoRl 2 SET query_sql=REPLACE(query_sql,' ','\n ') 3 WHERE instr(query_sql,' ')>0 4 5 6 UPDATE t_prestoRl 7 SET query_sql=REPLACE(query_sql,'"','\" ') 8 WHERE instr(query_sql,'"')>0
View Code
通过jmeter 测试presto select 压力测试 :
1.添加Jmeter JDBC Connection Configuration 组件;
>a.下载驱动: (https://prestodb.github.io/docs/current/installation/jdbc.html) 注意:要和 presto 的版本对应 ;我的版本是338 我用的是(presto-jdbc-338.jar)
>b.连接参数 和 可选参数 , 查看截图 ;