【kafka KSQL】游戏日志统计分析(1)
【kafka KSQL】游戏日志统计分析(1)
以游戏结算日志为例,展示利用KSQL对日志进行统计分析的过程。
启动confluent
cd ~/Documents/install/confluent-5.0.1/
bin/confluent start
查看kafka主题列表
bin/kafka-topics --list --zookeeper localhost:2181
创建接受游戏结算日志的topic
bin/kafka-topics --create --zookeeper localhost:2181 --replication-factor 1 --partitions 4 --topic score-normalized
使用生产者命令行工具往topic中写日志
bin/kafka-console-producer --broker-list localhost:9092 --topic score-normalized
>
{"cost":7, "epoch":1512342568296,"gameId":"2017-12-04_07:09:28_高手1区_200_015_185175","gameType":"situan","gamers": [{"balance":4405682,"delta":-60,"username":"0791754000"}, {"balance":69532,"delta":-60,"username":"70837999"}, {"balance":972120,"delta":-60,"username":"abc6378303"}, {"balance":23129,"delta":180,"username":"a137671268"}],"reason":"xiayu"}
使用消费者命令行工具查看日志是否正常写入
bin/kafka-console-consumer --bootstrap-server localhost:9092 --topic score-normalized --from-beginning
;; 可以看到
{"cost":7, "epoch":1512342568296,"gameId":"2017-12-04_07:09:28_高手1区_200_015_185175","gameType":"situan","gamers": [{"balance":4405682,"delta":-60,"username":"0791754000"}, {"balance":69532,"delta":-60,"username":"70837999"}, {"balance":972120,"delta":-60,"username":"abc6378303"}, {"balance":23129,"delta":180,"username":"a137671268"}],"reason":"xiayu"}
启动KSQL客户端
bin/ksql http://localhost:8088
可以看到ksql启动后的图标,和操作终端。
ksql终端查看kafka topic列表
ksql> show topics;
打印topic中的消息
PRINT 'score-normalized';
可以看到:
Format:STRING
19-1-5 下午11时59分31秒 , NULL , {"cost":7, "epoch":1512342568296,"gameId":"2017-12-04_07:09:28_\xE9\xAB\x98\xE6\x89\x8B1\xE5\x8C\xBA_200_015_185175","gameType":"situan","gamers": [{"balance":4405682,"delta":-60,"username":"0791754000"}, {"balance":69532,"delta":-60,"username":"70837999"}, {"balance":972120,"delta":-60,"username":"abc6378303"}, {"balance":23129,"delta":180,"username":"a137671268"}],"reason":"xiayu"}
其中:
- 第一个逗号
19-1-5 下午11时59分31秒表示消息时间。 - 第二个逗号
NULL为消息的Key,因为是从kafka-console-producer推送的,默认为NULL。 - 后面的就是推送过来的消息内容。
从topic score-normalized创建一个Stream
CREATE STREAM SCORE_EVENT \
(epoch BIGINT, \
gameType VARCHAR, \
cost INTEGER, \
gamers ARRAY< \
STRUCT< \
username VARCHAR, \
balance BIGINT, \
delta BIGINT \
> \
>, \
gameId VARCHAR, \
tax BIGINT, \
reason VARCHAR) \
WITH ( KAFKA_TOPIC='score-normalized', \
VALUE_FORMAT='JSON', \
TIMESTAMP='epoch');
其中TIMESTAMP='epoch'表示以epoch的时间为事件的时间戳。
删除一个STREAM
DROP STREAM stream_name ;
如果有查询语句在查询该流,则会出现错误:
Cannot drop USER_SCORE_EVENT.
The following queries read from this source: [].
The following queries write into this source: [CSAS_USER_SCORE_EVENT_2, InsertQuery_4, InsertQuery_5, InsertQuery_3].
You need to terminate them before dropping USER_SCORE_EVENT.
需要用TERMINATE命令停止这些查询语句,然后再删除流:
TERMINATE CSAS_USER_SCORE_EVENT_2;
TERMINATE InsertQuery_4;
从最早记录开始查询
ksql> SET 'auto.offset.reset' = 'earliest';
从Stream中查询所有数据
ksql> SELECT * FROM SCORE_EVENT;
可以看到:
1546702389664 | null | 1512342568296 | situan | 7 | [{USERNAME=0791754000, BALANCE=4405682, DELTA=-60}, {USERNAME=70837999, BALANCE=69532, DELTA=-60}, {USERNAME=abc6378303, BALANCE=972120, DELTA=-60}, {USERNAME=a137671268, BALANCE=23129, DELTA=180}] | 2017-12-04_07:09:28_高手1区_200_015_185175 | null | xiayu
其中:
- 第1列为记录的时间戳。
- 第2列为记录的key。
- 第3列以后就是消息中的各个字段的值,对应创建流时的顺序。
- 倒数第2列的null,是因为消息中
tax字段不存在。
统计2017-12-04日的对局总数
;; 增加一个game_date字段,用于统计
CREATE STREAM SCORE_EVENT_WITH_DATE AS \
SELECT SUBSTRING(gameId, 0, 10) AS game_date, * \
FROM SCORE_EVENT;
SELECT game_date, COUNT(*) \
FROM SCORE_EVENT_WITH_DATE \
WHERE game_date = '2017-12-04' AND reason = 'game' \
GROUP BY game_date;
目前KSQL还不支持类似下面的查询:
SELECT COUNT(*) \
FROM SCORE_EVENT \
WHERE gameId LIKE '2017-12-04_%';
统计参与对局的总玩家数(去重)
因为一条日志中包含多个玩家的对局信息,所以想法把每个玩家拆分成单独的事件
- 整合各个玩家的事件到一个统一的流
USER_SCORE_EVENT:
CREATE STREAM USER_SCORE_EVENT AS \
SELECT epoch, gameType, cost, gameId, tax, reason, gamers[0]->username AS username, gamers[0]->balance AS balance, gamers[0]->delta AS delta \
FROM SCORE_EVENT;
INSERT INTO USER_SCORE_EVENT \
SELECT epoch, gameType, cost, gameId, tax, reason, gamers[1]->username AS username, gamers[1]->balance AS balance, gamers[1]->delta AS delta \
FROM SCORE_EVENT;
INSERT INTO USER_SCORE_EVENT \
SELECT epoch, gameType, cost, gameId, tax, reason, gamers[2]->username AS username, gamers[2]->balance AS balance, gamers[2]->delta AS delta \
FROM SCORE_EVENT;
INSERT INTO USER_SCORE_EVENT \
SELECT epoch, gameType, cost, gameId, tax, reason, gamers[3]->username AS username, gamers[3]->balance AS balance, gamers[3]->delta AS delta \
FROM SCORE_EVENT;
- 为了后续用于玩家名username的连接
JOIN查询,需要重新设置Key:
CREATE STREAM USER_SCORE_EVENT_REKEY AS \
SELECT * FROM USER_SCORE_EVENT \
PARTITION BY username;
输出:
ksql> SELECT * FROM USER_SCORE_EVENT_REKEY;
4000 | lzc | 4000 | situan | 7 | 2017-12-04_07:09:28_高手2区_500_015_185175 | null | game | lzc | 972120 | -60
4000 | lzb | 4000 | situan | 7 | 2017-12-04_07:09:28_高手2区_500_015_185175 | null | game | lzb | 69532 | -60
注意:
实践过程中发现:只有对STREAM的field进行PARTITION BY才能生效。
- 统计各个玩家总的对局数、输赢总数、贡献的总税收,并以此创建一个表
USER_SCORE_TABLE:
CREATE TABLE USER_SCORE_TABLE AS \
SELECT username, COUNT(*) AS game_count, SUM(delta) AS delta_sum, SUM(tax) AS tax_sum \
FROM USER_SCORE_EVENT_REKEY \
WHERE reason = 'game' \
GROUP BY username;
查看USER_SCORE_TABLE所有数据:
ksql> SELECT * FROM USER_SCORE_TABLE;
1546709338711 | 70837999 | 70837999 | 4 | -240 | 0
1546709352758 | 0791754000 | 0791754000 | 4 | -240 | 0
1546709338711 | a137671268 | a137671268 | 4 | 720 | 0
1546709352758 | abc6378303 | abc6378303 | 4 | -240 | 0
- 查询某个玩家的对局数、输赢总数、贡献的总税收:
ksql> SELECT * FROM USER_SCORE_TABLE WHERE username = '70837999';
输出:
1546709338711 | 70837999 | 70837999 | 4 | -240 | 0
统计玩家总数(去重)
- 添加一个
傀儡列用于统计:
CREATE TABLE USER_SCORE_WITH_TAG AS \
SELECT 1 AS tag, * FROM USER_SCORE_TABLE;
- 统计去重后的玩家总数
SELECT tag, COUNT(username) \
FROM USER_SCORE_WITH_TAG \
GROUP BY tag;
续
KSQL WINDOW 功能。
【kafka KSQL】游戏日志统计分析(1)的更多相关文章
- scribe、chukwa、kafka、flume日志系统对比
scribe.chukwa.kafka.flume日志系统对比 1. 背景介绍许多公司的平台每天会产生大量的日志(一般为流式数据,如,搜索引擎的pv,查询等),处理 这些日志需要特定的日志系统,一 ...
- Nginx Access Log日志统计分析常用命令
Nginx Access Log日志统计分析常用命令 IP相关统计 统计IP访问量 awk '{print $1}' access.log | sort -n | uniq | wc -l 查看某一时 ...
- spark读取 kafka nginx网站日志消息 并写入HDFS中(转)
原文链接:spark读取 kafka nginx网站日志消息 并写入HDFS中 spark 版本为1.0 kafka 版本为0.8 首先来看看kafka的架构图 详细了解请参考官方 我这边有三台机器用 ...
- 项目01-flume、kafka与hdfs日志流转
项目01-flume.kafka与hdfs日志流转 1.启动kafka集群 $>xkafka.sh start 3.创建kafka主题 kafka-topics.sh --zookeeper s ...
- 一次flume exec source采集日志到kafka因为单条日志数据非常大同步失败的踩坑带来的思考
本次遇到的问题描述,日志采集同步时,当单条日志(日志文件中一行日志)超过2M大小,数据无法采集同步到kafka,分析后,共踩到如下几个坑.1.flume采集时,通过shell+EXEC(tail -F ...
- Kafka学习笔记之Kafka自身操作日志的清理方法(非Topic数据)
0x00 概述 本文主要讲Kafka自身操作日志的清理方法(非Topic数据),Topic数据自己有对应的删除策略,请看这里. Kafka长时间运行过程中,在kafka/logs目录下产生了大量的ka ...
- 转 Nginx Access Log日志统计分析常用命令
Nginx Access Log日志统计分析常用命令Nginx Access Log日志统计分析常用命令IP相关统计 统计IP访问量 awk '{print $1}' access.log | sor ...
- kafka对接Rancher日志
kafka对接Rancher日志 目录 kafka对接Rancher日志 概述 环境准备 正常对接kafka集群 1.helm添加bitnami库 2.下载 kafka 对应的chart压缩文件 3. ...
- 【转载】scribe、chukwa、kafka、flume日志系统对比
原文地址:http://www.ttlsa.com/log-system/scribe-chukwa-kafka-flume-log-system-contrast/ 1. 背景介绍许多公司的平台每天 ...
随机推荐
- CountDownLatch是个啥?
文章篇幅较短,对于一些AQS的顶级方法例如releaseShared并没有做过深的讲解,因为这些算是AQS的范畴,关于AQS可以看下另一篇文章--AQS. CountDownLatch一般被称作&q ...
- WinForm中DataGridView复制选中单元格内容解决方案
WinForm中DataGridView鼠标选中单元格内容复制方案 1.CTR+C快捷键复制 前提:该控件ClipboardCopyMode属性设置值非Disable: 2.鼠标框选,自定义代码实现复 ...
- Java中的数据结构-HashMap
Java数据结构-HashMap 目录 Java数据结构-HashMap 1. HashMap 1.1 HashMap介绍 1.1.1 HashMap介绍 1.1.2 HashMap继承图 1.2 H ...
- 【C++】VS2017 不能将const char * 分配给 char *
我的方式是把结构体中定义的 char * 换成string #include <iostream> #include<string> using namespace std; ...
- 35 编码 ASCII Unicode UTF-8 ,字符串的编码、io流的编码
* 编码表: * 信息在计算机上是用二进制表示的,这种表示法让人理解就很困难.为保证人类和设备,设备和计算机之间能进行正确的信息交换,人们编制的统一的信息交换代码,这就是ASCII码表 *ASCII ...
- Array(数组)对象-->pop() 方法
1.定义和用法 pop() 方法用于删除数组的最后一个元素并返回删除的元素. 语法: array.pop() 注意:此方法改变数组的长度! 举例: var arr = [1,2,3,4,5]; con ...
- CentOS7安装MYCAT中间件
MYCAT是一个被广泛使用的功能强大的开源的数据库中间件,当然他的理想不仅仅是做一个中间件.这篇文章主要记录MYCAT服务的搭建过程,下篇会继续更新MYCAT的使用配置. 本篇记录将使用CentOS7 ...
- Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(二)之Introduction to Objects
The genesis of the computer revolution was a machine. The genesis of out programming languages thus ...
- TCP基础概念
定义 传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的.可靠的.基于字节流的传输层通信协议 特点 TCP是一种面向广域网的通信协议,目的是在跨越多个网 ...
- Python - Python算法之冒泡算法的超简单实现
[原创]转载请注明作者Johnthegreat和本文链接 冒泡排序在算法中算是最简单也最容易实现的,这里介绍一个非常简单实现的代码: def bubble_sort(ls): for first in ...