数据库同步 Elasticsearch 后数据不一致,怎么办?

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 数据库同步 Elasticsearch 后数据不一致,怎么办?

1、实战线上问题

  • Q1:Logstash 同步 postgreSQL 到 Elasticsearch 数据不一致。

在使用 Logstash 从 pg 库中将一张表导入到 ES 中时,发现 ES 中的数据量和 PG 库中的这张表的数据量存在较大差距。如何快速比对哪些数据没有插入?导入过程中,Logstash 日志没有异常。PG 中这张表有 7600W。

  • Q2:mq 异步双写数据库、es 的方案中,如何保证数据库数据和 es 数据的一致性?

2、推荐解决方案之一——ID 比较法

如下示例,仅拿问题1举例验证,问题2原理一致。

2.1 方案探讨

要找出哪些数据没有插入到 Elasticsearch 中,可以采用以下方法:

  • 确保 Logstash 配置文件中的 input 插件的 JDBC 驱动程序正确配置,以便从 PostgreSQL 数据库中提取所有数据。注意 statement 参数,确保它选择了所有需要的数据。
  • 检查 Logstash 配置文件的 output 插件,确保正确配置了 Elasticsearch 的连接参数。同时,检查是否有过滤器在导入过程中过滤掉了部分数据。
  • 在 Logstash 配置文件中添加一个 stdout 插件,将从 PostgreSQL 数据库中读取的数据记录到文件中。

例如,可以添加以下内容:

output {
  elasticsearch {
    ...Elasticsearch 配置...
  }
  stdout {
    codec => json_lines
    path => "/path/to/logstash_output.log"
  }
}

将 Logstash 输出文件与 PostgreSQL 数据库中的原始数据进行比较,以找出未导入的数据。可以使用 Python、Shell 脚本或其他编程语言编写一个简单的脚本来执行此操作。

如果 Logstash 输出文件中的记录数与 PostgreSQL 数据库中的记录数一致,但 Elasticsearch 中的记录数不一致,请检查 Elasticsearch 集群的健康状况和日志。确认集群是否在接收和索引数据时遇到问题。

如果问题仍然存在,尝试将批量操作的大小减小,以减轻 Elasticsearch 和 Logstash 的负担。可以通过在 Logstash 配置文件的 output 插件中设置 flush_size 和 idle_flush_time 参数来实现。

处理大量数据时,可能需要调整 Logstash 和 Elasticsearch 的性能和资源配置。根据硬件和网络条件,可能需要优化批量操作、JVM 设置、线程池大小等方面的设置。

2.2 比较脚本的实现

以下是一个简单的 Shell 脚本示例,用于比较 Logstash 输出文件(JSON 格式)和 PostgreSQL 数据库中的数据。该脚本将比较特定字段(如 id)以确定哪些数据可能未导入到 Elasticsearch。

首先,从 PostgreSQL 数据库中导出数据,将其保存为 CSV 文件:

COPY (SELECT id FROM your_table) TO '/path/to/postgres_data.csv' WITH

接下来,创建一个名为 compare.sh 的 Shell 脚本:

#!/bin/bash
# 将 JSON 文件中的 ID 提取到一个文件中
jq '.id' /path/to/logstash_output.log > logstash_ids.txt
 
# 删除 JSON 中的双引号
sed -i 's/"//g' logstash_ids.txt
 
# 对 Logstash 和 PostgreSQL 的 ID 文件进行排序
sort -n logstash_ids.txt > logstash_ids_sorted.txt
sort -n /path/to/postgres_data.csv > postgres_ids_sorted.txt
 
# 使用 comm 比较两个已排序的 ID 文件
comm -23 postgres_ids_sorted.txt logstash_ids_sorted.txt > missing_ids.txt
 
# 输出结果
echo "以下 ID 在 Logstash 输出文件中未找到:"
cat missing_ids.txt

为脚本添加可执行权限并运行:

chmod +x compare.sh
 
./compare.sh

此脚本会比较 logstash_output.log 和 postgres_data.csv 文件中的 ID。如果发现缺失的 ID,它们将被保存在 missing_ids.txt 文件中,并输出到控制台。请注意,该脚本假设已经安装了 jq(一个命令行 JSON 处理器)。如果没有,请先安装 jq

3、推荐方案二——Redis 加速对比

在这种情况下,可以使用 Redis 的集合数据类型来存储 PostgreSQL 数据库和 Logstash 输出文件中的 ID。接下来,可以使用 Redis 提供的集合操作来找到缺失的 ID。

以下是一个使用 Redis 实现加速比对的示例:

首先,从 PostgreSQL 数据库中导出数据,将其保存为 CSV 文件:

COPY (SELECT id FROM your_table) TO '/path/to/postgres_data.csv' WITH CSV HEADER;

安装并启动 Redis。

使用 Python 脚本将 ID 数据加载到 Redis:

import redis
import csv
 
# 连接到 Redis
 
r = redis.StrictRedis(host='localhost', port=6379, db=0)
 
# 从 PostgreSQL 导出的 CSV 文件中加载数据
with open('/path/to/postgres_data.csv', newline='') as csvfile:
    csv_reader = csv.reader(csvfile)
    next(csv_reader)  # 跳过表头
    for row in csv_reader:
        r.sadd('postgres_ids', row[0])
 
# 从 Logstash 输出文件中加载数据
with open('/path/to/logstash_output.log', newline='') as logstash_file:
    for line in logstash_file:
        id = line.split('"id":')[1].split(',')[0].strip()
        r.sadd('logstash_ids', id)
 
# 计算差集
missing_ids = r.sdiff('postgres_ids', 'logstash_ids')
 
# 输出缺失的 ID
print("以下 ID 在 Logstash 输出文件中未找到:")
for missing_id in missing_ids:
    print(missing_id)

这个 Python 脚本使用 Redis 集合数据类型存储 ID,然后计算它们之间的差集以找到缺失的 ID。需要先安装 Python 的 Redis 库。可以使用以下命令安装:

pip install redis

这个脚本是一个基本示例,可以根据需要修改和扩展它。使用 Redis 的优点是它能在内存中快速处理大量数据,而不需要在磁盘上读取和写入临时文件。

4、小结

方案一:使用 Shell 脚本和 grep 命令

  • 优点:

(1)简单,易于实现。

(2)不需要额外的库或工具。

  • 缺点:

(1)速度较慢,因为它需要在磁盘上读写临时文件。

(2)对于大数据量的情况,可能会导致较高的磁盘 I/O 和内存消耗。

方案二:使用 Redis 实现加速比对

  • 优点:

(1)速度更快,因为 Redis 是基于内存的数据结构存储。

(2)可扩展性较好,可以处理大量数据。

  • 缺点:

(1)实现相对复杂,需要编写额外的脚本。

(2)需要安装和运行 Redis 服务器。

根据需求和数据量,可以选择合适的方案。如果处理的数据量较小,且对速度要求不高,可以选择方案一,使用 Shell 脚本和 grep 命令。这种方法简单易用,但可能在大数据量下表现不佳。

如果需要处理大量数据,建议选择方案二,使用 Redis 实现加速比对。这种方法速度更快,能够有效地处理大数据量。然而,这种方法需要额外的设置和配置,例如安装 Redis 服务器和编写 Python 脚本。

在实际应用中,可能需要根据具体需求进行权衡,以选择最适合的解决方案。

推荐阅读


更短时间更快习得更多干货!

和全球 近2000+ Elastic 爱好者一起精进!

比同事抢先一步学习进阶干货!


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
1天前
|
NoSQL Shell MongoDB
NoSQL数据使用指令和引擎连接数据库实例
【5月更文挑战第8天】本文介绍了MongoDB的本地使用和常用操作,包括通过mongo shell连接数据库、显示数据库和集合,以及副本集设置。最后提到了MongoDB的日志功能和顶点集的使用,如capped collection的创建和管理。
17 3
|
2天前
|
关系型数据库 MySQL 数据库
实时计算 Flink版产品使用合集之支持将数据写入 OceanBase 数据库吗
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
19 5
|
2天前
|
关系型数据库 MySQL API
实时计算 Flink版产品使用合集之可以通过mysql-cdc动态监听MySQL数据库的数据变动吗
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
16 0
|
2天前
|
存储 SQL Oracle
关系型数据库文件方式存储DATA FILE(数据文件)
【5月更文挑战第11天】关系型数据库文件方式存储DATA FILE(数据文件)
14 3
|
2天前
|
消息中间件 Java Kafka
实时计算 Flink版产品使用合集之可以将数据写入 ClickHouse 数据库中吗
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
13 1
|
2天前
|
Oracle 关系型数据库 MySQL
实时计算 Flink版产品使用合集之Flink CDC 2.3.0和Flink 1.17,无法从MySQL数据库中抽取数据,是什么原因导致的
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
19 1
|
2天前
|
SQL 关系型数据库 数据库
实时计算 Flink版产品使用合集之将数据写入Elasticsearch时,若Elasticsearch中的字段类型为date,对应的SQL类型应该是什么
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
23 0
|
3天前
|
存储 JSON 前端开发
数据库中的数据
数据库中的数据
7 0
|
3天前
|
SQL 监控 API
实时计算 Flink版产品使用合集之可以用来同步数据到 Elasticsearch(ES)吗
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
12 0
实时计算 Flink版产品使用合集之可以用来同步数据到 Elasticsearch(ES)吗
|
3天前
|
监控 安全 关系型数据库
关系型数据库数据完整性保障
【5月更文挑战第10天】关系型数据库数据完整性保障
13 4