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--

相關文章
相關標籤/搜索