[2.0快速体验]Apache Doris 2.0 日志分析快速体验

1. 概述

应用程序、服务器、云基础设施、IoT 和移动设备、DevOps、微服务架构—最重要的业务和 IT 发展趋势帮助我们以前所未有的方式优化运维和客户体验。但这些趋势也导致由机器生成的数据出现爆炸式成长,其中包括日志和指标等,例如,用户交易、客户行为、传感器活动、机器行为和安全威胁等。这些数据十分复杂,但同时也最为重要,因为它们包含关于 IT、安全和业务的运维情报。

日志分析涉及到对由您的 IT 系统和技术基础设施生成的机器数据进行搜索、分析与可视化,以便获得运维方面的见解。传统的数据分析工具已不能胜任如此多样性而且快速增加的机器数据的处理工作。

日志数据在不断增长。如果没有一个整体的、具有成本意识的解决方案,成本将继续不受控制地增长。人类数据和机器生成的数据正在以惊人的速度增长,其中人类生成的数据的增长率通常是商业数据的 10 倍。机器数据预计将增长更多。

传统的日志分析场景,直接在日志文件中 grep、awk 就可以获得自己想要的信息。但在规模较大的场景中,此方法效率低下,面临如下问题:

  1. 日志量太大如何归档?
  2. 文本搜索太慢怎么办?
  3. 如何多维度查询及关联查询分析等等

解决上面的问题,需要集中化的日志管理,所有服务器上的日志收集汇总。常见解决思路是建立集中式日志收集系统,将所有节点上的日志统一收集,管理,访问。ELK就是解决这些问题的一种解决方案。

我们知道 Apache Doris 是一个基于 MPP 架构的高性能、实时的分析型数据库,以极速易用的特点被人们所熟知,仅需亚秒级响应时间即可返回海量数据下的查询结果,不仅可以支持高并发的点查询场景,也能支持高吞吐的复杂分析场景。基于此,Apache Doris 能够较好的满足报表分析、即席查询、统一数仓构建、数据湖联邦查询加速等使用场景,用户可以在此之上构建用户行为分析、AB 实验平台、日志检索分析、用户画像分析、订单分析等应用。

如果我们希望使用 Apache Doris 来更好解决日志存储与分析场景的痛点,其实现路径也非常清晰——在数据库内部增加倒排索引、以满足字符串类型的全文检索和普通数值/日期等类型的等值、范围检索,同时进一步优化倒排索引的查询性能、使其更加契合日志数据分析的场景需求

在Apache Doris 2.0 给大家带来了全新的倒排索引,利用Doris的MPP执行框架、向量化计算引擎、列式存储、标准SQL、CBO的查询优化器等特性为用户提供高性能,低成本的日志分析服务。

通过在 Apache Doris 2.0.0 最新版本的探索与持续优化,在相同硬件配置和数据集的测试表现上,Apache Doris 在数据库内核实现高性能倒排索引后,相对于 ES 实现了日志数据写入速度提升 4 倍、存储空间降低 80%、查询性能提升 2 倍,再结合 Apache Doris 2.0.0 版本引入的冷热数据分离特性,整体性价比提升 10 倍以上!

关于Doris 倒排索引的更多介绍可以参考:https://mp.weixin.qq.com/s/WJXKyudW8CJPqlUiAro_KQ

下面我们将以Apache Doris 2.0 为例给大家演示怎么使用Doris来进行日志分析。我将使用下列组件来完成这个工作。演示环境是在Macos(M1芯片) 下,如果你在Linux 系统下,操作也是一样的。

  1. Apache Doris 2.0
  2. Logstash-7.17.4
  3. Filebeats-8.7.1
  4. Grafana

2. 系统安装

2.1 安装 Doris

如果你是其他Linux 系统可以直接从官网下载预编译好的Doris 2.0 安装包:

https://doris.apache.org/zh-CN/download

如果你也是Macos系统,可以参考官网文档进行本地编译:

https://doris.apache.org/zh-CN/docs/1.2/install/source-install/compilation-mac

安装可以参考:

https://zhuanlan.zhihu.com/p/559718796

2.2 安装 Nginx

Nginx的安装我也是通过Brew 安装的,其他平台的Nginx安装,请自行搜索,

brew install nginx

首先我们这里分析的是Nginx的日志信息,我对Nginx的日志格式进行了调整,特别是时间具体的配置信息如下:

这里调整了 log_format 配置,每个字段时间分隔符指定成了 # ,同时将时间格式调成yyyy-MM-dd HH:mm:ss 格式

#user nobody;
worker_processes 1;

#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#pid       logs/nginx.pid;

events {
  worker_connections 1024;
}

http {
  include       mime.types;
  default_type application/octet-stream;

  log_format main '$year-$month-$day $hour:$minutes:$seconds#$remote_addr#$remote_user#"$request"#"$uri"#'                   '$status#$request_time#$request_length#$body_bytes_sent#$bytes_sent#$ssl_protocol#$ssl_cipher#'
                  '$http_referer#$http_x_forwarded_for#"$http_user_agent"';

  #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  #                 '$status $body_bytes_sent "$http_referer" '
  #                 '"$http_user_agent" "$http_x_forwarded_for"';
  access_log logs/access.log main;

  sendfile       on;
  #tcp_nopush     on;

  #keepalive_timeout 0;
  keepalive_timeout 65;

  #gzip on;

  server {
      listen       80;
      server_name localhost;

      #charset koi8-r;
     if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})") {
         set $year $1;
         set $month $2;
         set $day $3;
         set $hour $4;
         set $minutes $5;
         set $seconds $6;
     }

      #access_log logs/host.access.log main;

      location / {
          root   html;
          index index.html index.htm;
      }

      #error_page 404             /404.html;

      # redirect server error pages to the static page /50x.html
      #
      error_page   500 502 503 504 /50x.html;
      location = /50x.html {
          root   html;
      }
  }

  include servers/*;
}

Nginx 安装好之后只有一个默认的欢迎页,我这边为了生成更多日志,我在Nginx下本地部署了Doris的官网

访问后生成的日志格式如下:

2023-05-23 00:17:49#127.0.0.1#-#"GET /zh-CN/blog/summit HTTP/1.1"#"/zh-CN/blog/summit"#301#0.000#838#169#379#-#-#-#-#"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.0.0"
2023-05-23 00:17:49#127.0.0.1#-#"GET /zh-CN/blog/summit/ HTTP/1.1"#"/zh-CN/blog/summit/index.html"#200#0.000#839#65503#65744#-#-#-#-#"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.0.0"

2.3 安装Logstash

我这边是直接使用 Brew 进行直接安装的,安装命令如下:

brew install elastic/tap/logstash-full

Logstash 配置文件目录:/opt/homebrew/etc/logstash

启动命令目录:/opt/homebrew/Cellar/logstash-full/7.17.4/bin/logstash

创建并使用管道配置文件:一个 Logstash 管理通常有一个或多个 input, filter 和 output 插件

验证通道,我们使用命令行输入级命令行输出的方式

/opt/homebrew/Cellar/logstash-full/7.17.4/bin/logstash -e 'input { stdin { } } output { stdout { } }'

随便输入一串数组回车可以看到下面的信息:

image.png

我们在 Logstash 配置目录下创建一个新的Doris的管道配置文件:doris.yaml

input {
beats {
  host =>"192.168.66.95"
  port => 5044
}
}
output {
  doris {
      http_hosts => [ "http://192.168.66.95:8030" ]
      user => "root"
      password => "zhangfeng"
      db => "demo"
      table => "nginx_log"
      label_prefix => "doris_logstash_nginx_log"
      column_separator => "#"
      columns => "http_time ,remote_addr,remote_user,request ,uri ,status,request_time,request_length,body_bytes_sent,bytes_sent ,ssl_protocol ,ssl_cipher ,http_referer ,http_x_forwarded_for ,http_user_agent"
  }
}

具体Doris的管道配置说明如下:

连接相关配置:

配置 说明
http_hosts FE的HTTP交互地址。 例如: ["http://fe1:8030", "http://fe2:8030"]
user 用户名,该用户需要有doris对应库表的导入权限
password 密码
db 数据库名
table 表名
label_prefix 导入标识前缀,最终生成的标识为 {label_prefix}{db}{table}_{time_stamp}

导入相关配置:(参考文档

配置 说明
column_separator 列分割符,默认为\t。
columns 用于指定导入文件中的列和 table 中的列的对应关系。
where 导入任务指定的过滤条件。
max_filter_ratio 导入任务的最大容忍率,默认零容忍。
partition 待导入表的 Partition 信息。
timeout 超时时间,默认为600s。
strict_mode 严格模式,默认为false。
timezone 指定本次导入所使用的时区,默认为东八区。
exec_mem_limit 导入内存限制,默认为 2GB,单位为字节。

其他配置

配置 说明
save_on_failure 如果导入失败是否在本地保存,默认为true
save_dir 本地保存目录,默认为 /tmp
automatic_retries 失败时重试最大次数,默认为3
batch_size 每批次最多处理的event数量,默认为100000
idle_flush_time 最大间隔时间,默认为20(秒)

启动指定管道的命令如下:

/opt/homebrew/Cellar/logstash-full/7.17.4/bin/logstash -f /opt/homebrew/etc/logstash/doris.yaml --config.reload.automatic

启动之后,Logstash 开始通过管道 Input 采集数据,然后按照管道 output 配置的输出管道输出到指定的地方。

2.4 安装Filebeats

我这边是直接使用 Brew 进行直接安装的,安装命令如下:

brew install filebeat

配置 Filebeats

vi /opt/homebrew/etc/filebeat/filebeat.yml

修改下面几项:

filebeat.inputs:

# Each - is an input. Most options can be set at the input level, so
# you can use different inputs for various configurations.
# Below are the input specific configurations.

# filestream is an input for collecting log messages from files.
- type: log

# Unique ID among all inputs, an ID is required.
id: my-filestream-id

# Change to true to enable this input configuration.
enabled: true

# Paths that should be crawled and fetched. Glob based paths.
paths:
  - /opt/homebrew/Cellar/nginx/1.23.4/logs/access.log
  #- c:\programdata\elasticsearch\logs\*

  ......

#output.elasticsearch:
# Array of hosts to connect to.
hosts: ["localhost:9200"]

# Protocol - either `http` (default) or `https`.
#protocol: "https"

# Authentication credentials - either API key or username/password.
#api_key: "id:api_key"
#username: "elastic"
#password: "changeme"

# ------------------------------ Logstash Output -------------------------------
output.logstash:
# The Logstash hosts
hosts: ["192.168.66.95:5044"]

  1. type :改成 log
  2. enabled :改成 true
  3. paths :这里是你要采集的日志文件路径
  4. output.elasticsearch :注释掉
  5. output.logstash :打开

启动Filebeats

/opt/homebrew/opt/filebeat/bin/filebeat -e -c /opt/homebrew/etc/filebeat/filebeat.yml -d "publish"

2.5 编译安装 Doris Logstash 插件

下载 Doris 源码:

git clone https://github.com/apache/doris.git

在extension/logstash/ 目录下执行

gem build logstash-output-doris.gemspec

你将在同目录下得到 logstash-output-doris-{version}.gem 文件

安装 Doris Logstash 插件:

/opt/homebrew/opt/filebeat/bin/filebeat -e -c /opt/homebrew/etc/filebeat/filebeat.yml logstash-output-doris-{version}.gem

安装成功之后可以看到提示信息:

image.png

3. 采集分析

这里我们主要使用到Doris 2.0 里的新功能倒排索引,Doris 倒排索引的语法如下:

  1. 建表时指定索引
CREATE TABLE table_name
(
columns_difinition,
 INDEX idx_name1(column_name1) USING INVERTED [PROPERTIES("parser" = "english|chinese")] [COMMENT 'your comment']
 INDEX idx_name2(column_name2) USING INVERTED [PROPERTIES("parser" = "english|chinese")] [COMMENT 'your comment']
)
table_properties;
  1. Alter方式添加索引
  -- 语法1
  CREATE INDEX idx_name ON table_name(column_name) USING INVERTED [PROPERTIES("parser" = "english|chinese")] [COMMENT 'your comment'];
  -- 语法2
  ALTER TABLE table_name ADD INDEX idx_name(column_name) USING INVERTED [PROPERTIES("parser" = "english|chinese")] [COMMENT 'your comment'];

语法说明:

  • 建表时定义倒排索引,语法说明如下

  • 默认不指定代表不分词

  • english是英文分词,适合被索引列是英文的情况,用空格和标点符号分词,性能高

  • chinese是中文分词,适合被索引列有中文或者中英文混合的情况,采用jieba分词库,性能比english分词低

  • USING INVERTED 是必须的,用于指定索引类型是倒排索引

  • PROPERTIES 是可选的,用于指定倒排索引的额外属性,目前有一个属性parser指定分词器

  • COMMENT 是可选的,用于指定注释

下面这个是我这个例子的创建和Nginx日志格式相对应的表结构,建表语句如下:

CREATE TABLE nginx_log(
  http_time datetimev2,
  remote_addr varchar(200),
  remote_user varchar(200),
  request string,
  uri string,
   status int,
  request_time decimal(12,6),
  request_length int,
  body_bytes_sent int,
  bytes_sent int,
  ssl_protocol varchar(200),
  ssl_cipher varchar(200),
  http_referer varchar(200),
  http_x_forwarded_for  varchar(200),
  http_user_agent string,
   INDEX idx_request(request) USING INVERTED PROPERTIES("parser" = "english") ,
   INDEX idx_uri(uri) USING INVERTED PROPERTIES("parser" = "english") ,
   INDEX idx_remote_addr(remote_addr) USING INVERTED PROPERTIES("parser" = "english") ,
   INDEX idx_http_user_agent(http_user_agent) USING INVERTED PROPERTIES("parser" = "english")
)
Duplicate KEY(`http_time`, `remote_addr`)
DISTRIBUTED BY HASH(`http_time`) BUCKETS 2
PROPERTIES (
"replication_allocation" = "tag.location.default: 1",
"in_memory" = "false",
"storage_format" = "V2"
);

这里我对部分字段创建的了倒排索引,并指定分词是英文分析,如果你的日志中有中文,你可以指定成:chinese(中文分词)

Logstash 和 Filebeats 启动之后,我们在控制台可以看到 Logstash 采集数据入库的信息:

image-20230602135127222.png

然后我们在MySQL 命令行下可以通过SQL进行查询日志的表

image.png

日志检索及分析

  1. 我们按照响应状态进行分组统计请求数量
mysql> select count(*),status  from nginx_log  group by status ;
+----------+--------+
| count(*) | status |
+----------+--------+
|       13 |    304 |
|        8 |    301 |
|        6 |    200 |
+----------+--------+

2. 统计访问社区栏目的要请求次数

mysql> select count(*) from nginx_log where  request MATCH_ANY 'community';
+----------+
| count(*) |
+----------+
|       12 |
+----------+
1 row in set (0.02 sec)

3. 统计访问博客栏目的要请求次数

mysql> select count(*) from nginx_log where  request MATCH_ANY 'blog';
+----------+
| count(*) |
+----------+
|        7 |
+----------+
1 row in set (0.03 sec)

4. Doris 倒排索引能力

Doris 倒排索引具备以下能力

  • 支持字符串类型的全文检索

  • 支持字符串全文检索,包括同时匹配多个关键字MATCH_ALL、匹配任意一个关键字MATCH_ANY

  • 支持字符串数组类型的全文检索

  • 支持英文、中文分词

  • 加速普通等值、范围查询,覆盖bitmap索引的功能,未来会代替bitmap索引

  • 支持字符串、数值、日期时间类型的 =, !=, >, >=, <, <= 快速过滤

  • 支持字符串、数字、日期时间数组类型的 =, !=, >, >=, <, <=

  • 支持完善的逻辑组合

  • 新增索引对OR NOT逻辑的下推

  • 支持多个条件的任意AND OR NOT组合

  • 支持灵活、快速的索引管理

  • 支持在创建表上定义倒排索引

  • 支持在已有的表上增加倒排索引,而且支持增量构建倒排索引,无需重写表中的已有数据

  • 支持删除已有表上的倒排索引,无需重写表中的已有数据

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,651评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,468评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,931评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,218评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,234评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,198评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,084评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,926评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,341评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,563评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,731评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,430评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,036评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,676评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,829评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,743评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,629评论 2 354

推荐阅读更多精彩内容