使用MYSQL的INNODB实现任务分发机制
最近公司有个项目,需要多并发完成任务,也就是一个任务控制中心控制多个WORKER的问题,这里的核心点在于如果WORKER_A正在执行1号任务,任务中心不能让WORKER_B重复执行1号任务,即WORKER_A和WORKER_B同时来任务中心需要互斥。
咱们的解决方案是使用MYSQL的INNODB行锁机制完成这项工作,即使用MYSQL来充当任务中心的角色。相关参考:SELECT FOR UPDATE原理。
一、创建数据表: test
CREATE TABLE `test` (
`unit_id` int() NOT NULL AUTO_INCREMENT,
`style` int() NOT NULL DEFAULT '',
PRIMARY KEY (`unit_id`)
) ENGINE=InnoDB AUTO_INCREMENT= DEFAULT CHARSET=utf8
二、插入测试数据
......
三、程序:
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.Statement; public class Jdbc {
public static void main(String[] args) throws Exception {
Connection conn = null;
String sql;
String url = "jdbc:mysql://10.235.160.137:3306/lz_main?" + "user=lzstat&password=711TJS&useUnicode=true&characterEnco
ding=UTF8"; try {
Class.forName("com.mysql.jdbc.Driver");// 动态加载mysql驱动 conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement();
int i = 0, result = -1;
String id = "";
while (i<1000000) {
i = i+1;
//查找等待执行的数据
sql = "SELECT unit_id as id,style FROM test WHERE style = 0 LIMIT 1";
ResultSet rs = stmt.executeQuery(sql);
if (rs.next()){
id = rs.getString(1);
//锁定执行
stmt.executeUpdate("SET AUTOCOMMIT=0;");
stmt.executeUpdate("BEGIN WORK;");
sql = "SELECT unit_id as id,style FROM test WHERE unit_id = " + id + " AND style = 0 FOR UPDATE";
ResultSet rs1 = stmt.executeQuery(sql);
if (rs1.next()){
id = rs1.getString(1);
sql = "UPDATE test SET style = 1 WHERE unit_id = " + id;
stmt.executeUpdate(sql);
sql = "COMMIT;";
result = stmt.executeUpdate(sql);
if(result!=-1){
System.out.println("do things:" + id);
System.out.println(System.currentTimeMillis());
sql = "update test set style = style + 1 where unit_id = " + id;
result = stmt.executeUpdate(sql);
}
}
else{
stmt.executeUpdate("COMMIT;");
}
}else{
break;
}
}
} catch (SQLException e) {
System.out.println("MySQL操作错误");
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
conn.close();
} } }
执行:java -cp :/home/wb-liqiu/java/libs/mysql-connector-java-5.1.13.jar Jdbc。相关原理:http://www.cnblogs.com/liqiu/p/3441038.html
四、执行
在多个窗口执行这个程序,输出类似:
do things:38114
1390532207770
do things:38115
1390532207785
do things:38116
1390532207804
do things:38117
1390532207818
do things:38118
1390532207833
do things:38119
1390532207848
do things:38120
1390532207862
do things:38121
1390532207877
do things:38122
1390532207891
do things:38123
1390532207906
do things:38124
1390532207920
do things:38125
1390532207933
do things:38126
1390532207947
do things:38127
1390532207962
这样就可以统计同一秒,执行了多少任务了。
1390532370秒并发数量的命令:cat log3 | grep 1390532370 | wc -l
我测试的综合结果是:每秒QPS在60左右。如果增加WORKER,那么QPS依然在50左右徘徊,说明核心瓶颈是数据表的锁定时间
PS:问题
- QPS不能满足需要怎么办?考虑分表解决
- 如何再不增加QPS,如何完成更多的任务?一次锁定id+100行,然后update,再同时执行这些任务
使用MYSQL的INNODB实现任务分发机制的更多相关文章
- MySQL中InnoDB脏页刷新机制Checkpoint
我们知道InnoDB采用Write Ahead Log策略来防止宕机数据丢失,即事务提交时,先写重做日志,再修改内存数据页,这样就产生了脏页.既然有重做日志保证数据持久性,查询时也可以直接从缓冲池页中 ...
- mysql中innodb引擎的mvcc机制和BufferPool缓存机制
一.MVCC (1)mvcc主要undo日志版本链和read-view一致性视图来保证多事务的并发控制,mvcc是innodb的一种特殊机制,他保证了事务四大特性之一的隔离性(原子性,一致性,隔离性) ...
- MySQL数据库InnoDB存储引擎中的锁机制
MySQL数据库InnoDB存储引擎中的锁机制 http://www.uml.org.cn/sjjm/201205302.asp 00 – 基本概念 当并发事务同时访问一个资源的时候,有可能 ...
- MySQL的innoDB锁机制以及死锁处理
MySQL的nnoDB锁机制 InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.行级锁与表级锁本来就有许多不同之处,innodb正常的select ...
- MySQL的InnoDB索引原理详解
摘要 本篇介绍下Mysql的InnoDB索引相关知识,从各种树到索引原理到存储的细节. InnoDB是Mysql的默认存储引擎(Mysql5.5.5之前是MyISAM,文档).本着高效学习的目的,本篇 ...
- MySQL的InnoDB索引原理详解 (转)
摘要: 本篇介绍下Mysql的InnoDB索引相关知识,从各种树到索引原理到存储的细节. InnoDB是Mysql的默认存储引擎(Mysql5.5.5之前是MyISAM,文档).本着高效学习的目的,本 ...
- MySql中innodb存储引擎事务日志详解
分析下MySql中innodb存储引擎是如何通过日志来实现事务的? Mysql会最大程度的使用缓存机制来提高数据库的访问效率,但是万一数据库发生断电,因为缓存的数据没有写入磁盘,导致缓存在内存中的数据 ...
- [转]MySQL 表锁和行锁机制
本文转自:http://www.cnblogs.com/itdragon/p/8194622.html MySQL 表锁和行锁机制 行锁变表锁,是福还是坑?如果你不清楚MySQL加锁的原理,你会被它整 ...
- MySQL 各级别事务的实现机制
MySQL 各级别事务的实现机制在处理cnctp项目已合包裹状态同步的问题时,发现读包裹状态和对包裹状态的更新不在一个事务内,我提出是否会因为消息并发导致状态一致性问题.在和同事讨论的过程中,我们开始 ...
随机推荐
- Android Butterknife框架
Android Butterknife框架 注解攻略 时间 2014-02-27 09:28:09 Msquirrel原文 http://www.msquirrel.com/?p=95 一.原理. ...
- 错误:update 忘了加 where
职业生涯应该都犯过的错误,幸好是在开发库,生产环境的库真是要严格的进行权限管理和脚本执行流程规范.
- 猫都能学会的Unity3D Shader入门指南(二)
关于本系列 这是Unity3D Shader入门指南系列的第二篇,本系列面向的对象是新接触Shader开发的Unity3D使用者,因为我本身自己也是Shader初学者,因此可能会存在错误或者疏漏,如果 ...
- [Android Security] 反编译常用工具
copy : https://down.52pojie.cn/Tools/Disassemblers/
- ADB与AVD的常见问题
一.adb问题常用解决方法 若是模拟器启动正常,但是adb检测不到模拟器,我们给他一套不解释连招,下面教大家几招基础拳法. 1.基础拳法一:循环自动检测 下图那个小按钮,点它,狠狠的点它,然后点运行, ...
- SQLSERVER系统视图 sql server系统表详细说明
参考 https://www.cnblogs.com/luluping/archive/2012/11/05/2754639.html https://www.cnblogs.com/litubin/ ...
- arcgis server 10 for java 8399根目录是404的提示取消,并跳转到 地图目录 /arcgis/rest/services下
看了Howto: 取消ArcGIS Server 9.x for Java内置tomcat在8399端口的文件列表 http://support.esrichina-bj.cn/2009/0819/9 ...
- bat 批处理切换到当前脚本所在文件夹
bat 批处理切换到当前脚本所在文件夹 切换到当前脚本所在的文件夹 ? 1 cd %~dp0 另外附上一些bat基本内容 —————————————————————————————— 批处理常用 ...
- go语言之进阶篇json解析到结构体
1.json解析到结构体 示例: package main import ( "encoding/json" "fmt" ) type IT struct { ...
- Android实现在线更新的过程案例
一.更新软件的准备 在线更新软件的话需要我们有签名的应用,我们需要把签过名之后的软件放入到服务器中,我的如下: 其中apk是有签名的更新版本! updateinfo.html代码如下: {" ...