生成整数自增ID(集群主键生成服务)
Web服务器集群调用这个整数生成服务,然后根据各种规则,插入指定的数据库.
一般来说,整数自增可以通过几个方式实现.
1.MySQL 单独建一个表,使用Auto_increment特性.
- CREATE TABLE `test` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- PRIMARY KEY (`id`)
- ) 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(集群主键生成服务)相关推荐
- mybatis主键生成策略和mp主键生成策略
mybatis主键生成策略和mp主键生成策略 1,mybatis plus 主键生成策略 都是通过给实体类的属性添加注解的方式执行type = IDTYPE- 1,AUTO数据库ID自增 2, ...
- 雪花算法及分布式主键生成策略详解
目前雪花算法常应用于分布式环境下作为分布式主键的首选,本文详细介绍下雪花算法及相关分布式主键的生成策略. 如下内容已本文PPT讲解内容为基础. 本次内容共包括4部分:分布式主键生成策略,雪花算法详解, ...
- redis主从读写分离replication复制数据+sentienl哨兵集群主备切换
说明:最近公司在自己搭建了一套redis主从读写分离+sentinel哨兵集群主备切换,通过手工去搭建replication复制+主从架构+读写分离+哨兵集群+高可用redis集群架构 公司的已经搭建 ...
- php中怎么让主键自增长,在数据库设计中,无论如何也该设计一个自增ID字段作为主键吗?...
首先纠正错误 没有自增主键是无法修改数据的-- 你能确定吗? 果真如你所说,那请问: 1. 下面这数据有主键自增吗? 2. 这样的数据是不是不能修改? 主键自增主要是方便 主键自增主要就是为了方便,让 ...
- db2主键自增和oracle,DB2主键自增长设置(id自增)
接触DB2还没有多久,最近的项目中 需要创建一个表,表的主键自增长,毕竟跟Oracle有点不一样啊! CREATE TABLE T_RUNNING_THREAD ( IDINTEGER NOT NU ...
- kubernetes V1.10.4 集群部署 (手动生成证书)
说明:本文档涉及docker镜像,yaml文件下载地址 链接:https://pan.baidu.com/s/1QuVelCG43_VbHiOs04R3-Q 密码:70q2 本文只是作为一个安装记录 ...
- 4.ID主键生成策略
保证唯一性(auto_increment) 一.xml方式 1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mappi ...
- hibernate 7大主键生成策略详解与对象状态
一:代理主键_主键自增 1.identity 1.采用底层数据库本身提供的主键生成标识符,条件是数据库支持自动增长数据类型 2.该生成器要求在数据库中把主键定义成为自增长类型.适用于代理主键 2.in ...
- Hibernate各种主键生成策略与配置详解 - 真的很详细啊!!
1.assigned 主键由外部程序负责生成,在 save() 之前必须指定一个.Hibernate不负责维护主键生成.与Hibernate和底层数据库都无关,可以跨数据库.在存储对象前,必须要使用主 ...
- 【Hibernate】hibernate主键生成策略与配置详解
//####################################################### **Hibernate各种主键生成策略与配置详解** //############# ...
最新文章
- 计算机组成原理 — CPU — 缓存访问
- linux文件夹加密访问,技术|Linux系统上用encfs创建和管理加密文件夹
- 刚柔并济的开源分布式事务解决方案
- python的回溯信息_基于Python的回溯算法
- li 字多出了省略号_文字溢出自动显示省略号css方法 -
- 让windows 2003启动后直接进入桌面
- java实现ListObject转List实体类,java实现Object转对象,java实现Object转实体类
- 【Swift学习】Swift编程之旅(一)
- 树莓派智能家居-天气预报和实时温湿度监控
- 快速实现MySQL迁移到Redis
- 组织健康的路径:良性互动
- Linux下DHCP服务的配置相关参数说明
- Address already in use: JVM_Bind:8080类似问题解决方法
- URLDecoder和URLEncoder的使用总结
- 驱动开发:BSOD 0xC4_f6 句柄问题
- 【原生JS小实例】加减乘除取余计算器
- AMD Ryzen Threadripper 2990WX和intel 9980XE 用于第一性原理计算对比
- 用计算解决科学难题,用算法让生活变得更好
- Chrome浏览器搜索引擎问题
- BLE 蓝牙抓包分析