在集群的环境中,有这种场景
需要整数自增ID,这个整数要求一直自增,并且需要保证唯一性.

Web服务器集群调用这个整数生成服务,然后根据各种规则,插入指定的数据库.
    
    一般来说,整数自增可以通过几个方式实现.
    1.MySQL 单独建一个表,使用Auto_increment特性.

  1. CREATE TABLE `test` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. PRIMARY KEY (`id`)
  4. ) ENGINE=InnoDB DEFAULT CHARSET=utf8

如果需要生成ID,则Insert一个记录,然后获取last_insert_id()得到ID值

    
    这种方式的优点是简单,而且比较快.
    缺点是这个表会越来越大,需要定期进行清理.

2.Oracle 序列
    优点很明显,足够快,而且不占用空间.
    缺点..你需要有Oracle

3.mysql 单行更新自增

    需要生成ID的时候,进行如下调用

以上三种数据库方式的效率对比如下(都是测试的虚拟环境,作为趋势参考,数值是每秒生成的ID个数)

  单线程 5线程 10线程 20线程
MySQL Auto_increment 340-390 277 229 178
Oracle序列 714 555 454 454
MySQL 单行更新 303 136 66 19

4.使用Redis自增
    使用两个Redis实例,一个分发奇数ID,一个分发偶数ID
    任何一个Redis损坏,都可以切换到另外一个Redis实例.

5.使用程序模拟序列

下面的ID生成服务,初始化先从数据库拿到一段ID,然后分发。
    一旦ID耗尽,再从数据库获取一段ID。
    可以启动多个ID生成服务,避免单点故障.
    ID生成服务本身应该串行化,避免锁竞争.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;public class SeqGenerator {private static ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();private static int currentVal = -1;private static int maxVal = -1;private static int fetchSize = 10000;//每次生成一万个idstatic{try {fetchFromDB();} catch (Exception e) {// TODO Auto-generated catch block
            e.printStackTrace();}}public static int getSeq() throws InterruptedException, ExecutionException {Callable<Integer> c = new Callable<Integer>() {@Overridepublic Integer call() throws Exception {int result = currentVal;if (currentVal > maxVal) {//如果当前值>数据库最大值,重新生成idfetchFromDB();result = currentVal;}currentVal++;return result;}};Future<Integer> task = singleThreadExecutor.submit(c);return task.get().intValue();}private static void fetchFromDB() throws Exception {Class.forName("com.mysql.jdbc.Driver");Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "xx", "xx");connection.setAutoCommit(false);Statement st = connection.createStatement();ResultSet rs = st.executeQuery("select * from test for update");rs.next();currentVal = rs.getInt(1) + 1;//当前值rs.close();st.executeUpdate("update test set id=id+" + fetchSize);//更新db中最大值rs = st.executeQuery("select * from test for update");rs.next();maxVal = rs.getInt(1);//最大值connection.commit();rs.close();st.close();connection.close();}public static void main(String[] args) throws Exception {int i = 1000000;long start = System.currentTimeMillis();while (i > 0) {System.out.println(SeqGenerator.getSeq());i--;}long end = System.currentTimeMillis();System.out.println(end - start);}
}

使用这种自定义序列,1百万ID的生成时间是14s.效果非常明显.

转载于:https://www.cnblogs.com/firstdream/p/5222541.html

生成整数自增ID(集群主键生成服务)相关推荐

  1. mybatis主键生成策略和mp主键生成策略

    mybatis主键生成策略和mp主键生成策略 1,mybatis plus 主键生成策略 都是通过给实体类的属性添加注解的方式执行type = IDTYPE- ​ 1,AUTO数据库ID自增 ​ 2, ...

  2. 雪花算法及分布式主键生成策略详解

    目前雪花算法常应用于分布式环境下作为分布式主键的首选,本文详细介绍下雪花算法及相关分布式主键的生成策略. 如下内容已本文PPT讲解内容为基础. 本次内容共包括4部分:分布式主键生成策略,雪花算法详解, ...

  3. redis主从读写分离replication复制数据+sentienl哨兵集群主备切换

    说明:最近公司在自己搭建了一套redis主从读写分离+sentinel哨兵集群主备切换,通过手工去搭建replication复制+主从架构+读写分离+哨兵集群+高可用redis集群架构 公司的已经搭建 ...

  4. php中怎么让主键自增长,在数据库设计中,无论如何也该设计一个自增ID字段作为主键吗?...

    首先纠正错误 没有自增主键是无法修改数据的-- 你能确定吗? 果真如你所说,那请问: 1. 下面这数据有主键自增吗? 2. 这样的数据是不是不能修改? 主键自增主要是方便 主键自增主要就是为了方便,让 ...

  5. db2主键自增和oracle,DB2主键自增长设置(id自增)

    接触DB2还没有多久,最近的项目中 需要创建一个表,表的主键自增长,毕竟跟Oracle有点不一样啊! CREATE  TABLE T_RUNNING_THREAD ( IDINTEGER NOT NU ...

  6. kubernetes V1.10.4 集群部署 (手动生成证书)

    说明:本文档涉及docker镜像,yaml文件下载地址 链接:https://pan.baidu.com/s/1QuVelCG43_VbHiOs04R3-Q 密码:70q2 本文只是作为一个安装记录 ...

  7. 4.ID主键生成策略

    保证唯一性(auto_increment) 一.xml方式 1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mappi ...

  8. hibernate 7大主键生成策略详解与对象状态

    一:代理主键_主键自增 1.identity 1.采用底层数据库本身提供的主键生成标识符,条件是数据库支持自动增长数据类型 2.该生成器要求在数据库中把主键定义成为自增长类型.适用于代理主键 2.in ...

  9. Hibernate各种主键生成策略与配置详解 - 真的很详细啊!!

    1.assigned 主键由外部程序负责生成,在 save() 之前必须指定一个.Hibernate不负责维护主键生成.与Hibernate和底层数据库都无关,可以跨数据库.在存储对象前,必须要使用主 ...

  10. 【Hibernate】hibernate主键生成策略与配置详解

    //####################################################### **Hibernate各种主键生成策略与配置详解** //############# ...

最新文章

  1. 计算机组成原理 — CPU — 缓存访问
  2. linux文件夹加密访问,技术|Linux系统上用encfs创建和管理加密文件夹
  3. 刚柔并济的开源分布式事务解决方案
  4. python的回溯信息_基于Python的回溯算法
  5. li 字多出了省略号_文字溢出自动显示省略号css方法 -
  6. 让windows 2003启动后直接进入桌面
  7. java实现ListObject转List实体类,java实现Object转对象,java实现Object转实体类
  8. 【Swift学习】Swift编程之旅(一)
  9. 树莓派智能家居-天气预报和实时温湿度监控
  10. 快速实现MySQL迁移到Redis
  11. 组织健康的路径:良性互动
  12. Linux下DHCP服务的配置相关参数说明
  13. Address already in use: JVM_Bind:8080类似问题解决方法
  14. URLDecoder和URLEncoder的使用总结
  15. 驱动开发:BSOD 0xC4_f6 句柄问题
  16. 【原生JS小实例】加减乘除取余计算器
  17. AMD Ryzen Threadripper 2990WX和intel 9980XE 用于第一性原理计算对比
  18. 用计算解决科学难题,用算法让生活变得更好
  19. Chrome浏览器搜索引擎问题
  20. BLE 蓝牙抓包分析

热门文章

  1. ecstore 定时任务配置
  2. Swift - 二进制,八进制,十六机制的表示方法
  3. Andorid用ksoap2调用wcfDemo
  4. Ubuntu - 新建管理员用户
  5. PostgreSQL使用函数实现merge功能
  6. 麦达数字SaaS布局再落子9300万投资赢销通
  7. golang之旅--接口 (interface)
  8. 团队博客作业-Week3
  9. 让hammer完美支持Pixi.js - 2D webG库
  10. 5月第3周安全回顾 思科路由器Rootkit现身 企业需漏洞管理