先了解几个基本点:
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
1
ZackYang 2015-05-15 15:13:35 +08:00
我都是用 uuid 改写...
|
2
jiangzhuo 2015-05-15 15:14:25 +08:00
做集羣 肯定要集羣間使用的時間統一的,特別是這種生成唯一性和時間有序的id的時候
|
3
yueyoum 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 字段就行, 相比上面的问题, 增加一个带索引的列,根本不是问题 |
4
kslr 2015-05-15 16:09:02 +08:00
这不是mongodb的坑,这么多机器时间还不统一,另外 create_at和update_at
|
7
likuku 2015-05-15 20:21:16 +08:00 1
@sing1ee 配置好 ntpd 服务啊,每台服务器都运行它。ntpd 是渐进式校准服务器时钟,不会引起时钟误差颠簸(有些服务/软件假若侦测到时钟颠簸,可能会终止运行/运行不正常)。
|
8
likuku 2015-05-15 20:22:45 +08:00
@sing1ee 关于时钟颠簸/跃变 会引起问题,参考:
AsiaBSDCon上说OpenBSD的sensor framework的时候的一个观点 - delphij's Chaos : https://blog.delphij.net/2007/03/asiabsdconopenb.html |
9
mko0okmko0 2015-05-15 22:08:26 +08:00
统一使用格林威治时间.直接存成秒数字.一般索引提速.需要时间索引则另用函数生成索引.
|
10
springwarm 2015-05-15 23:20:41 +08:00
楼主给出的基本点,"北京时间比UTC时间早了八个小时",会不会有问题
UTC 和本地时间的换算公式是: UTC + 时区差 = 本地时间 北京是东八区,对应的公式应该是: UTC + (+0800) = 北京时间 以此推断,是UTC 时间比北京时间早了八个小时吧 |
11
sing1ee OP @springwarm 这个应该是北京早吧=;=
|
12
Landarky 2015-05-16 09:31:43 +08:00 via iPad
不仅是时区问题 机器时间也可能差几分钟 修改到一致就好
|
13
likuku 2015-05-16 11:11:00 +08:00
@Landarky 修改机器时间...都21世纪了,没啥理由不用ntpd吧。如今桌面的 ubuntu/osx/windows都默认安装并开启ntpd服务的了。
|
14
xiaogui 2015-05-16 12:42:09 +08:00
UTC 并不是问题,都采用 UTC 最好了。
|
15
whatisnew 2015-05-16 13:13:12 +08:00
我用 mongodb 试着删除 where asc 顺序的前 30 行记录,折腾了半小时 remove findandmodify 都没搞定,然后,我就撤退了。。。
|
16
makuta 2015-05-16 17:31:13 +08:00
做Mongo集群
|
17
ddou 2015-05-16 18:57:37 +08:00
个人觉得是使用方式不对,ObjectId当ID用就行了,其他时间的话应该是CreatedAt和UpdatedAt
|
18
Cu635 2015-05-16 21:55:13 +08:00
@springwarm 北京时间比UTC早。UTC的1:00am是北京时间当天的9:00am。
|
19
Cu635 2015-05-16 21:57:00 +08:00
@springwarm 计算公式是
1:00am(UTC)+(+0800)(东八区)=9:00am(北京时间,东八区时间) |
20
VirgilMing 2015-05-17 01:27:20 +08:00 via iPhone
我很好奇哪个时区比 UTC+8 还 +8?
|
21
springwarm 2015-05-17 17:00:57 +08:00
|