• MongoDB文档(Document)全局唯一ID的设计思路


    MongoDB中数据的基本单元称为文档(Document)。文档是MongoDB的核心概念,多个键极其关联的值有序的放置在一起便是文档。

    在一个特定集合内部,需要唯一的标识文档。因此MongoDB中存储的文档都由一个"_id"键,用于完成此功能。这个键的值可以是任意类型的,默认试ObjectId对象。ObjectId对象的生成思路是本文的主题,也是很多分布式系统可以借鉴的思路。

    为了考虑分布式,“_id”要求不同的机器都能用全局唯一的同种方法方便的生成它。因此不能使用自增主键(需要多台服务器进行同步,既费时又费力),因此选用了生成ObjectId对象的方法。

    ObjectId使用12字节的存储空间,其生成方式如下:

    |0|1|2|3|4|5|6 |7|8|9|10|11|

    |时间戳  |机器ID|PID|计数器   |

    前四个字节时间戳是从标准纪元开始的时间戳,单位为秒,有如下特性:

    1. 时间戳与后边5个字节一块,保证秒级别的唯一性;
    2. 保证插入顺序大致按时间排序;
    3. 隐含了文档创建时间;

    时间戳的实际值并不重要,不需要对服务器之间的时间进行同步(因为加上机器ID和进程ID已保证此值唯一,唯一性是ObjectId的最终诉求)。

    机器ID是服务器主机标识,通常是机器主机名的散列值。

    同一台机器上可以运行多个mongod实例,因此也需要加入进程标识符PID。

    前9个字节保证了同一秒钟不同机器不同进程产生的ObjectId的唯一性。后三个字节是一个自动增加的计数器(一个mongod进程需要一个全局的计数器),保证同一秒的ObjectId是唯一的。同一秒钟最多允许每个进程拥有(256^3 = 16777216)个不同的ObjectId。

    总结一下:时间戳保证秒级唯一,机器ID保证设计时考虑分布式,避免时钟同步,PID保证同一台服务器运行多个mongod实例时的唯一性,最后的计数器保证同一秒内的唯一性(选用几个字节既要考虑存储的经济性,也要考虑并发性能的上限)。

    "_id"既可以在服务器端生成也可以在客户端生成,在客户端生成可以降低服务器端的压力。

  • 相关阅读:
    windows的80端口被占用时的处理方法
    Ansible自动化运维工具安装与使用实例
    Tomcat的测试网页换成自己项目首页
    LeetCode 219. Contains Duplicate II
    LeetCode Contest 177
    LeetCode 217. Contains Duplicate
    LeetCode 216. Combination Sum III(DFS)
    LeetCode 215. Kth Largest Element in an Array(排序)
    Contest 176 LeetCode 1354. Construct Target Array With Multiple Sums(优先队列,递推)
    Contest 176
  • 原文地址:https://www.cnblogs.com/liuhao/p/2270649.html
Copyright © 2020-2023  润新知