用logstash 作数据的聚合统计

以spark-streaming 处理消费数据,统计日志经spark sql存储在mysql中

日志写入方式为append
val wordsDataFrame = rdd.toDF("supplier", "type", "domain", "pdate", "count", "idate")
wordsDataFrame
.write
.format("jdbc")
.mode("append").options(mysql_conf)
.save()
因为spark-streaming是批处理服务,这些日志只是中间结果,会有大量小批次的统计信息
表名statistics_temp
id(自增id) domain idate count
1 www.baidu.com 2018-06-13 1
2 www.baidu.com 2018-06-13 2
3 www.taobao.com 2018-06-13 3

求每日每domain的数据还需再一次作聚合

原本的构想是通过logstash将日志导入es,elk方案,kibana直接划分时间间隔聚合出结果展示

现在有个需求是要存入每日的量级入一张表,直接在mysql展示

不考虑从kibana聚合再写入es,statistics_temp数据量较大,每次查询都从statistics_temp用聚合显然不可行

因此需要由这张临时表,导出完真正的有效表statistics,这种需求很常见,通常是记录时间点,定时执行,读取时间点后的数据,统计再upsert

导出表名statistics(domain+idate 配置联合唯一索引,DUPLICATE才生效)
id(自增id) domain idate count
1 www.baidu.com 2018-06-13 3
3 www.taobao.com 2018-06-13 3

最近作数据流程设计搭建,不想写这种代码,因为对logstash比较熟悉,因此便想试试logstash的方案,最终实验可行

环境
logstash 5.5
mysql 5.7

聚合 需要官方插件
https://www.elastic.co/guide/en/logstash/current/plugins-filters-aggregate.html#plugins-filters-aggregate-example2
写入 mysql需要第三方插件
https://github.com/theangryangel/logstash-output-jdbc

1安装插件
logstash5.5 默认不含logstash-filters-aggregate 需单独安装,其他版本未知
logstash-plugins install logstash-filters-aggregate
第三方插件,默认不含,需单独安装
logstash-plugins install logstash-output-jdbc

2执行
由于jdbc_fetch_size参数不生效,因此会拿出大量数据(mysql-connector-java-5.1.44-bin.jar,默认的数据量)需要调整堆大小,避免oom

export LS_JAVA_OPTS="-Xms4g -Xmx8g"
logstash -f /logstash/statistic.conf

重点是/logstash/statistic.conf的内容

input {
jdbc {
jdbc_driver_library => "/logstash/mysql-connector-java-5.1.44-bin.jar"
jdbc_driver_class => "com.mysql.jdbc.Driver"
jdbc_connection_string => "jdbc:mysql://host:3306/db1"
jdbc_user => "root"
jdbc_password => "root"
schedule => "* * * * *"
use_column_value => true
tracking_column => "id"
jdbc_fetch_size => 2000
tracking_column_type => "numeric"
statement => "SELECT * from statistics WHERE id > :sql_last_value"
clean_run => false
record_last_run => true
last_run_metadata_path => "/home/logstash/.statistic"
}
}

filter {
aggregate {
task_id => "%{domain}_%{idate}"
code => "
map['domain'] = event.get('domain')
map['idate'] = event.get('idate')
map['count'] ||= 0
map['count'] += event.get('count')
event.cancel()
"
push_previous_map_as_event => true
}
}

output {
stdout{
codec=>rubydebug{}
}
jdbc {
driver_jar_path => "/logstash/mysql-connector-java-5.1.44-bin.jar"
driver_class => "com.mysql.jdbc.Driver"
connection_string => "jdbc:mysql://host:3306/db1?user=root&password=root"
statement => [ "INSERT INTO `bbs`.`statistics2` (`domain`,`idate`,`count`) VALUES(?,?,?) ON DUPLICATE KEY UPDATE `count` = `count` + ?;", "domain","idate","count","count" ]
}
}

tracking_column => "id"
tracking_column_type => "numeric"
statement => "SELECT * from statistics WHERE id > :sql_last_value"
last_run_metadata_path => "/home/logstash/.statistic"

以上四个参数,配置记录点的信息

该例子为自增id numeric类型
记录文件示例
bash-4.3# cat /home/logstash/.statistic
--- 127986843

若是时间类型
tracking_column => "updated_on"
tracking_column_type => "timestamp"
statement => "SELECT * from user WHERE updated_on > :sql_last_value"
last_run_metadata_path => "/home/logstash/.statistic"

记录文件示例
bash-4.3# cat /home/logstash/.statistic
--- 2018-06-13 10:57:59.000000000 +00:00

可以通过,停logstash服务,改记录文件,再启动logstash服务,来重新聚合统计某记录点后的数据。

示例
count 对比
statistics_temp:
mysql> select count(count),idate from statistics_temp where domain='www.abc.com' and idate>'2018-06-15' group by idate;
+--------------+------------+
| count(count) | idate |
+--------------+------------+
| 15290 | 2018-06-16 |
| 27176 | 2018-06-17 |
| 18997 | 2018-06-18 |
| 21785 | 2018-06-19 |
+--------------+------------+
statistics:
mysql> select count(count),idate from statistics where domain='www.abc.com' and idate>'2018-06-15' group by idate;
+--------------+------------+
| count(count) | idate |
+--------------+------------+
| 532 | 2018-06-16 |
| 533 | 2018-06-17 |
| 534 | 2018-06-18 |
| 535 | 2018-06-19 |
+--------------+------------+

sum 对比
statistics_temp
mysql> select sum(count),idate from statistics_temp where domain='www.abc.com' and idate>'2018-06-15' group by idate;
+------------+------------+
| sum(count) | idate |
+------------+------------+
| 390499 | 2018-06-16 |
| 705807 | 2018-06-17 |
| 462147 | 2018-06-18 |
| 600657 | 2018-06-19 |
+------------+------------+
statistics
mysql> select sum(count),idate from statistics where domain='www.abc.com' and idate>'2018-06-15' group by idate;
+------------+------------+
| sum(count) | idate |
+------------+------------+
| 390499 | 2018-06-16 |
| 705807 | 2018-06-17 |
| 462147 | 2018-06-18 |
| 600657 | 2018-06-19 |
+------------+------------+

相比statistics_temp,statistics count减少,sum一致,聚合成功

用logstash 作数据的聚合统计的更多相关文章

  1. 小试牛刀ElasticSearch大数据聚合统计

    ElasticSearch相信有不少朋友都了解,即使没有了解过它那相信对ELK也有所认识E即是ElasticSearch.ElasticSearch最开始更多用于检索,作为一搜索的集群产品简单易用绝对 ...

  2. pandas:聚合统计、数据分箱、分组可视化

    1.聚合统计 1.1描述统计 #df.describe(),对数据的总体特征进行描述 df.groupby('team').describe() df.groupby('team').describe ...

  3. 通过Flink实现个推海量消息数据的实时统计

    背景 消息报表主要用于统计消息任务的下发情况.比如,单条推送消息下发APP用户总量有多少,成功推送到手机的数量有多少,又有多少APP用户点击了弹窗通知并打开APP等.通过消息报表,我们可以很直观地看到 ...

  4. 关于MongoDB时间格式转换和时间段聚合统计的用法总结

    一 . 背景需求 在日常的业务需求中,我们往往会根据时间段来统计数据.例如,统计每小时的下单量:每天的库存变化,这类信息数据对运营管理很重要. 这类数据统计依赖于各个时间维度,年月日.时分秒都有可能. ...

  5. Solr.NET快速入门(五)【聚合统计,分组查询】

    聚合统计 属性 说明 Min 最小值 Max 最大值 Sum 总和 Count 记录数,也就是多少行记录 Missing 结果集中,有多少条记录是空值 SumOfSquares 平方和(x1^2 + ...

  6. MongoDB 中聚合统计计算--$SUM表达式

    我们一般通过表达式$sum来计算总和.因为MongoDB的文档有数组字段,所以可以简单的将计算总和分成两种:1,统计符合条件的所有文档的某个字段的总和:2,统计每个文档的数组字段里面的各个数据值的和. ...

  7. Elasticsearch 第六篇:聚合统计查询

    h2.post_title { background-color: rgba(43, 102, 149, 1); color: rgba(255, 255, 255, 1); font-size: 1 ...

  8. 《C++语言基础》实践參考——数组作数据成员

    返回:贺老师课程教学链接 [项目5 - 数组作数据成员]阅读教材P255例8.4.注意到类中的数据成员能够是数组.设计一个工资类(Salary),当中类的数据成员例如以下: class Salary ...

  9. 8.3Solr API使用(StatsComponent聚合统计)

    转载请出自出处:http://eksliang.iteye.com/blog/2169134 一.概述 Solr可以利用StatsComponent 实现数据库的聚合统计查询,也就是min.max.a ...

随机推荐

  1. POJ 1416:Shredding Company

    Shredding Company Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4713   Accepted: 2714 ...

  2. Tensorflow学习教程------普通神经网络对mnist数据集分类

    首先是不含隐层的神经网络, 输入层是784个神经元 输出层是10个神经元 代码如下 #coding:utf-8 import tensorflow as tf from tensorflow.exam ...

  3. 数据可视化BI平台——CBoard的部署与使用(笔记整理)

    CBoard作为国内自主开发的数据可视化平台,因其方便好用而受到广大用户的使用和好评.现今CBoard有社区版和企业版两个版本,本文所述为社区版的0.4.2版本.注意:所需的一切资源以及相关参考链接都 ...

  4. 10. react 基础 ref 的使用 及 React 16 的生命周期函数 及 生命周期函数使用场景

    一. ref 的使用 ( 直接获取 DOM 元素 ) 在 input 标签上 可以使用 ref 属性 获取当前DOM节点 eg: import React , { Component, Fragmen ...

  5. Q8:String to Integer (atoi)

    8. String to Integer (atoi) 官方的链接:8. String to Integer (atoi) Description : Implement atoi to conver ...

  6. Java编程知识点梳理

    1. elementAt()   temp.elementAt(0) 返回temp这个vector里面存放的第一个元素--->也是一个vector类型. 2. 字符串空格分割 String [] ...

  7. git本地仓库连接同步修改远程仓库

    如何使用GIT BASH同步远程仓库 1. 新建一个目录 2. 右键GIT BASH 3. git clone git@github.com:purity12138/221701117.git (SS ...

  8. js filter()用法小结

    /* filter() 对数组中的每个元素都执行一次指定的函数(callback),并且创建一个新的数组, 该数组元素是所有回调函数执行时返回值为 true 的原数组元素.它只对数组中的 非空元素执行 ...

  9. SQL基础教程(第2版)第4章 数据更新:4-4 事务

    ●事务是需要在同一个处理单元中执行的一系列更新处理的集合. ● 事务处理的终止指令包括COMMIT(提交处理)和ROLLBACK(取消处理)两种. ● DBMS的事务具有原子性(Atomicity). ...

  10. 实现3d效果

    transform-origin: center left 60px;可以实现3d转换