用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. tensorflow--conv函数

    #第一种yolo3中程序 def convolutional(input_data, filters_shape, trainable, name, downsample=False, activat ...

  2. nginx重写常用写法

    1.将http协议重写成https协议: (用户用http进行访问,但后端是https),则可添加80 http端口监听,然后进行https rewrite; server {     listen ...

  3. Python说文解字_Python之多任务_05

    问:在Py3.5之前yield表现非常好,在Py3.5之后为了将予以变得更加明确,就引入了async和await关键词用于定义原生的协议. 答:async和await原生协程: async def d ...

  4. 学生信息的添加 Java web简单项目初试(失败)

    题目要求: 1登录账号:要求由6到12位字母.数字.下划线组成,只有字母可以开头:(1分) 2登录密码:要求显示“• ”或“*”表示输入位数,密码要求八位以上字母.数字组成.(1分) 3性别:要求用单 ...

  5. .NET httpClient Post请求,GET请求方法

    1.后端是WebAPI,POST请求,修饰符是[FromBody]的字符串,[FromBody]修饰的时候数据是来自body部分,而不是来自url部分,所以后端取值会自动映射出数据,比如后端是这样的, ...

  6. contos7 共享文件夹开机自动挂载

    网上很多文章都说改文件/etc/fstab 我试了很多次都不行 然后看到另一个方法 在/etc/rc.d/rc.local 增加挂在脚本这个时候要注意执行权限问题 我是这样做的 sudo mount ...

  7. Linux(CENTOS7) Jdk完整步骤安装

    方式一: 直接通过yum安装,这种方式比较方便,下面贴上安装jdk1.8*的命令: -openjdk* -y 上面命令执行完成之后,使用下面命令即可查看是否安装成功: java -version 方式 ...

  8. Python不区别字符串大小写的列表比较法

    一开始想这样写,结果报了索引错误 后来改正: if user_name.lower() in [names.lower() for names in names]: 我觉得应该是in后面应该跟列表,而 ...

  9. Django框架(十一):模板介绍、模板语言、模板继承、HTML转义

    1. 模板介绍 1.1 模板的功能 产生html,控制页面上展示的内容.模板文件不仅仅是一个html文件. 模板文件包含两部分内容: 静态内容:css.js.html. 动态内容:用于动态去产生一些页 ...

  10. 启动zookeeper却没有进程

    第一次: 没有jdk,安装好jdk就可以了 第二次: java的环境变量没配好,按照下图的配就行: Java_HOME和jre_HOME都是jdk的目录就行 最后两行不加试试,好像都没多大关系 应该是 ...