Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 664|回复: 0

【elasticsearch】数据早8小时Or晚8小时,你知道为什么吗,附解决方案

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-4-28 09:55:38 | 显示全部楼层 |阅读模式
    前言
    • 这篇文章,不会解释什么是本初子午线,只想以做实验的方式来理解数据差8小时的问题。下面就先说结论,再来谈原理。
    解决方案
    • 想必大家都很清楚:中国标准时间= UTC + 8小时。
    • 那么所有和时区有关的地方,都有可能成为“凶手”。
    如果是java写入es怎么解决时区问题?
    • 如果你使用java程序来写入es,我推荐你写入带T的时间字符串。提供程序如下:
    /**
    	 * String timeZoneConvert = timeZoneConvert(
    	 * 				new Date().getTime()
    	 * 				, "yyyy-MM-dd'T'HH:mm:ss.SSSZ",
    	 * 				"Asia/Shanghai");
    	 * 				
    	 * @param date 毫秒
    	 * @param pattern format时间格式
    	 * @param timeZone 时区
    	 * @return 如:2019-12-30T16:32:07.616+0800
    	 */
    	public static String timeZoneConvert(Long date,String pattern,String timeZone){
    		SimpleDateFormat simpleDateFormat=new SimpleDateFormat(pattern);
    		simpleDateFormat.setTimeZone(TimeZone.getTimeZone(timeZone));
    		return simpleDateFormat.format(date);
    	}
    
    • 为什么?因为java有些api是带时区的。如new Date().getTime()默认是东八区,System.currentTimeMillis() 依赖于当前时区来计算毫秒值。
    • 虽然上述例子依赖了这个api,但是这里只是想说明java程序所处的环境的时区同样有影响,特别是这个程序很可能是容器化的,那么可能又和系统镜像的时区有关了。
    如果是logstash写入es怎么解决时区问题?
    • 建议input的时间源数据就是带上时区的字符串,否则就要进行转换。
     mutate{
            gsub => [
               "time", "[+]", "T"
            ]
          } 
            mutate{
          replace => ["time","%{time}+08:00"]
          }
    

    或是:

    date {
        match => ["timestamp", "yyyy-MM-dd HH:mm:ss"]
        target => "my_timestamp"
        timezone => "+08:00"
    }
    
    如果是语句聚合es数据怎么解决时区问题?
    • 指定time_zone配置
    "aggs": {
        "by_day": {
          "date_histogram": {
            "field":     "date",
            "interval":  "day",
            "time_zone": "Asia/Shanghai"
          }
        }
      }
    
    kibana显示怎么解决时区问题?
    • Management>>Advanced Settings设置时区。

    file

    原理&试验
    Es中和时间相关的数据类型
    • 一般在写入es的时候,会以json的方式写入,由于json中没有日期数据类型,所以日期如何存储显示,是由es决定的,也就是说es会进行隐式的类型转换。
    • es中的日期可以是:
    • 格式化日期的字符串,例如"2019-12-30"或"2019/12/30 12:10:30"。
    • 毫秒值。
    • 秒值。
    试验
    • 这里以不同的时间api准备了一些数据写入es,让我们来看看会发生什么。

    file

    • 数据打印出来如下:
    {
        "AsiaTime":"2019-12-30T16:32:07.616+0800",
        "newDateTime":1577694727581,
        "localTimeNow":"2019-12-30T16:32:07.615",
        "systemCurrentTimeMilis":1577694727581,
        "newDate":1577694727581
    }
    
    • 默认不设置索引模板的情况,写入es后,我们发现带 时区‘T’的数据类型为date。
      file

    • 接下来,我们将轮流设置这两个字段为kibana的时间搜索字段,看看会发生什么。

    两个实验对时区的思考
    • 实验一:以localTimeNow做时间搜索字段,显示比数据时间晚了8小时。
      file

    • 实验二:以AsiaTime做时间搜索字段,显示比数据时间早了8小时。
      file

    • 如何解释?当然是由于时区影响。记住这几个点,就很好理解了:

      • es内部,时间会转换成UTC格式,实际按照数值型存储。可以理解为毫秒数。
      • kibana会通过获取时区配置显示时间到界面。

    首先来说实验一,为什么kibana上显示的时比数据时间多8个小时呢?明明是30号的数据,愣是跑到31号去了?

    • 这条数据 "localTimeNow":"2019-12-30T16:32:07.615"。带时区T,默认是UTC时区,
      而kibana获取的时区配置是Asia/Shanghai,为东8区,相当于在原来的时间上加上8个小时显示,所以跑到31号去了。
      用大腿想一下,你肯定知道,这种情况下如果把kibana时区设置为UTC,当然数据就显示正常啦。

    • 再来说实验二, "AsiaTime":"2019-12-30T16:32:07.616+0800,由于上面设置了当前kibana时区为UTC,数据带东八区的时区,所以晚了8小时。同理将kibana时区改为东八区后显示正常。

    总结

    • 时区问题,万变不离其宗,搞清楚原理后,任意数据怎么变化,我们都能够有方法应对,希望这篇文章对你有所帮助。

    欢迎来公众号【侠梦的开发笔记】 一起交流进步

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-15 21:55 , Processed in 0.069077 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表