先了解几个基本点:
1. MongoDB默认生成的ObjectId是在客户端完成的,时间戳+host+进程id等,详情见文档
2. ObjectId生成的时候,是根据当期那服务器时间所在的时区
3. 从collection中读出ObjectId,读取generation_time属性,默认是UTC
4. 北京时间比UTC时间早了八个小时
我们两台服务器,一个是北京时间,一个比北京时间早了八个小时。。。从这两个服务器入库MongoDB,并且根据generation_time读,就彻底乱了,结果
1. 北京时间的服务器,得到的generation_time时间比北京时间晚了八个小时
2. 比北京早了的服务器,得到的generation_time时间和北京时间相同
我们以为2是正确的。。。
我们用的是pymongo
|      1ZackYang      2015-05-15 15:13:35 +08:00 我都是用 uuid 改写... | 
|  |      2jiangzhuo      2015-05-15 15:14:25 +08:00 做集羣 肯定要集羣間使用的時間統一的,特別是這種生成唯一性和時間有序的id的時候 | 
|  |      3yueyoum      2015-05-15 15:19:23 +08:00  2 这点还真没注意。 我现在基本都用 UUID 做主键。 无论是 mysql, postgresql 还是 mongodb 简单,方便。 uuid4 冲突几率是有, 如果你能碰到, 也算是你的运气。 什么 分布式, 唯一ID生成, 数据库合并, 瞬间解决。 特别方便的一个使用例子是 django orm 的 bulk_create, 如果你的主键是 自增长 int 那么 返回的 列表中 对象是没有 id 属性的。 这时候用UUID 先给对象赋予ID, bulk_create 返回的对象就是带有ID属性的。 这在 bulk_create后, 需要这些新增加对象ID 的情况 特别有用。 再说一个场景吧。 曾经有个项目, 一个server 对应一个 db, 用的 mongodb, 因为担心效率问题,没有上全局ID生成服务。 是每个server自己算的, 算法大概是 PARAM * NEWID + SERVER_ID param 是一个定义好的数值,比如 1024, newid 是这个server 自己生成的唯一自增长ID, 比如 1,2,3,4... server_id 就是这个 server 的 id, 不同server 的 id 不一样。 这样生成好处是 方便,快速 但缺点也很明显 能开多少server 是由 param 来决定的, 最多 param 个 所以,上UUID, 上面问题一锅端。 有同学会说 INT ID 好啊, 数字的,自然就排序了, mongo 的 objectid 好啊, 还带有时间戳, 也可以排序。 大不了在记录中增加一个 create_at 字段就行, 相比上面的问题, 增加一个带索引的列,根本不是问题 | 
|      4kslr      2015-05-15 16:09:02 +08:00 这不是mongodb的坑,这么多机器时间还不统一,另外 create_at和update_at | 
|  |      7likuku      2015-05-15 20:21:16 +08:00  1 @sing1ee 配置好 ntpd  服务啊,每台服务器都运行它。ntpd 是渐进式校准服务器时钟,不会引起时钟误差颠簸(有些服务/软件假若侦测到时钟颠簸,可能会终止运行/运行不正常)。 | 
|  |      8likuku      2015-05-15 20:22:45 +08:00 @sing1ee 关于时钟颠簸/跃变 会引起问题,参考: AsiaBSDCon上说OpenBSD的sensor framework的时候的一个观点 - delphij's Chaos : https://blog.delphij.net/2007/03/asiabsdconopenb.html | 
|      9mko0okmko0      2015-05-15 22:08:26 +08:00 统一使用格林威治时间.直接存成秒数字.一般索引提速.需要时间索引则另用函数生成索引. | 
|  |      10springwarm      2015-05-15 23:20:41 +08:00 楼主给出的基本点,"北京时间比UTC时间早了八个小时",会不会有问题 UTC 和本地时间的换算公式是: UTC + 时区差 = 本地时间 北京是东八区,对应的公式应该是: UTC + (+0800) = 北京时间 以此推断,是UTC 时间比北京时间早了八个小时吧 | 
|  |      11sing1ee OP @springwarm 这个应该是北京早吧=;= | 
|  |      12Landarky      2015-05-16 09:31:43 +08:00 via iPad 不仅是时区问题  机器时间也可能差几分钟  修改到一致就好 | 
|  |      13likuku      2015-05-16 11:11:00 +08:00 @Landarky 修改机器时间...都21世纪了,没啥理由不用ntpd吧。如今桌面的 ubuntu/osx/windows都默认安装并开启ntpd服务的了。 | 
|  |      14xiaogui      2015-05-16 12:42:09 +08:00 UTC 并不是问题,都采用 UTC 最好了。 | 
|  |      15whatisnew      2015-05-16 13:13:12 +08:00 我用 mongodb 试着删除 where asc 顺序的前 30 行记录,折腾了半小时 remove findandmodify 都没搞定,然后,我就撤退了。。。 | 
|  |      16makuta      2015-05-16 17:31:13 +08:00 做Mongo集群 | 
|      17ddou      2015-05-16 18:57:37 +08:00 个人觉得是使用方式不对,ObjectId当ID用就行了,其他时间的话应该是CreatedAt和UpdatedAt | 
|  |      18Cu635      2015-05-16 21:55:13 +08:00 @springwarm 北京时间比UTC早。UTC的1:00am是北京时间当天的9:00am。 | 
|  |      19Cu635      2015-05-16 21:57:00 +08:00 @springwarm 计算公式是 1:00am(UTC)+(+0800)(东八区)=9:00am(北京时间,东八区时间) | 
|  |      20VirgilMing      2015-05-17 01:27:20 +08:00 via iPhone 我很好奇哪个时区比 UTC+8 还 +8? | 
|  |      21springwarm      2015-05-17 17:00:57 +08:00 |