mongodb 多机部署时的容易忽略的一个要点
2014-09-19 14:19
411 查看
mongodb默认生成的ObjectId 由4部分组成:
前四个字节为时间戳。objectid的前4位进行提取“4e7020cb”,然后按照十六进制转为十进制,变为“1315971275”,这个数字就是一个时间戳;
紧接着三个字节是所在主机的唯一标识符,一般是机器主机名的散列值,这样就确保了不同主机生成不同的机器hash值,确保在分布式中不造成冲突,这也就是在同一台机器生成的objectId中间的字符串都是一模一样的原因。
再接着两个字节是进程ID,即pid。Machine是为了确保在不同机器产生的objectId不冲突,而pid就是为了在同一台机器不同的mongodb进程产生了objectId不冲突,而pid就是产生objectId的进程标识符。
最后三个字节为自增计数器。前面的九个字节是保证了一秒内不同机器不同进程生成objectId不冲突,这后面的三个字节“36236b”是一个自动增加的计数器,用来确保在同一秒内产生的objectId也不会发现冲突,允许256的3次方等于16777216条记录的唯一性。
总的来看,objectId的前4个字节时间戳,记录了文档创建的时间;接下来3个字节代表了所在主机的唯一标识符,确定了不同主机间产生不同的objectId;后2个字节的进程id,决定了在同一台机器下,不同mongodb进程产生不同的objectId;最后通过3个字节的自增计数器,确保同一秒内产生objectId的唯一性。
今天发现明明是两台服务器上且不同mongodb服务所生成的ObjectId中的唯一标识符都一样,即都为7f8b9a,下面是分别用四个各在在两台服务器上生成的真实ObjectId来说明:
为了好查看中间故意加了空格,可以看出唯一标识符都为7f8b9ab9,这是为什么呢?
原因就是我在部署公司新采购的服务器,安装centos6.5时为省劲机器名都是localhost.localdomain(在shell下运行hostname即可查看机器名)。这样也就导致生成的散列值一样,导致从ObjectId无法区分是哪天服务器生成的。
解决办法就是修改主机名,方法有两种:
1.临时修改主机名
#hostname 新主机名
# export HOSTNAME=新主机名
最后再重启mongodb服务及php服务后方可生效
2.永久修改主机名
# vi /etc/sysconfig/network
HOSTNAME=新主机名
这个是永久修改,重启服务器后生效。
前四个字节为时间戳。objectid的前4位进行提取“4e7020cb”,然后按照十六进制转为十进制,变为“1315971275”,这个数字就是一个时间戳;
紧接着三个字节是所在主机的唯一标识符,一般是机器主机名的散列值,这样就确保了不同主机生成不同的机器hash值,确保在分布式中不造成冲突,这也就是在同一台机器生成的objectId中间的字符串都是一模一样的原因。
再接着两个字节是进程ID,即pid。Machine是为了确保在不同机器产生的objectId不冲突,而pid就是为了在同一台机器不同的mongodb进程产生了objectId不冲突,而pid就是产生objectId的进程标识符。
最后三个字节为自增计数器。前面的九个字节是保证了一秒内不同机器不同进程生成objectId不冲突,这后面的三个字节“36236b”是一个自动增加的计数器,用来确保在同一秒内产生的objectId也不会发现冲突,允许256的3次方等于16777216条记录的唯一性。
总的来看,objectId的前4个字节时间戳,记录了文档创建的时间;接下来3个字节代表了所在主机的唯一标识符,确定了不同主机间产生不同的objectId;后2个字节的进程id,决定了在同一台机器下,不同mongodb进程产生不同的objectId;最后通过3个字节的自增计数器,确保同一秒内产生objectId的唯一性。
今天发现明明是两台服务器上且不同mongodb服务所生成的ObjectId中的唯一标识符都一样,即都为7f8b9a,下面是分别用四个各在在两台服务器上生成的真实ObjectId来说明:
----------------------A服务器-------------------------- 541bc109 7f8b9a 9da6 8b4568 541bc05c 7f8b9a 9ea6 8b4569 541bc05b 7f8b9a 9da6 8b4567 541bc054 7f8b9a 9ea6 8b4568 541bbff2 7f8b9a 9ea6 8b4567 -----------------------B服务器------------------------- 541bc02a 7f8b9a 4d4c 8b5562 541bc02a 7f8b9a 4d4c 8b5561 541bc02a 7f8b9a 4d4c 8b5560 541bc02a 7f8b9a 4d4c 8b555b
为了好查看中间故意加了空格,可以看出唯一标识符都为7f8b9ab9,这是为什么呢?
原因就是我在部署公司新采购的服务器,安装centos6.5时为省劲机器名都是localhost.localdomain(在shell下运行hostname即可查看机器名)。这样也就导致生成的散列值一样,导致从ObjectId无法区分是哪天服务器生成的。
解决办法就是修改主机名,方法有两种:
1.临时修改主机名
#hostname 新主机名
# export HOSTNAME=新主机名
最后再重启mongodb服务及php服务后方可生效
2.永久修改主机名
# vi /etc/sysconfig/network
HOSTNAME=新主机名
这个是永久修改,重启服务器后生效。
相关文章推荐
- 新手在sae部署程序容易忽略的一个细节
- 一个容易被大家忽略的多线程性能优化方案:Cache行级别优化
- 一个比较容易忽略的错误
- 探讨使用外联接(OUTER JOIN)联接两表时容易忽略的一个小问题
- 二分查找容易忽略的一个bug
- 链接选项rpath,容易被忽略的一个功能
- 一个容易忽略的优先级问题
- ORACLE 中 VARCHAR2 类型的字段长度是按照 byte 来定义的 一个容易被忽略的问题
- 二分查找容易忽略的一个bug
- 关于指向结构体的指针——又一个指针用法中容易忽略的问题
- 使用JNDI的一个容易忽略的错误
- 二分查找容易忽略的一个bug
- getHibernateTemplate 抛出NullPointer 异常 其中一个容易被忽略的原因
- hdu 1011 树dp还是容易理解的,不过在做这个题的时候把一个边界条件给忽略了,以后得注意
- android——ListView的item容易忽略的一个小错误
- 一个容易忽略的陷阱:修改字符串常量的值
- 重叠I/O网络编程使用AcceptEx时容易忽略的一个问题
- 一个容易忽略的问题
- 【转】一个非常常见但容易被忽略的c++问题——用IPML模式可以解决
- python安装第三方包之后无法导入相应模块(一个容易忽略的bug)