分布式主键生成策略

在分布式高并发的情况下,分布式主键生成策略可参考mongodb的objectid实现。

ObjectId是一种轻量的,不同的机器不同的进程都能用全局唯一的同种方法生成它,而不是采用传统的自增的主键策略,因为在多台服务器上同步自动增加主键既费力又费时。ObjectId是一个24位的字符串,它是由一组十六进制的字符构成,每个字节两位的十六进制数字,总共用了12字节的存储空间。MongoDB的这种设计,体现着空间换时间的思想。官网中对ObjectId的规范,如图所示。

图官网对ObjectId的规范

1)     Time

时间戳。将刚才生成的objectid的前4位进行提取“4e7020cb”,然后按照十六进制转为十进制,变为“1315971275”,这个数字就是一个时间戳。通过时间戳的转换,就成了易看清的时间格式,如图3所示。

2)    Machine

机器。接下来的三个字节就是“7cac81”,这三个字节是所在主机的唯一标识符,一般是机器主机名的散列值,这样就确保了不同主机生成不同的机器hash值,确保在分布式中不造成冲突,这也就是在同一台机器生成的objectId中间的字符串都是一模一样的原因。

3)    PID

进程ID。上面的Machine是为了确保在不同机器产生的objectId不冲突,而pid就是为了在同一台机器不同的mongodb进程产生了objectId不冲突,接下来的“af71”两位就是产生objectId的进程标识符。

4)    INC

自增计数器。前面的九个字节是保证了一秒内不同机器不同进程生成objectId不冲突,这后面的三个字节“36236b”是一个自动增加的计数器,用来确保在同一秒内产生的objectId也不会发现冲突,允许256的3次方等于16777216条记录的唯一性。

总的来看,objectId的前4个字节时间戳,记录了文档创建的时间;接下来3个字节代表了所在主机的唯一标识符,确定了不同主机间产生不同的objectId;后2个字节的进程id,决定了在同一台机器下,不同mongodb进程产生不同的objectId;最后通过3个字节的自增计数器,确保同一秒内产生objectId的唯一性。ObjectId的这个主键生成策略,很好地解决了在分布式环境下高并发情况主键唯一性问题,值得学习借鉴。

参考: http://www.mongodb.org/display/DOCS/Object+IDs

时间: 2024-10-10 16:38:23

分布式主键生成策略的相关文章

JPA中的主键生成策略

Table 策略 (Table strategy) 这种策略中,持久化引擎 (persistence engine) 使用关系型数据库中的一个表 (Table) 来生成主键.这种策略可移植性比较好,因为所有的关系型数据库都支持这种策略.不同的 J2EE 应用服务器使用 不同的持久化引擎. 下面用一个例子来说明这种表生成策略的使用: 清单 1.Table 生成策略 @Entity public class PrimaryKey_Table { @TableGenerator(name = "PK_

常用Hibernate主键生成策略

今天学习到了关于Hibernate主键生成策略的问题,总结下,不足之处,请大家指出. Hibernate为优秀的持久层框架的代表.在传统的JDBC+JavaBean操作中,实体对象都由程序员自己去封装,然后返回.而在Hibernate中,采用对象关系映射『ORM』,大大简化了对数据库的操作. 在数据库的设计和操作中,我们通常会给表建立主键.主键,可以分为自然主键和代理主键. 自然主键表示:采用具有业务逻辑含义的字段作为表的主键.比如在用户信息表中,采用用户的身份证号码作为主键.但是这样一来,随着

Hibernate主键生成策略总结(这里面讲的很详细)

 Hibernate提供的主键生成策略,使我们可以在实体类的映射xml文件中设定关键字来告诉hibernate我们要使用的主键生成方式,然后hibernate会根据设定完成数据库的主键控制. 一.首先通过举例子来了解实体映射文件(*.hbm.xml)中对id生成策略配置格式     用户User的实体类User.java      [java] view plaincopyprint? package com.bjpowernode.hibernate;    import java.util.

mysql-MySQL不支持Hibernate的sequence主键生成策略吗?

问题描述 MySQL不支持Hibernate的sequence主键生成策略吗? 网上都说MySQL不支持Hibernate的sequence主键生成策略.为什么我的实体类使用JAP的@GeneralValue(好像是这个,没有指定生成策略)的时候,数据库会产生hibernate_sequence表?? 解决方案 hibernate主键生成策略值sequenceHibernate主键生成策略Hibernate主键生成策略

hibernate-Hibernate框架使用JPA注解时,使用的主键生成策略

问题描述 Hibernate框架使用JPA注解时,使用的主键生成策略 Hibernate框架使用JPA注解,在ID加上@GeneratedValue注解,使用的是什么主键生成策略?数据库生成了一张hibernate_sequence表.使用的是M有SQL数据库 解决方案 你用的sequence 这种策略吧,这是针对oracle 不提供自动增长的数据库类型的主键的生成方式 解决方案二: JPA使用Hibernate实现使用UUID.主键的生成策略.JPA学习笔记(4)--使用Table策略来生成主

架构师-我在设计一个表结构.主键生成策略选择哪种好,有什么讲究吗?

问题描述 我在设计一个表结构.主键生成策略选择哪种好,有什么讲究吗? 选uuid? 还是选数字自增? 一般情况下都用哪个啊? 一般情况下都用哪个啊? 一般情况下都用哪个啊? 解决方案 主键一般都是非业务主键,仅作编号没有实际意义,自增或者UUID都可以的.比较如下: 解决方案二: 数字自增长 一直用的这种,还不错.

hibernate主键生成策略identity··为什么加入的第一个数据主键一直是0

问题描述 hibernate主键生成策略identity··为什么加入的第一个数据主键一直是0 从0开始没有1····· 解决方案 配置问题..............................

hibernate5(5)实体映射注解配置[2]主键生成策略

@GeneratedValue基本注解类型 在上一篇文章中,我们讲到了JPA使用@GeneratedValue注解来定义生成策略,而关于注解生成策略有4种基本支持类型: 1. GenerationType.TABLES 当前主键的值单独保存到一个数据库的表中 2. GenerationType.SEQUENCE 利用底层数据库提供的序列生成标识符 3. GenerationType.IDENTITY 采取数据库的自增策略 4. GenerationType.AUTO 根据不同数据库自动选择合适的

hibernate 的主键生成策略小结

                                                                          hibernate主键生成策略1,increment:以递增的方式生成OID,每次增加一(hibernate在执行插入语句之前会执行一次查询,查询的结果为这个表中的id的最大值,然后加1处理在绑定到这个insert语句中)  <id name="userid" type="java.lang.Long">