当前位置:首页 > 技术 > 正文内容

基于ELK的分布式日志与数据同步实践

访客 技术 2026年6月19日 1

ELK架构核心组件解析

ELK技术栈由三个关键开源工具构成,共同实现日志的采集、存储、分析与可视化:

  • Logstash:作为数据管道,负责从多种来源收集、过滤并转发日志或业务数据。
  • Elasticsearch:提供分布式的全文搜索和数据分析能力,支撑海量数据的实时查询。
  • Kibana:构建于Elasticsearch之上,提供直观的数据仪表盘和交互式探索界面。

使用Logstash采集系统日志

在完成Elasticsearch(9200端口)与Kibana(5601端口)容器部署后,可进一步搭建Logstash服务以集中管理应用日志。

部署独立Logstash实例

  1. 创建配置目录:
    mkdir -p /opt/logstash/conf
  2. 编写运行参数文件 logstash.yml
http.host: "0.0.0.0"
http.port: 4560
xpack.monitoring.elasticsearch.hosts: ["http://192.168.40.77:9200"]
  1. 定义输入输出逻辑的管道配置 logstash.conf
input {
  tcp {
    mode => "server"
    host => "0.0.0.0"
    port => 5000
    codec => "json_lines"
  }
}

output {
  elasticsearch {
    hosts => ["http://192.168.40.77:9200"]
    index => "app-logs-%{+yyyy.MM.dd}"
  }
}
  1. 赋予读写权限:
    chmod -R 777 /opt/logstash
  2. 启动Docker容器:
docker run -d --name log-collector --network my-net \
  -p 5000:5000 -p 4560:4560 \
  -v /opt/logstash/conf/logstash.yml:/usr/share/logstash/config/logstash.yml \
  -v /opt/logstash/conf/logstash.conf:/usr/share/logstash/pipeline/logstash.conf \
  registry.cn-hangzhou.aliyuncs.com/joezhou/logstash:8.4.0
  1. 开放防火墙端口:
firewall-cmd --add-port=5000/tcp --permanent
firewall-cmd --add-port=4560/tcp --permanent
firewall-cmd --reload

Spring Boot集成日志推送

在Java项目中引入依赖:

<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>7.2</version>
</dependency>

更新 logback.xml 添加远程输出节点:

<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    <destination>192.168.40.77:5000</destination>
    <encoder class="net.logstash.logback.encoder.LogstashEncoder">
        <customFields>{"application":"service-a"}</customFields>
    </encoder>
</appender>

<root level="INFO">
    <appender-ref ref="CONSOLE"/>
    <appender-ref ref="LOGSTASH"/>
</root>

随后可在Kibana中创建索引模式 app-logs-* 并选择 @timestamp 字段进行日志浏览。

通过Logstash实现MySQL到ES的数据同步

为避免对主数据库造成压力,建议连接至MySQL集群中的只读副本执行数据抽取任务。

全量数据导入配置

适用于首次初始化或周期性整体刷新场景。

input {
  jdbc {
    jdbc_driver_library => "/data/mysql-connector-java-8.0.16.jar"
    jdbc_driver_class => "com.mysql.cj.jdbc.Driver"
    jdbc_connection_string => "jdbc:mysql://192.168.40.77:3306/es"
    jdbc_user => "root"
    jdbc_password => "root"
    statement => "SELECT * FROM dept ORDER BY updated ASC"
    schedule => "* * * * *" 
    jdbc_paging_enabled => true
    jdbc_page_size => 500
  }
}

filter {
  mutate { remove_field => ["@version"] }
}

output {
  elasticsearch {
    hosts => ["http://192.168.40.77:9200"]
    index => "dept"
    document_id => "%{deptno}"
  }
}

增量数据同步策略

利用时间戳字段追踪变更,仅拉取新增或修改记录。

input {
  jdbc {
    ...
    statement => "SELECT * FROM emp WHERE updated > :sql_last_value ORDER BY updated ASC"
    use_column_value => true
    tracking_column => "updated"
    tracking_column_type => "timestamp"
    record_last_run => true
    last_run_metadata_path => "/data/emp_last_run.txt"
    clean_run => false
  }
}

output {
  elasticsearch {
    hosts => ["http://192.168.40.77:9200"]
    index => "emp"
    document_id => "%{empno}"
  }
}

注意:物理删除操作不会被自动捕获,需结合逻辑删除标志位处理。

Spring Data Elasticsearch高级用法

借助Spring生态提供的抽象层简化ES操作。

实体映射与分词设置

重建索引以启用中文IK分词器:

PUT /dept
{
  "mappings": {
    "properties": {
      "dname": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart"
      }
    }
  }
}

自定义类型转换器

解决Java 8时间类型与ES格式不兼容问题:

public class LocalDateTimeConverter implements PropertyValueConverter {

    private static final DateTimeFormatter FORMATTER =
        DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

    @Override
    public Object write(Object value) {
        if (value instanceof LocalDateTime dt) {
            return dt.format(FORMATTER);
        }
        throw new IllegalArgumentException("Invalid type");
    }

    @Override
    public Object read(Object value) {
        if (value instanceof String str) {
            return LocalDateTime.parse(str, FORMATTER);
        }
        throw new IllegalArgumentException("Invalid format");
    }
}

文档实体类定义

@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(indexName = "dept")
public class DepartmentDoc {

    @Id
    private Long deptno;

    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private String dname;

    @Field(type = FieldType.Keyword)
    private String loc;

    @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
    @ValueConverter(LocalDateTimeConverter.class)
    private LocalDateTime updated;
}

仓库接口与常用方法

public interface DepartmentRepository extends ElasticsearchRepository<DepartmentDoc, Long> {

    List<DepartmentDoc> findByDnameContaining(String keyword);

    Page<DepartmentDoc> findByDnameContainingOrderByDeptnoDesc(String keyword, Pageable pageable);
}

典型测试用例:

@Test
void testQueryWithPagination() {
    PageRequest page = PageRequest.of(0, 5);
    Page<DepartmentDoc> result = repo.findByDnameContainingOrderByDeptnoDesc("研发", page);
    System.out.println("Total pages: " + result.getTotalPages());
    result.getContent().forEach(System.out::println);
}

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。