最近公司有个项目,需要多并发完成任务,也就是一个任务控制中心控制多个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实现任务分发机制的更多相关文章

  1. MySQL中InnoDB脏页刷新机制Checkpoint

    我们知道InnoDB采用Write Ahead Log策略来防止宕机数据丢失,即事务提交时,先写重做日志,再修改内存数据页,这样就产生了脏页.既然有重做日志保证数据持久性,查询时也可以直接从缓冲池页中 ...

  2. mysql中innodb引擎的mvcc机制和BufferPool缓存机制

    一.MVCC (1)mvcc主要undo日志版本链和read-view一致性视图来保证多事务的并发控制,mvcc是innodb的一种特殊机制,他保证了事务四大特性之一的隔离性(原子性,一致性,隔离性) ...

  3. MySQL数据库InnoDB存储引擎中的锁机制

    MySQL数据库InnoDB存储引擎中的锁机制    http://www.uml.org.cn/sjjm/201205302.asp   00 – 基本概念 当并发事务同时访问一个资源的时候,有可能 ...

  4. MySQL的innoDB锁机制以及死锁处理

    MySQL的nnoDB锁机制 InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.行级锁与表级锁本来就有许多不同之处,innodb正常的select ...

  5. MySQL的InnoDB索引原理详解

    摘要 本篇介绍下Mysql的InnoDB索引相关知识,从各种树到索引原理到存储的细节. InnoDB是Mysql的默认存储引擎(Mysql5.5.5之前是MyISAM,文档).本着高效学习的目的,本篇 ...

  6. MySQL的InnoDB索引原理详解 (转)

    摘要: 本篇介绍下Mysql的InnoDB索引相关知识,从各种树到索引原理到存储的细节. InnoDB是Mysql的默认存储引擎(Mysql5.5.5之前是MyISAM,文档).本着高效学习的目的,本 ...

  7. MySql中innodb存储引擎事务日志详解

    分析下MySql中innodb存储引擎是如何通过日志来实现事务的? Mysql会最大程度的使用缓存机制来提高数据库的访问效率,但是万一数据库发生断电,因为缓存的数据没有写入磁盘,导致缓存在内存中的数据 ...

  8. [转]MySQL 表锁和行锁机制

    本文转自:http://www.cnblogs.com/itdragon/p/8194622.html MySQL 表锁和行锁机制 行锁变表锁,是福还是坑?如果你不清楚MySQL加锁的原理,你会被它整 ...

  9. MySQL 各级别事务的实现机制

    MySQL 各级别事务的实现机制在处理cnctp项目已合包裹状态同步的问题时,发现读包裹状态和对包裹状态的更新不在一个事务内,我提出是否会因为消息并发导致状态一致性问题.在和同事讨论的过程中,我们开始 ...

随机推荐

  1. 深入理解Java并发之synchronized实现原理

    深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoader) 深入 ...

  2. [Web 前端] React Js img 图片显示默认 占位符

    cp from : https://blog.csdn.net/wyk304443164/article/details/77093339 没有考虑到兼容性,因为我们暂时只适配了webkit. 也没有 ...

  3. Kubernetes基础:查看状态、管理服务

    目标 了解Kubernetes Pod 了解Kubernetes Node 学习如何调试部署问题 了解如何通过Service暴露应用 Kubernetes Pods 在Kubernetes中创建一个D ...

  4. Kendall Rank(肯德尔等级)相关系数

    1.简介在统计学中,肯德尔相关系数是以Maurice Kendall命名的,并经常用希腊字母τ(tau)表示其值.肯德尔相关系数是一个用来测量两个随机变量相关性的统计值.一个肯德尔检验是一个无参数假设 ...

  5. [转]你如何面对—LNMP高并发时502

    From : http://www.topthink.com/topic/5683.html 之前php-fpm配置: 单个php-fpm实例,使用socket方式,内存8G 静态方式,启动php-f ...

  6. 【BZOJ】【3697】采药人的路径&【3127】【USACO2013 Open】Yin and Yang

    点分治 Orz hzwer 倒是比较好想到点分治……然而在方案统计这里,我犯了两个错误…… 1.我比较傻逼的想的是:通过儿子来更新父亲,也就是统计以x为根的子树中xxxx的路径有多少条……这样转移. ...

  7. 【已解决】Android微信开放平台,申请移动应用的 应用签名 如何获取

    在微信开放平台,申请移动应用的时候: https://open.weixin.qq.com/cgi-bin/appcreate?t=manage/createMobile&type=app&a ...

  8. rsync推送备份服务器(Linux)

    rsync推送备份服务器备份服务器操作需被备份的服务器操作批处理shell备份服务器操作#编辑配置文件vi /etc/rsyncd.conf uid = root #运行RSYNC守护进程的用户gid ...

  9. boost并发编程boost::atomic

    三个用于并发编程的组件: atomic,thread,asio(用于同步和异步io操作)   atomic atomic,封装了不同计算机硬件的底层操作原语,提供了跨平台的原子操作功能,解决并发竞争读 ...

  10. Linux修改终端显示前缀及环境变量

    Linux终端前面默认显示一长串,如: [work@aaa.baidu.com dir]$ 这是由PS1环境变量决定的: [work@aaa.baidu.com dir]$ echo $PS1 [\u ...