MongoDB的timezone问题

MongoDB是以UTC格式来存储全部时间的,查询的时候也是返回UTC时间,不提供在数据库链接级别的timezone支持,这就带来一个问题:没法使用groupby对日期进行聚合,由于你所在的timezone的日期跟UTC的日期不彻底是同一天。html

虽然这个功能在社区里面呼声仍是比较高的,可是10gen公司至今都没有给出timezone支持的时间表。 https://jira.mongodb.org/browse/SERVER-6310git

 

这样对于想要存储正确时间到mongodb中,有两种套路。github

1:存入数据库以前,把datetime转成UTC时间;从数据库读取时(读取的结果并不带timezone信息,由于它确定是UTC时间),再把UTC时间转成local timezone。  具体参照这里mongodb

2:使用驱动自己提供的tz_aware=True来进行半自动转,为何说是半自动,由于插入的时候datetime必须带有tzinfo信息,它才能帮助你自动转换成UTC,否则就直接存入mongoDB了。查询的时候datetime带了UTC的tzinfo,须要使用astimezone把它转成local timezone。 具体参照这里数据库

 

对于groupby的问题,到目前尚未好的解决方案,要么把数据所有拉到客户端,而后进行统一转换,再统计。这样代价会比较大,对于大一点数据来讲就不太现实。apache

若是不须要同一数据支持多timezone的话,能够把本地时间直接存入到mongodb中 ;)app

 

纪录一次本身碰到的一个跟groupby相关的具体问题及解决方案。url

《背景》spa

经过各个app server上的td-agent来收集apache的access log,并存入mongoDB中code

 td-agent用于收集access log的配置

<source>
  type tail
  path /var/log/httpd/access_log
  pos_file /var/log/td-agent/access_log.pos
  tag apache.access
  format /^(?<host>[^ ]*) \[(?<time>[^\]]*)\] (?<user>[^ ]*) (?<url>[^ ]*) (?<code>[^ ]*) (?<size>[^ ]*) (?<taken>[^ ]*)$/
  time_format %d/%b/%Y:%H:%M:%S %z
</source>

<match apache.access>
  # plugin type
  type mongo_timezone

  # timezone
  utcoffset 8

  # mongodb db + collection
  database apache
  collection access

  # mongodb host + port
  host 127.0.0.1
  port 27017

  # interval
  flush_interval 10s
</match>

 

为了使得groupby能够对日期聚合,必须把本地时间直接存入mongoDB,全部的hack就在mongo_timezone这个mongo_timezone  本身定制plugin里面了。(把该定制文件放入/etc/td-agent/plugin/就能够在配置文件里面直接使用)

每个fluent的event log包含三部分,tag,time,message。这是一个sample

2013-08-09T00:00:30+09:00       apache.access      {"host":"117.136.88.98","user":"1","request":"POST /index/ HTTP/1.1","code":"200","size":"822","taken":"40790"}

根据fluent-plugin-mongo的源代码,这个timestamp形式的time值默认会写入mongoDB,能够在这里定制我须要的值。

 

--EOF--

相关文章
相关标签/搜索