介绍
建立每秒处理1,000,000和更多事件的数据管道并不是一件容易的事。 为了处理如此大的流量,应正确设计和实施所有数据管道组件。 幸运的是,并非所有数据管道组件都应从头开始构建。 开源社区提供了很多非常可靠的解决方案。 在本文中,我将展示如何仅通过使用免费和开放源代码构建块就可以构建数据摄取组件(它是数据管道中对容量最敏感的部分),而无需编写任何代码。
总览
现代化的数据管道应包含自动化数据移动,转换,分析和使用所需的所有步骤。 在下图中,您可以看到6步数据管道的高级数据流。 第一步包含所有数据生成源。 任何东西都可以成为数据生成源-软件系统,硬件设备甚至人类。 生成数据后,应将其提取到数据管道中。 第二步,收集/获取,提供收集和存储数据到数据存储中的所有必要组件。 数据存储后,即可进行处理。 数据处理的主要目标是准备数据以供分析数据库使用。 通常,它称为ETL-提取,转换和加载。 完成ETL后,可以对数据进行分析,然后由报告系统使用。
本文的主要重点是数据收集步骤。
数据收集/提取
可以通过拉或推将任何数据提取到数据管道。 在这里,我们将重点介绍通过推送获取数据,这意味着外部数据源通过将数据发送到某个已知接口来显式与数据管道交互。 此类接口的最佳示例是REST API。 将事件直接推送到数据管道的REST API是一种提取事件/事件批处理/日志文件的简单且难以置信的快速方式,特别适用于实时使用案例。 在下图上,您可以看到有关此类数据收集服务的示例。 数据源使用某些DNS名称生成数据并将其作为HTTP请求发送。 DNS名称在AWS Route53中解析为Nginx服务器IP地址。
无代码数据摄取的核心组件是Nginx和Fluentd。 两者都是免费和开源软件组件。 Nginx用作Web服务器,Fluentd用作日志传送组件。
Nginx的
内部Nginx Worker流程
Nginx是高性能的HTTP服务器,它处理传入连接,执行安全检查,应用速率限制,读取请求数据,将数据写入磁盘并将HTTP响应返回给客户端。 在下图中,您可以看到Nginx内部的处理管道。 这里最有趣的步骤是带有感叹号图标的步骤。 如果要使用可处理HTTP请求的代码实现,则应添加上游配置。 例如,uWSGI,Python和Flask / Django或FastCGI和C ++将完成工作。 在我们的情况下,我们正在寻找一种无代码解决方案,因此不使用上游。 所有传入的数据都以Nginx日志的形式收集在" access.log"文件中。
Nginx配置
从Nginx开始最方便的方法之一是使用Nginx官方docker映像。 这是我们非常简单的docker文件:我们正在使用DockerHub中的Nginx映像,删除默认的Nginx配置文件并复制data-ingest.conf。
FROM nginx
RUN rm /etc/nginx/conf.d/*
ADD data-ingest.conf /etc/nginx/conf.d/
第二个文件是data-ingest.conf-Nginx配置。 该文件在GitHub上完全可用。 在这里,我想解释一下/ events位置最有趣的配置部分。 通过使用提供的配置,Nginx将处理/ events GET请求并将请求数据记录到/var/log/nginx/events_data.log
location /event {
default_type text/plain;
add_header Allow "GET" always;
access_log /var/log/nginx/events_data.log getdata;
if ( $request_method !~ ^(GET)$ ) {
return 405 'GET allowed only';
}
return 200 '$time_localURI: $request_uri:$request_id';
}
Fluentd
Fluentd是最初由Treasure Data开发的跨平台开源数据收集软件项目。 它可与其他日志传送器(如logstash,Apache flume,rsyslog)相媲美,但在可用插件数量方面具有明显的优势。
与Nginx一样,从Fluentd开始的最佳方法是使用其docker映像之一。 在随附的流畅的Dockerfile部分(完整的Docker文件在此处)上,您可以看到已添加Apache Kafka和AWS S3插件。
RUN apk update && apk add --no-cache ca-certificates ruby ruby-irb su-exec==${SU_EXEC_VERSION}-r0 dumb-init==${DUMB_INIT_VERSION}-r0 && apk add --no-cache --virtual .build-deps build-base ruby-dev gnupg && echo 'gem: --no-document' >> /etc/gemrc && gem install oj -v 2.18.3 && gem install json -v 2.1.0 && gem install fluentd -v 0.14.25 && gem install fluent-plugin-kafka --no-document && gem install fluent-plugin-s3 -v 1.0.0 --no-document && apk del .build-deps && rm -rf /tmp/* /var/tmp/* /usr/lib/ruby/gems/*/cache/*.gem
流利的配置文件使用户可以控制输入和输出行为。 对于数据收集AP,Fluentd仅使用一个数据源(Nginx日志文件)以及两个输出AWS S3和stdout构建。 基于此配置,Fluentd将尾部/var/log/nginx/events_data.log尾部l保留所有行(parse = none)到输出存储中。
@type tail path /var/log/nginx/events_data.log pos_file /var/log/fluentd/td-agent/access.log.pos tag nginx.access @type none @type copy @type stdout @type file path /var/log/fluentd @type s3 # aws key_id and key are optional for EC2 with IAM Role #aws_key_id YOUR_AWS_KEY_ID #aws_sec_key YOUR_AWS_SECRET_KEY # change bucket name and region s3_bucket e2e-test-io s3_region us-west-2path logs/ s3_object_key_format %{path}%{time_slice}_%{index}.%{file_extension} buffer_path /var/log/fluent/s3 time_slice_format %Y%m%d-%H-%M time_slice_wait 1m utc format json
将输出写入AWS S3时,Fluentd将每分钟创建一个S3对象(time_slice_wait 1m),并且对象名称将具有以下模式—%Y%m%d-%H-%M。 例如,它看起来像是20191203–17–01_0.gz。
运行
要大致了解Data Collect API的工作原理,可以在本地运行它。 只需克隆以下存储库:
git clone https://github.com/dimastatz/no-code-data-ingest.git.
确保您的计算机上具有所有必需的先决条件git,docker和docker-compose
克隆存储库后,导航至no-code-data-ingest文件夹,并将执行权限添加到run_all.sh和stop_all.sh。 例如,您可以执行以下操作:
$ cd no-code-data-ingest/ $ chmod -R 777 *.sh
之后,导航至no-code-data-ingest / fluentd文件夹,编辑fluent.conf以设置您的AWS区域和存储桶。
现在您可以运行run_all.sh脚本
$ ./run_all.sh
该bash脚本通过设置所有必需的文件夹和权限来准备本地计算机,然后运行docker-compose.yml。 docker-compose.yml定义Nginx和Fluentd服务,并在/ tmp / data-collector上挂载共享卷。
version: '3'services: nginx: build: nginx/. volumes: - /tmp/data-collector:/var/log/ ports: - "8080:8080" fluentd: build: fluentd/. volumes: - /tmp/data-collector:/var/log/ ports: - "8888:24224"
运行run_all.sh之后,您将在终端中看到Docker构建了Nginx和Fluentd映像。
Building nginxStep 1/3 : FROM nginxlatest: Pulling from library/nginx000eee12ec04: Pull completeeb22865337de: Pull completebee5d581ef8b: Pull completeDigest: sha256:50cf965a6e08ec5784009d0fccb380fc479826b6e0e65684d9879170a9df8566Status: Downloaded newer image for nginx:latest ---> 231d40e811cdStep 2/3 : RUN rm /etc/nginx/conf.d/* ---> Running in d1d40abbd03cRemoving intermediate container d1d40abbd03c ---> 89a1280987b5Step 3/3 : ADD data-ingest.conf /etc/nginx/conf.d/ ---> eee6692acf94Successfully built eee6692acf94Successfully tagged no-code-data-ingest_nginx:latestBuilding fluentdStep 1/18 : FROM alpine:3.53.5: Pulling from library/alpine
完成构建过程后,docker-compose将运行Nginx和Fluentd容器,您将看到Fluentd正在运行并遵循Nginx events_data.log的尾部。
fluentd_1 | 2019-12-04 13:15:25 +0000 [info]: #0 starting fluentd worker pid=14 ppid=6 worker=0fluentd_1 | 2019-12-04 13:15:26 +0000 [info]: #0 following tail of /var/log/nginx/events_data.logfluentd_1 | 2019-12-04 13:15:26 +0000 [info]: #0 fluentd worker is now running worker=0
现在,您可以执行端到端测试。 打开一个新终端并运行以下curl命令
$ curl localhost:8080/event?data=event_content
Curl在8080端口上对本地HTTP服务执行HTTP GET请求。 Nginx将处理该请求并将其写入events_data.log文件。 之后,Fluentd将把events_data.log发送到stdout:
2019-12-04 13:26:25.935724194 +0000 nginx.access: {"message":"04/Dec/2019:13:26:25 +0000, GET, data=event_content, 264, 200"}
Fluentd还将日志发送到AWS S3:
$ aws s3 ls e2e-test-io/logs/2019-12-03 17:01:46 118 20191203-17-01_0.gz2019-12-03 17:04:01 119 20191203-17-02_0.gz2019-12-03 17:06:02 98 20191203-17-04_0.gz2019-12-03 17:07:02 92 20191203-17-05_0.gz
就是这样,现在您有了有效的Data Collect API,可将日志发送到AWS S3。 通过编辑fluent.conf,您可以添加您选择的任何输出存储:Apache Kafka,AWS Kinesis,ElasticSearch,Splunk,BigQuery等。
性能
NGINX以其出色的性能而闻名。 Nginx使用非同步的,事件驱动的架构来应对这种巨大的负载。 它可以承受高负载以及负载变化很大的负载,并利用RAM使用率,CPU使用率和延迟的预测来提高效率。 通过使用https://openbenchmarking.org/,您可以发现Nginx可以在每个内核上处理多达10K RPS。 从https://www.nginx.com/blog/testing-the-performance-of-nginx-and-nginx-plus-web-servers/查看更乐观的基准测试时,我们可以在单个服务器上看到多达40K RPS 核心和32核心上的1.2M。 当然,这取决于配置和设置细节,但最重要的是可以实现1M RPS的目标。
结论
随着开放源代码构建块的数量和质量的增长,同时由于公司处理的软件开发人员数量有限,无代码开发方法越来越受欢迎。 在此示例中,我们看到可以通过编写零行代码来构建用于高负载管道的数据摄取,并且所有涉及的构建块都是完全免费的。
(本文翻译自Dima Statz的文章《No-Code Data Collect API》,参考:https://medium.com/swlh/no-code-data-collect-api-f8e934ed8535)