如何使用MongoDb实现分布式Id?
传统数据库软件开发中,主键自动生成技术各大数据库对于该需求也提供了相应的支持,比如MySQL的自增。
分布式ID特性包括:唯一性:确保生成的ID是全网唯一的;高可用性:确保任何时候都能正确的生成ID。
github上对分布式ID这个特性的描述是:分布式唯一和时间序列。
主要方案方案包括
- 使用reids的incr命令
- 使用UUID
- Twitter的snowflake算法
- 利用zookeeper生成唯一ID
- MongoDB的ObjectId
MongoDB的ObjectId设计成轻量型的,不同的机器都能用全局唯一
它的格式:
前4个字节是从标准纪元开始的时间戳,单位为秒。时间戳,与随后的5个字节组合起来,提供了秒级别的唯一性。由于时间戳在前,这意味着ObjectId大致会按照插入的顺序排列。这对于某些方面很有用,如将其作为索引提高效率。这4个字节也隐含了文档创建的时间。绝大多数客户端类库都会公开一个方法从ObjectId获取这个信息。
接下来的3字节是所在主机的唯一标识符。通常是机器主机名的散列值。这样就可以确保不同主机生成不同的ObjectId,不产生冲突。为了确保在同一台机器上并发的多个进程产生的ObjectId是唯一的,接下来的两字节来自产生ObjectId的进程标识符(PID)。
- 前9字节保证了同一秒钟不同机器不同进程产生的ObjectId是唯一的。
- 后3字节就是一个自动增加的计数器,确保相同进程同一秒产生的ObjectId也是不一样的。同一秒钟最多允许每个进程拥有2563(16777216)个不同的ObjectId。
机器ID是服务器主机标识,通常是机器主机名的散列值。
同一台机器上可以运行多个mongod实例,因此也需要加入进程标识符PID。
前9个字节保证了同一秒钟不同机器不同进程产生的ObjectId的唯一性。后三个字节是一个自动增加的计数器(一个mongod进程需要一个全局的计数器),保证同一秒的ObjectId是唯一的。同一秒钟最多允许每个进程拥有(256^3=16777216)个不同的ObjectId。
总结一下:时间戳保证秒级唯一,机器ID保证设计时考虑分布式,避免时钟同步,PID保证同一台服务器运行多个mongod实例时的唯一性,最后的计数器保证同一秒内的唯一性(选用几个字节既要考虑存储的经济性,也要考虑并发性能的上限)。
"_id"既可以在服务器端生成也可以在客户端生成,在客户端生成可以降低服务器端的压力。
主要参考:
https://blog.csdn.net/forezp/article/details/69056017
https://www.cnblogs.com/xjk15082/archive/2011/09/18/2180792.html
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: 如何使用MongoDb实现分布式Id?
本文地址: https://pptw.com/jishu/18004.html