ehcache + mysql例子与性能测试

最近用到了ehcache,根据从网上搜集的资料,调试了一个小例子,顺带做了性能测试。cache的效率的确很高,较sql直接查询性能上升近8000倍。

第一步:先在mysql环境中建好TEST,

CREATE TABLE TEST ( 
    TEST_ID         bigint(20)  ,
    TEST_NAME         varchar(50),
    TEST_TIME       timestamp default CURRENT_TIMESTAMP,
    TEST_VALUE      decimal(10,3)  
)

表结构如下

mysql> describe TEST;
+------------+---------------+------+-----+-------------------+-----------------------------+
| Field      | Type          | Null | Key | Default           | Extra                       |
+------------+---------------+------+-----+-------------------+-----------------------------+
| TEST_ID    | bigint(20)    | YES  |     | NULL              |                             |
| TEST_NAME  | varchar(50)   | YES  |     | NULL              |                             |
| TEST_TIME  | timestamp     | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| TEST_VALUE | decimal(10,3) | YES  |     | NULL              |                             |
+------------+---------------+------+-----+-------------------+-----------------------------+
4 rows in set (0.11 sec)

第二步,建java工程,建立与TEST表对应bean,

import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.*;

public class TEST implements Serializable {
    private static final long serialVersionUID = 1L;
    public Long TEST_ID;
    public String TEST_NAME;
    public Timestamp TEST_TIME;
    public BigDecimal TEST_VALUE;
    @Override
    public String toString() {
        return String.format("ID:%s,,,NAME:%s", TEST_ID, TEST_NAME);
    }
}

Util类代码如下:

import java.util.Random;

public class Util{

    public static Random rand = new Random();
    public static String atoz = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    public static String genString(int length) {
        StringBuilder re = new StringBuilder(length);
        re.append(atoz.charAt(rand.nextInt(52)));
        for (int i = 0; i < length; i++) {
            re.append(atoz.charAt(rand.nextInt(62)));
        }
        return re.toString();
    }

    public static double genDouble() {
        double d1 = 5120 * rand.nextDouble();
        double d2 = 1024000 * rand.nextDouble();
        return d1 + d2;
    }
}

主程序:

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.HashMap;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;


public class Main {

    private static String dbURL="jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=GBK";
    private static String user="root";
    private static String pass="beautiful_mm";
    private static String dbDriver="com.mysql.jdbc.Driver";
    private static String FORMAT="yyyy-MM-dd HH:mm:ss";
    private static SimpleDateFormat dateFormat=new SimpleDateFormat(FORMAT);
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        CacheManager manager = CacheManager.create("./src/main/resources/ehcache.xml");
        Cache demo = manager.getCache("demoCache");
        if(null==manager)
        {System.out.println("manager is null? can not get ehcache manager");}
        else
        {System.out.println("get ehcache manager succeed!");}
        try {
        // 插入10W数据,以备测试
traditionalInsert(
100000); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } try { ehcache(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } Cache cid = manager.getCache("TEST_ID.TEST"); long begin = System.currentTimeMillis(); for(int i=1;i<10001;i++) { Element e5120 = cid.get(new Long(i)); } long end1 = System.currentTimeMillis(); System.out.println("从cache中查询10000条数据消耗时间: " + (end1-begin)); for(int i=1;i<10001;i++) { try { getRecord(i); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } long end2 = System.currentTimeMillis(); System.out.println("用sql查询10000条数据消耗时间: " + (end2-end1)); } public static HashMap<Long, TEST> simpleCache() throws Exception { HashMap<Long, TEST> cacheid = new HashMap<Long, TEST>(); Class.forName(dbDriver); Connection conn = DriverManager.getConnection(dbURL, user, pass); try { long begin = System.currentTimeMillis(); Statement s = conn.createStatement(); String sql = "SELECT TEST_ID,TEST_NAME,TEST_TIME,TEST_VALUE FROM TEST"; ResultSet querySet = s.executeQuery(sql); for (int i = 1; querySet.next(); i++) { TEST curr = new TEST(); curr.TEST_ID = querySet.getLong(1); curr.TEST_NAME = querySet.getString(2); curr.TEST_TIME = querySet.getTimestamp(3); curr.TEST_VALUE = querySet.getBigDecimal(4); cacheid.put(curr.TEST_ID, curr); } long end = System.currentTimeMillis(); System.out.printf("Time:%d\n", (end - begin)); } catch (Exception ex) { ex.printStackTrace(); } finally { conn.close(); } return cacheid; } public static void traditionalInsert(int total) throws Exception { Thread.sleep(3000); Timestamp current = new Timestamp(System.currentTimeMillis()); String currentStr = dateFormat.format(current); System.out.println(currentStr); Connection conn = DriverManager.getConnection(dbURL, user, pass); try { long begin = System.currentTimeMillis(); conn.setAutoCommit(false); String sql = "INSERT INTO TEST (TEST_ID,TEST_NAME,TEST_TIME,TEST_VALUE) VALUES (?, ?, ?, ?)"; PreparedStatement ps = conn.prepareStatement(sql); for (int i = 1; i <= total; i++) { ps.setLong(1, i); ps.setString(2, Util.genString(33)); ps.setTimestamp(3, current); ps.setBigDecimal(4, new BigDecimal(Util.genDouble())); ps.addBatch(); if ((i % 500) == 0) { ps.executeBatch(); } } ps.executeBatch(); System.out.println("insert !! done"); conn.commit(); long end = System.currentTimeMillis(); System.out.printf("Count:%d Time:%d\n", total, (end - begin)); } catch (Exception ex) { ex.printStackTrace(); conn.rollback(); } finally { conn.close(); } } public static void ehcache() throws Exception { CacheManager manager = CacheManager.create("./src/main/resources/ehcache.xml"); manager.addCache("TEST_ID.TEST"); Cache cid = manager.getCache("TEST_ID.TEST"); Class.forName(dbDriver); Connection conn = DriverManager.getConnection(dbURL, user, pass); try { long begin = System.currentTimeMillis(); Statement s = conn.createStatement(); String sql = "SELECT TEST_ID,TEST_NAME,TEST_TIME,TEST_VALUE FROM TEST"; ResultSet querySet = s.executeQuery(sql); for (int i = 1; querySet.next(); i++) { TEST curr = new TEST(); curr.TEST_ID = querySet.getLong(1); curr.TEST_NAME = querySet.getString(2); curr.TEST_TIME = querySet.getTimestamp(3); curr.TEST_VALUE = querySet.getBigDecimal(4); cid.put(new Element(curr.TEST_ID, curr)); } long end = System.currentTimeMillis(); System.out.printf("ehcache cost Time:%d\n", (end - begin)); } catch (Exception ex) { ex.printStackTrace(); } finally { conn.close(); } } public static TEST getRecord(int id) throws Exception { TEST ret = null; Class.forName(dbDriver); Connection conn = DriverManager.getConnection(dbURL, user, pass); try { long begin = System.currentTimeMillis(); Statement s = conn.createStatement(); String sql = "SELECT TEST_ID,TEST_NAME,TEST_TIME,TEST_VALUE from TEST where TEST_ID="+id; ResultSet querySet = s.executeQuery(sql); for (int i = 1; querySet.next(); i++) { TEST curr = new TEST(); curr.TEST_ID = querySet.getLong(1);; curr.TEST_NAME = querySet.getString(2); curr.TEST_TIME = querySet.getTimestamp(3); curr.TEST_VALUE = querySet.getBigDecimal(4); return curr; // cid.put(new Element(curr.TEST_ID, curr)); } long end = System.currentTimeMillis(); System.out.printf("ehcache cost Time:%d\n", (end - begin)); } catch (Exception ex) { ex.printStackTrace(); } finally { conn.close(); } return ret; } }

最终运行结果:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
get ehcache manager succeed!
2012-11-25 22:28:41
insert !! done
Count:100000 Time:14980
ehcache cost Time:5881
从cache中查询10000条数据消耗时间: 71
用sql查询10000条数据消耗时间: 500620 

可以看出,从cache中取数据的效率较直接从DB中查高出7000倍,即使加上构建cache的时间,也胜过查库约80倍。

目前可以看出,cache的构建时间将会是大范围应用的一个瓶颈,一个应用的启动时间会因为cache构建而变的过长,这在应用中想办法处理。待后续研究。

原文地址:https://www.cnblogs.com/vigarbuaa/p/2788305.html