数据库选型之MySQL(固态硬盘)
刘勇 Email: lyssym@sina.com
本博客记录作者在工作与研究中所经历的点滴,一方面给自己的工作与生活留下印记,另一方面若是能对大家有所帮助,则幸甚至哉矣!
简介
鉴于高频中心库task(核心业务处理与存储逻辑)部分占用机器较多,为节省成本,调研数据库或缓存,以期满足高频生产的需求:1)峰值1w条/s;2)峰值60w条/m。本着节省成本的角度,本文对开源、免费的数据库MySQL在固态硬盘下从事务处理条目下展开测试,测试目标平均写入速率达10000条/s 以上则能满足要求。
测试环境
硬件环境
10.1.120.34:Intel Core I5-4590, 主频:3.30G, 内存:16G, 有固态硬盘
软件环境:
10.1.120.34: Cent OS 6.5, MySQL 5.6.26 (社区版)
表结构:
DROP TABLE IF EXISTS `transaction`;
CREATE TABLE `transaction` (
`tradedate` datetime DEFAULT NOT NULL,
`symbol` varchar(6) DEFAULT NOT NULL,
`symbolname` varchar(8) DEFAULT NOT NULL,
`trdmintime` varchar(6) DEFAULT NOT NULL,
`startprice` decimal(9,3) DEFAULT NOT NULL,
`highprice` decimal(9,3) DEFAULT NOT NULL,
`lowprice` decimal(9,3) DEFAULT NOT NULL,
`endprice` decimal(9,3) DEFAULT NOT NULL,
`change` decimal(9,3) DEFAULT NOT NULL,
`changeratio` decimal(6,3) DEFAULT NOT NULL,
`minvolume` decimal(10,0) DEFAULT NOT NULL,
`minamout` decimal(16,3) DEFAULT NOT NULL,
`unix` bigint(20) DEFAULT NOT NULL,
`market` varchar(3) DEFAULT NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
table transaction
配置文件:即数据库配置文件,见/etc/my.cnf
# read_rnd_buffer_size = 2M
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
innodb_flush_log_at_trx_commit = 2
innodb_autoinc_lock_mode = 2
query_cache_type = 1
query_cache_size = 20M
innodb_buffer_pool_size = 2G
innodb_flush_method = O_DSYNC
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
my.cnf
性能测试
事务处理
针对高频生产的应用需求,本文构造高频中心库系统的数据结构,从事物处理角度,对本地节点MySQL进行写入操作,分别存储数据量为60K、100K、600K条数据,对其速率进行测试。需要指出,由于常见I/O访问的瓶颈主要受限于写入测试,本文只针对写入操作进行测试,暂不考虑读取操作或者混合读写方式,若写入操作不满足要求,其它操作无需测试。
本文采用写入多条数据执行事务处理。因为10.1.120.34上采用固态硬盘作为存储介质,其安装有MySQL,根据应用场景,第一种从远程访问,即测试主机10.1.25.50访问MySQL,第二种从本地访问10.1.120.34访问MySQL。以下分别从事务处理条目为1000、2000和3000下展开测试。
以1000条数据为基础执行事务处理,结果见表-1。
表-1 1000条下事务处理MySQL测试结果
节点 |
数据库IP |
数据量(K) |
平均写入速率(条/s) |
远程节点 | 10.1.120.34 | 60 | 2328 |
远程节点 | 10.1.120.34 | 100 | 2366 |
远程节点 | 10.1.120.34 | 600 | 2372 |
本地节点 | 10.1.120.34 | 60 | 14936 |
本地节点 | 10.1.120.34 | 100 | 16526 |
本地节点 | 10.1.120.34 | 600 | 21169 |
以2000条数据为基础执行事务处理,结果见表-2。
表-2 2000条下事务处理MySQL测试结果
节点 |
数据库IP |
数据量(K) |
平均写入速率(条/s) |
远程节点 | 10.1.120.34 | 60 | 2318 |
远程节点 | 10.1.120.34 | 100 | 2333 |
远程节点 | 10.1.120.34 | 600 | 2320 |
本地节点 | 10.1.120.34 | 60 | 12714 |
本地节点 | 10.1.120.34 | 100 | 17914 |
本地节点 | 10.1.120.34 | 600 | 20214 |
以3000条数据为基础执行事务处理,结果见表-3。
表-3 3000条下事务处理MySQL测试结果
节点 |
数据库IP |
数据量(K) |
平均写入速率 (条/s) |
远程节点 | 10.1.120.34 | 60 | 2319 |
远程节点 | 10.1.120.34 | 100 | 2377 |
远程节点 | 10.1.120.34 | 600 | 2429 |
本地节点 | 10.1.120.34 | 60 | 11202 |
本地节点 | 10.1.120.34 | 100 | 17587 |
本地节点 | 10.1.120.34 | 600 | 18577 |
小结
从表1-3可知:1)在远程节点访问MySQL,即使采用固态硬盘,其速率还是较慢,无法满足需求;2)在本地节点,访问MySQL,则能够满足高频生产的需求。
批处理
为比较批处理方式和事务处理方式的性能,本文针对其进行比较测试。
每1000条数据,执行一次批处理,测试结果如表-4。
表-4 1000条下批处理与事务处理MySQL测试结果
方式 |
数据库IP |
数据量(K) |
平均写入速率(条/s) |
批处理 | 10.1.120.34 | 60 | 15974 |
批处理 | 10.1.120.34 | 100 | 16328 |
批处理 | 10.1.120.34 | 600 | 17633 |
事务处理 | 10.1.120.34 | 60 | 14936 |
事务处理 | 10.1.120.34 | 100 | 16526 |
事务处理 | 10.1.120.34 | 600 | 21169 |
每2000条数据,执行一次批处理,测试结果如表-5。
表-5 2000条下批处理与事务处理MySQL测试结果
方式 |
数据库IP |
数据量(K) |
平均写入速率(条/s) |
批处理 | 10.1.120.34 | 60 | 14840 |
批处理 | 10.1.120.34 | 100 | 16310 |
批处理 | 10.1.120.34 | 600 | 17364 |
事务处理 | 10.1.120.34 | 60 | 12714 |
事务处理 | 10.1.120.34 | 100 | 17914 |
事务处理 | 10.1.120.34 | 600 | 20214 |
每3000条数据,执行一次批处理,测试结果如表-6。
表-6 3000条下批处理与事务处理MySQL测试结果
节点 |
数据库IP |
数据量(K) |
平均写入速率(条/s) |
批处理 | 10.1.120.34 | 60 | 14641 |
批处理 | 10.1.120.34 | 100 | 16371 |
批处理 | 10.1.120.34 | 600 | 17593 |
事务处理 | 10.1.120.34 | 60 | 11202 |
事务处理 | 10.1.120.34 | 100 | 17587 |
事务处理 | 10.1.120.34 | 600 | 18577 |
小结
从表4-6测试结果来看,在写入数据量少时,批处理方式较事务方式速率快一些,但是随着访问数据量增加,事务处理方式稍微快一些。
总结
从上述测试结果来看,以固态硬盘作为存储介质,在本地访问MySQL可以满足高频生产的需求。此外,鉴于高频生产高负载的需求,优先选择事务处理方式。
附录:
测试部分源代码:
import java.sql.Date;
import java.math.BigDecimal; public class Transaction {
private Date tradedate;
private String symbol;
private String symbolName;
private String trdmintime;
private BigDecimal startprice;
private BigDecimal highprice;
private BigDecimal lowprice;
private BigDecimal endprice;
private BigDecimal change;
private BigDecimal changeratio;
private BigDecimal minvolume;
private BigDecimal minamout;
private long unix;
private String market; public Transaction(Date tradedate,
String symbol,
String symbolName,
String trdmintime,
BigDecimal startprice,
BigDecimal highprice,
BigDecimal lowprice,
BigDecimal endprice,
BigDecimal change,
BigDecimal changeratio,
BigDecimal minvolume,
BigDecimal minamout,
long unix,
String market)
{
this.symbol = symbol;
this.symbolName = symbolName;
this.trdmintime = trdmintime;
this.startprice = startprice;
this.highprice = highprice;
this.lowprice = lowprice;
this.endprice = endprice;
this.change = change;
this.changeratio = changeratio;
this.minvolume = minvolume;
this.minamout = minamout;
this.unix = unix;
this.market = market;
} public void setTradedate(Date tradedate) {
this.tradedate = tradedate;
} public void setSymbol(String symbol) {
this.symbol = symbol;
} public void setSymbolName(String symbolName) {
this.symbolName = symbolName;
} public void setTrdmintime(String trdmintime) {
this.trdmintime = trdmintime;
} public void setStartprice(BigDecimal startprice) {
this.startprice = startprice;
} public void setHighprice(BigDecimal highprice) {
this.highprice = highprice;
} public void setLowprice(BigDecimal lowprice) {
this.lowprice = lowprice;
} public void setEndprice(BigDecimal endprice) {
this.endprice = endprice;
} public void setChange(BigDecimal change) {
this.change = change;
} public void setChangeratio(BigDecimal changeratio) {
this.changeratio = changeratio;
} public void setMinvolume(BigDecimal minvolume) {
this.minvolume = minvolume;
} public void setMinamout(BigDecimal minamout) {
this.minamout = minamout;
} public void setUnix(long unix) {
this.unix = unix;
} public void setMarket(String market) {
this.market = market;
} public Date getTradedate() {
return tradedate;
} public String getSymbol() {
return symbol;
} public String getSymbolName() {
return symbolName;
} public String getTrdmintime() {
return trdmintime;
} public BigDecimal getStartprice() {
return startprice;
} public BigDecimal getHighprice() {
return highprice;
} public BigDecimal getLowprice() {
return lowprice;
} public BigDecimal getEndprice() {
return endprice;
} public BigDecimal getChange() {
return change;
} public BigDecimal getChangeratio() {
return changeratio;
} public BigDecimal getMinvolume() {
return minvolume;
} public BigDecimal getMinamout() {
return minamout;
} public long getUnix() {
return unix;
} public String getMarket() {
return market;
} }
Class Transcation
import java.sql.*;
import java.math.BigDecimal;
import java.math.RoundingMode; public class Test {
public static int PREFIX = 1000; // 批处理量
public static int FIX = 600; // 操作数据 K
private Connection conn;
private PreparedStatement pstm;
private String sql;
private int count; public static void main(String[] args) {
// TODO Auto-generated method stub Transaction ts = new Transaction(null,
"",
"",
"010000",
new BigDecimal(15.857).setScale(3, RoundingMode.HALF_UP),
new BigDecimal(18.550).setScale(3, RoundingMode.HALF_UP),
new BigDecimal(13.147).setScale(3, RoundingMode.HALF_UP),
new BigDecimal(16.383).setScale(3, RoundingMode.HALF_UP),
new BigDecimal(0.151).setScale(3, RoundingMode.HALF_UP),
new BigDecimal(1.550).setScale(3, RoundingMode.HALF_UP),
new BigDecimal(5000000).setScale(3, RoundingMode.HALF_UP),
new BigDecimal(500000000).setScale(3, RoundingMode.HALF_UP),
System.currentTimeMillis(),
"SSE"); Test test = new Test();
int symbolData = 100000;
test.initMySQL(); long start = test.getRunTime();
for(int i = 0; i < Test.FIX*1000; i++) {
ts.setTradedate(new Date(System.currentTimeMillis()));
ts.setSymbol(Integer.toString(symbolData));
symbolData++ ;
ts.setSymbolName("中国银行");
ts.setUnix(ts.getUnix()+1);
test.insertData(ts);
}
long end = test.getRunTime();
System.out.println("写入速率为: " + Test.FIX*1000*1000/(end-start)); test.down();
} public void initMySQL()
{
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://10.1.120.34:3306/hdfs";
String user = "root";
String password = ""; try {
Class.forName(driver);
conn = DriverManager.getConnection(url, user, password);
if (!conn.isClosed())
System.out.println("Start MySQL!");
} catch (Exception e) {
e.printStackTrace();
} count = 0;
sql = "insert into transaction" + " values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
try {
pstm = conn.prepareStatement(sql);
conn.setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
} public void insertData(Transaction ts)
{
try {
pstm.setDate(1, ts.getTradedate());
pstm.setString(2, ts.getSymbol());
pstm.setString(3, ts.getSymbolName());
pstm.setString(4, ts.getTrdmintime());
pstm.setBigDecimal(5, ts.getStartprice());
pstm.setBigDecimal(6, ts.getHighprice());
pstm.setBigDecimal(7, ts.getLowprice());
pstm.setBigDecimal(8, ts.getEndprice());
pstm.setBigDecimal(9, ts.getChange());
pstm.setBigDecimal(10, ts.getChangeratio());
pstm.setBigDecimal(11, ts.getMinvolume());
pstm.setBigDecimal(12, ts.getMinamout());
pstm.setLong(13, ts.getUnix());
pstm.setString(14, ts.getMarket()); pstm.executeUpdate();
count++;
if (count == Test.PREFIX) {
conn.commit();
conn.setAutoCommit(false);
count = 0;
} } catch (SQLException e) {
try {
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
} public long getRunTime()
{
return System.currentTimeMillis();
} public void down()
{
try {
if (!conn.isClosed()) {
conn.close();
System.out.println("Close MySQL!");
}
} catch (Exception e) {
e.printStackTrace();
}
} }
Class Test
作者:志青云集
出处:http://www.cnblogs.com/lyssym
如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
如果,您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是【志青云集】。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
数据库选型之MySQL(固态硬盘)的更多相关文章
- 数据库选型之MySQL(普通硬盘)
刘勇 Email:lyssym@sina.com 本博客记录作者在工作与研究中所经历的点滴,一方面给自己的工作与生活留下印记,另一方面若是能对大家有所帮助,则幸甚至哉矣! 简介 鉴于高频中心库ta ...
- 数据库选型之MySQL(多线程并发)
刘勇 Email: lyssym@sina.com 本博客记录作者在工作与研究中所经历的点滴,一方面给自己的工作与生活留下印记,另一方面若是能对大家有所帮助,则幸甚至哉矣! 简介 鉴于高频中心库 ...
- 论 数据库 B Tree 索引 在 固态硬盘 上 的 离散存储
传统的做法 , 数据库 的 B Tree 索引 在 磁盘上是 顺序存储 的 , 这是考虑到 磁盘 机械读写 的 特性 . 实际上 , B Tree 是一个 树形结构 , 可以采用 链式 存储 , 就是 ...
- 基于SSD固态硬盘的数据库性能优化
基于SSD固态硬盘的数据库性能优化 2010-11-08 00:0051cto佚名 关键字:固态硬盘 数据库管理 SSD 企业软件热点文章 Java内存结构与模型结构分析 Oracle触发器的语法 ...
- 数据库选型之内存数据库eXtremeDB
刘勇 Email:lyssym@sina.com 简介 鉴于内存数据库访问速率快的特点,本文分别从单线程.多线程(并发访问)和多线程读/写混合访问角度对eXtremeDB数据库读写速率展开测试. ...
- nosql数据库选型
http://blogread.cn/it/article/6654 今天在书店里翻完了一遍<七天七数据库>.这本书简单介绍了postgreSQL,riak,mongodb,HBase,r ...
- {MySQL数据库初识}一 数据库概述 二 MySQL介绍 三 MySQL的下载安装、简单应用及目录介绍 四 root用户密码设置及忘记密码的解决方案 五 修改字符集编码 六 初识sql语句
MySQL数据库初识 MySQL数据库 本节目录 一 数据库概述 二 MySQL介绍 三 MySQL的下载安装.简单应用及目录介绍 四 root用户密码设置及忘记密码的解决方案 五 修改字符集编码 六 ...
- 固态硬盘和机械硬盘的比较和SQLSERVER在两种硬盘上的性能差异
固态硬盘和机械硬盘的比较和SQLSERVER在两种硬盘上的性能差异 在看这篇文章之前可以先看一下下面的文章: SSD小白用户收货!SSD的误区如何解决 这样配会损失性能?实测6种特殊装机方式 听说固态 ...
- 重新学习MySQL数据库3:Mysql存储引擎与数据存储原理
重新学习Mysql数据库3:Mysql存储引擎与数据存储原理 数据库的定义 很多开发者在最开始时其实都对数据库有一个比较模糊的认识,觉得数据库就是一堆数据的集合,但是实际却比这复杂的多,数据库领域中有 ...
随机推荐
- Codeforces Round #304 (Div. 2) B. Soldier and Badges 水题
B. Soldier and Badges Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/54 ...
- PAT甲级1021. Deepest Root
PAT甲级1021. Deepest Root 题意: 连接和非循环的图可以被认为是一棵树.树的高度取决于所选的根.现在你应该找到导致最高树的根.这样的根称为最深根. 输入规格: 每个输入文件包含一个 ...
- Java乱码解决
简述 乱码是JAVA开发时经常遇到的问题.主要出现在四种情况: 1. 系统接口之间 2. POST提交数据 3. GET提交数据和URL路径 4. ...
- (转)资源监控工具Spotlight监测LINUX
个人1.安装spotlight,Spotlight on Unix2.配置spotlight,注意spotlight默认不能使用root用户进行连接,需要用户自己创建一个具有root权限的用户.(1) ...
- ExtJS表格——行号、复选框、选择模型
本篇的内容是为表格添加行号,和复选框,最后谈一下Ext的选择模型.内容比较简单,就直接上代码了.一. 设置行号 行号的设置主要问题在于删除某一行后需要重新计算行号 Ext.onReady(fun ...
- 使用Dragablz快速构建Chrome样式的可拖拽分离的Tab页程序
今天发现了一个可以快速实现类似于Chrome方式的可拖拽分离的Tab页程序Dragablz.它可以实现动态创建,删除Tab页,并支持拖拽后形成独立窗口和窗口合并. 使用起来还是非常方便的. < ...
- mysql数据库测试库下载
The mysqlslap program can be helpful for simulating a high load produced by multiple clients issuing ...
- 如何使用Omnifocus做时间管理 4 多项目管理
这一篇和大家分享作为一个管理者,可能遇到的时间管理挑战和如何用omnifocus应对这些挑战. 张经理在一家IT公司上班,从程序员开始打拼了5年,凭借权威的技术能力当上了项目经理,同时管理三个项目,苦 ...
- Linux进程间通信:管道,信号量,消息队列,信号,共享内存,套接字
Linux下的进程通信手段基本上是从UNIX平台上的进程通信手段继承而来的.而对UNIX发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间 ...
- #pragma详细解释(一)
#pragma详细解释 #pragma详细解释(一) 2010-04-18 14:21:00| 分类: 默认分类 | 标签: |字号大中小订阅 在#Pragma是预处理指令它的作用是设定编 ...