数据采集

一、项目介绍

1.1 项目规划

大数据共设计 四个项目 ,项目 总时间8~9周 ,依照 采,传,存,取,用 的模式,设计为
数据采集&监控[一 周] ,
准实时数仓&用户画像[四周] ,
推荐系统[二周] ,
实时数仓[一周] 四个项目

1.2 数据采集&监控的项目架构

1)架构一(我们要使用的)
在这里插入图片描述
2)架构二(涉及到kafka,spark,flink。等学到后,由学员自己完成)
在这里插入图片描述

1.3 项目背景

  1. 数据从何处来
  2. 数据有哪些类型
  3. 针对于不同的数据进行搜集的工具
  4. 采集数据的指标监控
  5. 采集过程的警报
  6. 性能优化

1.4 数据分类

搜集的数据,都应该是自己公司的产品的数据。这个项目我们是模拟一些数据。比如C端的日志数据,内容数据,还有RDBMS里的业务数据。

  1. 日志数据

指的是用户与app进行交互时产生的行为数据。比如在什么时间登陆,点击了什么栏目这些数据

  1. 内容数据

app上发表的文件,图片,音频,视频等

3)业务数据

业务系统在RDBMS中存储的表数据,通常是业务中的增删改对应的数据

4)元数据

用来描述表的数据,称之为元数据,比如mysql中的

1.5 数据格式

  1. 日志数据

原始base64

eyJjb25ldG50Ijp7ImRpc3RpbmN0X2lkIjoiNjkyNDA3MiIsInByb3BlcnRpZXMiOnsibW9kZWwiOiJIUlktQUwwMGEiLCJuZXR3b3JrX3R5cGUiOiJXSUZJIiwiaXNfY2hhcmdpbmciOiIyIiwiYXBwX3ZlcnNpb24iOiI0LjQuNSIsImVsZW1lbnRfbmFtZSI6IuaIkeeahOmSseWMhemhtSIsImVsZW1lbnRfcGFnZSI6IummlumhtSIsImNhcnJpZXIiOiLkuK3lm73np7vliqgiLCJvcyI6ImFuZHJvaWQiLCJpbWVpIjoiOTM4ZDczMWY0MTg3NGRhMCIsImJhdHRlcnlfbGV2ZWwiOiI2OSIsInNjcmVlbl93aWR0aCI6IjEwODAiLCJkZXZpY2VfaWQiOiJlZDcxZDdkZi0yZjVjLTY2ZDMtY2JmYi01M2Y1NWJjNzg5OTkiLCJjbGllbnRfdGltZSI6IjIwMjAtMDQtMjUwNzo1OTo1MCIsImlwIjoiMTIxLjU2Ljc5LjQiLCJ3aWZpIjoiMSIsIm1hbnVmYWN0dXJlciI6IkhVQVdFSSIsInNjcmVlbl9oZWlnaHQiOiIyMzQwIn0sImV2ZW50IjoiQXBwQ2xpY2sifSwicHJvamVjdCI6Im5ld3MiLCJjdGltZSI6IjE1ODc3NzU3NDUifQo=
– decode之后的json
{
“content”: {
“distinct_id”: “6924072”, # 用户ID
“properties”: {
“model”: “HRY-AL00a”, #机型
“network_type”: “WIFI”, #用户网络类型
“is_charging”: “2”, #是否充电中
“app_version”: “4.4.5”, #app版本
“element_name”: “我的钱包页”, #元素名称
“element_page”: “首页”, #元素所在页面
“carrier”: “中国移动”, #运营商
“os”: “android”, #操作系统
“imei”: “938d731f41874da0”, #手机IMEI号
“battery_level”: “69”, #手机电量
“screen_width”: “1080”, #屏幕宽度
“device_id”: “ed71d7df-2f5c-66d3-cbfb-53f55bc78999”, #设备ID
“client_time”: “2020-04-25 07:59:50”,#客户端上报此条日志时间
“ip”: “121.56.79.4”, #客户端IP地址
“manufacturer”: “HUAWEI”, #制造商
“screen_height”: “2340”, #屏幕高度
“client_time”:“1587771745000” # 客户端上报日志时间
},
“event”: “AppClick” # 事件名称
},
“project”: “news”, #产品名称
“ctime”: “1587775745000” #服务器接收到日志时间
}

2 ) 内容数据

{
“article_id”: 487186016, # 文章ID,新闻的唯一标识
“type_name”: " 科技", #新闻类型
“pub_time”: “2020-04-20 19:45:36.919”, # 新闻发布时间
“title”: “小米10pro 30w无线充电对比华为40w有线充电”, # 新闻标题
“content”: “

之前做了一个小米10pro 30w无线充电对比华为40w有线充电,米10pro无线充电充满只需要55分钟。这次oppoACE2,看了其他媒体测试的40w快充,前半小时还比不上米10pro,总时间才快了5分钟。然而一个40w,一个30w,一个4000毫安,一个4500毫安。。。这40w真的阳痿

<img src=“http://fwimage.cnfanews.com/websiteimg/2020/20200421/29002919/ 2013b7e.jpg” style=“max-width:600px;”>

”, # 新闻内容html格式
“source_name”: “今日头条移动端-数码”, # 新闻来源
“tags”: “pro,充电,小时,测试,充满,比不上,需要” # 内容标签
}

3)业务数据

– 元信息表,已经过简化
CREATE TABLE meta (
id int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT ‘自增ID,主键’,
field varchar(50) NOT NULL DEFAULT ‘’ COMMENT ‘字段名称’,
filed_type varchar(20) NOT NULL DEFAULT ‘’ COMMENT ‘字段类型’,
field_desc varchar(255) DEFAULT NULL COMMENT ‘字段说明’,
app_version varchar(10) NOT NULL DEFAULT ‘’ COMMENT ‘上线版本号’,
status tinyint(4) DEFAULT ‘0’ COMMENT ‘字段状态,0 下线 1 上线’,
create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘创建时间’,
update_time timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT ‘更新时间’,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
– 广告信息表,已经过简化
CREATE TABLE ad_info (
id int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT ‘自增ID,主键’,
ad_id int(11) DEFAULT NULL COMMENT ‘广告ID’,
advertiser_id int(11) DEFAULT NULL COMMENT ‘广告商ID,一个广告商会投放多个广告’,
advertiser_name varchar(255) DEFAULT NULL COMMENT ‘广告商名称’,
create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘创建时间’,
update_time timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT ‘更新时间’,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

二、项目架构的部署

2.2 Nginx接口部署及其测试

2.2.1 目录结构说明

因为要使用openresty来存储行为数据,也就是要用openresty内嵌的nginx先采集日志,因此设计一下目录结构

– 用于存储此应用的各种信息的根目录
sudo mkdir -p /opt/apps/collect-app/
–用于存储此应用的nginx的主配置文件
sudo mkdir -p /opt/apps/collect-app/conf/
– 用于存储此应用的nginx的access.log error.log
sudo mkdir -p /opt/apps/collect-app/logs/
– 用于存储此应用的nginx的副配置文件
sudo mkdir -p /opt/apps/collect-app/conf/vhost/
– 拷贝nginx的mine.types文件到此采集项目的conf目录下
sudo cp /usr/local/openresty/nginx/conf/mime.types /opt/apps/collect-app/conf/

2.2.2 主配置文件的配置

编写此采集项目的nginx的主配置文件,命名为main-nginx.conf, 放到/opt/apps/collect-app/conf/ 目录下

# nginx 用户和组
user root root;
# work进程数,
worker_processes 4;
# 错误日志路径,和日志级别    
error_log logs/collect-app-error.log error;
# nginx pid文件
pid       logs/collect-app-nginx.pid;
# 单个worker最大打开的文件描述符个数
worker_rlimit_nofile 65535;
events
{
	#使用epoll模型, 一个优化策略
	use epoll;
	# 单个worker进程允许的最多连接数
	worker_connections 65535;
}
http
{
	include mime.types;
	default_type application/octet-stream;
	gzip on;
    # 指定压缩的最小字节数
	gzip_min_length 1k;
    # 16k是 缓冲的单位,4是倍数,可以是其他值作为倍数
	gzip_buffers 4 16k;
	gzip_http_version 1.0;
    # 压缩等级
	gzip_comp_level 2;
    # 可以压缩的文件类型
	gzip_types text/plain application/x-javascript text/css application/xml;
    #启用应答头"Vary: Accept-Encoding"
	gzip_vary on;
    # 参数中的下划线是否忽略,on表示忽略
	underscores_in_headers on;
	log_format main
		'$remote_addr - $remote_user [$time_local] '
		'$request_length '
		 '"$request" $status $bytes_sent $body_bytes_sent '
		'"$http_referer" "$http_user_agent" '
		'"$gzip_ratio" "$request_time" '
		'"$upstream_addr" "$upstream_status" "$upstream_response_time"';
	# 定义我们数据采集的 access 日志格式
	log_format collect-app-log-format '$cad';   
	open_log_file_cache max=1000 inactive=60s;
	keepalive_timeout 0;
	client_max_body_size 20m;
	include /opt/apps/collect-app/conf/vhost/*.conf;
}
在这里插入代码片

测试主配置文件:因为里面的变量cad还没有定义,就直接使用,所以会报错,继续配置下去就行,不用管

[root@qianfeng01 conf]# openresty -p /opt/apps/collect-app -c conf/main-nginx.conf -t

报以下错误
nginx: [emerg] unknown "cad" variable
nginx: configuration file /opt/apps/collect-app/conf/main-nginx.conf test failed

2.2.3 副配置文件的配置

编写此采集项目的nginx的副配置文件,命名为minor-nginx1.conf, 放到/opt/apps/collect-app/conf/vhost/ 目录下

#minor-nginx1.conf
server {
      listen  8802 default_server;
      # lua_need_request_body on;
      client_max_body_size 5M;
      client_body_buffer_size 5M;   
      location /data/v1 {
          set $cad  '';
    	  content_by_lua_block {
              -- cjson模块
              local cjson = require "cjson"
              -- 读取请求体信息
              ngx.req.read_body()
              -- 请求体信息存放到 body_data变量中
              local body_data = ngx.req.get_body_data()
              -- 如果请求体为空,返回错误
              if body_data == nil  then
                ngx.say([[{"code":500,"msg":"req body nil"}]])
                return 
              end
              -- 定义当前时间
              local current_time = ngx.now()*1000
              -- 请求的URL project参数中获取其值
              local project = ngx.var.arg_project
              -- 定义一个字典,存放有当前服务为日志增加的信息,如ctime表示接受到请求的时间,ip地址等
              local data={}
              data["project"] = project
              data["ctime"] = current_time
              if ngx.var.http_x_forwarded_for == nil then
                data["ip"] = ngx.var.remote_addr;
              else
                data["ip"] = ngx.var.http_x_forwarded_for
              end
              -- 将增加的信息编码为json
              local meta = cjson.encode(data)
              -- 将编码的json信息做base64 和 body_data拼接
              local res = ngx.encode_base64(meta) .. "-" .. ngx.unescape_uri(body_data)
              -- 将数据赋值给我们定义的nginx变量cad中,我们定义的log_format就使用这个变量的值
              ngx.var.cad = res 
              ngx.say([[{"code":200,"msg":"ok"}]])
   			}
          access_log  logs/collect-app-access.log  collect-app-log-format;
      }
}

再次进行测试主配置文件

[root@qianfeng01 conf]# openresty -p /opt/apps/collect-app -c conf/main-nginx.conf -t

2.2.4 测试Nginx的收集功能

1)启动nginx

[root@qianfeng01 conf]# openresty -p /opt/apps/collect-app -c conf/main-nginx.conf 

2)检查nginx

ps -ef | grep nginx
netstat -nltp | grep nginx

3)模拟用户登录访问网址

[root@qianfeng01 conf]#curl -X POST 'http://localhost:8802/data/v1?project=news' -d  helloworld 
{"code":200,"msg":"ok"}

注意:如果没有-d,也就没有发送正文数据即
[root@qianfeng01 conf]#curl -X POST 'http://localhost:8802/data/v1?project=news'
会出现{"code":500,"msg":"req body nil"}

4)检查一下日志文件

[root@qianfeng01 ~]# cd /opt/apps/collect-app/logs
[root@qianfeng01 logs]# cat collect-app-access.log
eyJwcm9qZWN0IjoibmV3cyIsImlwIjoiMTI3LjAuMC4xIiwiY3RpbWUiOjE2MDQzMDAyMTA4ODJ9-helloworld

可以看到是加密的前缀使用-和正文拼接

对前缀进行解密:
[root@qianfeng01 logs]# echo "eyJwcm9qZWN0IjoibmV3cyIsImlwIjoiMTI3LjAuMC4xIiwiY3RpbWUiOjE2MDQzMDAyMTA4ODJ9"|base64 -d

{"project":"news","ip":"127.0.0.1","ctime":1604300210882}

2.2.5 管理中心注册网址

目的:让外网可以识别本机(虚拟机)
1)下载frp 客户端

#创建目录用于存储frp的执行文件
[root@qianfeng01 logs]# mkdir /usr/local/frp/ && cd /usr/local/frp
#下载
wget http://doc.yihongyeyan.com/qf/project/soft/frp/frpc_0.33.linux_adm64.tgz 
#解压到当前目录下
tar -xvzf frpc_0.33.linux_adm64.tgz

2)使用frpc注册子域名。注册成功,域名就相当于指向了本机

语法: /usr/local/frp/frpc --sd name -l 8802 -u name
注意:name要换成你喜欢的字符串

比如:
[root@qianfeng01 local]# ./frp//frpc http --sd michael1001 -l 8802 -u michael1001

3)测试是否有效

curl http://name.frp.yihongyeyan.com/data/v1?project=news -d test_data
返回结果{"code":200,"data":true},表明测试成功

4)将域名配置到管理中心的管理模块中

目的:模拟用户向本机持续不断的发送数据。

# 接下来把此地址通过命令,配置到管理中心,你只需要把下方命令中 data_url=后面的地址替换成你的地址, name参数的值换成你的名字拼音全拼
curl -X POST \
  http://metadata.yihongyeyan.com/qf/api/v1/meta/register \
  -F data_url=http://michael1001.frp.yihongyeyan.com/data/v1?project=news \
  -F type=1 \
  -F name=michael1001
# 请求成功后会有如下图返回值
{"code":200,"data":{"id":2480,"data_url":"http://michael1001.frp.yihongyeyan.com/data/v1?project=news","type":"1","name":"michael1001","created_at":1604302530,"updated_at":1604302530},"error_code":0,"msg":"ok","status":200}

  1. 检查日志文件中是否在持续增加数据
[root@qianfeng01 logs]# cat collect-app-access.log
其中每一条记录都是用-拼接了前缀和正文

6)注意

当下次再启动模拟数据持续发送时,只需要执行第二步

2.3 flume采集行为数据

2.3.1 flume的source源分析

  1. 尽量使用可靠源,因此exec source源被排除
  2. 可靠源有spooling dir 和taildir。
  3. 由于我们要采集logs目录下的 collect-app-access.log,>因此可以使用taildir来监听并采集。
    不会有一个缺点,就是此日志文件会越来越大。
  4. 如果我们要使用spooling dir,它的特点是监听新文件,一旦更名后,后续的新文件就不同于之前的文件同名。

注意,3和4的问题都可以想办法解决,在这

里我们使用4,并解决它的缺点。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值