データベースを Elasticsearch と同期した後、データに一貫性がない場合はどうすればよいですか?

1. 実戦における問題点

  • Q1: Logstash が postgreSQL と Elasticsearch データを同期すると、一貫性が失われます。

Logstash を使用して pg ライブラリから ES にテーブルをインポートすると、ES のデータ量と PG ライブラリのこのテーブルのデータ量の間に大きなギャップがあることがわかります。挿入されていないデータをすばやく比較するにはどうすればよいですか? インポート プロセス中、Logstash ログは正常です。PG のこのテーブルには 7600W があります。

  • Q2: mq 非同期二重書き込みデータベースと es スキームにおいて、データベース データと es データの整合性を確保するにはどうすればよいですか?

2. 推奨ソリューションの 1 つ - ID 比較方法

以下の例では、質問 1 のみを検証します。質問 2 の原理は同じです。

2.1 スキームの議論

Elasticsearch に挿入されていないデータを確認するには、次の方法を使用できます。

  • Logstash 構成ファイル内の入力プラグインの JDBC ドライバーが、PostgreSQL データベースからすべてのデータを取得するように適切に構成されていることを確認してください。ステートメントのパラメータに注意し、必要なデータがすべて選択されていることを確認してください。

  • Logstash 設定ファイルの出力プラグインをチェックして、Elasticsearch への接続パラメータが正しく設定されていることを確認します。また、インポート プロセス中にフィルターによって一部のデータが除外されていないかどうかも確認してください。

  • Logstash 構成ファイルに stdout プラグインを追加して、PostgreSQL データベースから読み取られたデータをファイルに記録します。

たとえば、次のように追加できます。

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

Logstash 出力ファイルを PostgreSQL データベース内の元のデータと比較して、インポートされていないデータを見つけます。これを行うには、Python、シェル スクリプト、または別のプログラミング言語で簡単なスクリプトを作成できます。

Logstash 出力ファイルのレコード数が PostgreSQL データベースのレコード数と一致するが、Elasticsearch のレコード数と一致しない場合は、Elasticsearch クラスターの健全性とログを確認してください。クラスターでデータの受信とインデックス作成に問題が発生していないかどうかを確認してください。

問題が解決しない場合は、バッチ サイズを減らしてElasticsearch と Logstash の負荷を軽減してみてください。これは、Logstash 構成ファイルの出力プラグインで flash_size パラメーターと idle_flush_time パラメーターを設定することで実現できます。

大量のデータを扱う場合、Logstash と Elasticsearch のパフォーマンスとリソース構成を調整する必要がある場合があります。ハードウェアやネットワークの状態によっては、バッチ操作の設定、JVM 設定、スレッド プール サイズなどの調整が必要になる場合があります。

2.2 比較スクリプトの実装

以下は、Logstash 出力ファイル (JSON 形式) と PostgreSQL データベース内のデータを比較する簡単なシェル スクリプトの例です。スクリプトは ID などの特定のフィールドを比較して、どのデータが Elasticsearch にインポートされていない可能性があるかを判断します。

dd1f8a0ceaa3587abe362e87ccbcdf48.png

まず、PostgreSQL データベースからデータをエクスポートし、CSV ファイルとして保存します。

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

次に、compare.sh というシェル スクリプトを作成します。

#!/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. 推奨事項 2 - Redis アクセラレーションの比較

この場合、Redis のコレクション データ型を使用して、PostgreSQL データベースと Logstash 出力ファイルに ID を保存できます。次に、Redis が提供する set オペレーションを使用して、欠落している ID を見つけることができます。

3326b1788127ce190fc4e08e809739cb.png

以下は、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. まとめ

オプション 1: シェル スクリプトと grep コマンドを使用する

  • アドバンテージ:

(1) シンプルで実装が簡単。

(2) 追加のライブラリやツールは必要ありません。

  • 欠点:

(1) は、ディスク上の一時ファイルの読み取りと書き込みが必要なため、速度が遅くなります。

(2) データ量が大きい場合、ディスク I/O とメモリ消費量が増加する可能性があります。

解決策 2: Redis を使用して高速比較を実現する

  • アドバンテージ:

(1) Redis はメモリベースのデータ構造ストレージであるため、高速です。

(2) スケーラビリティに優れ、大量のデータを扱える。

  • 欠点:

(1) 実装は比較的複雑であり、追加のスクリプトを作成する必要があります。

(2) Redis サーバーがインストールされ、実行されている必要があります。

ニーズとデータ量に応じて、適切なソリューションを選択できます。処理するデータの量が少なく、速度要件がそれほど高くない場合は、シェル スクリプトと grep コマンドを使用してオプション 1 を選択できます。このアプローチはシンプルで使いやすいですが、大量のデータの場合はうまく機能しない可能性があります。

大量のデータを処理する必要がある場合は、オプション 2 を選択し、Redis を使用して比較を高速化することをお勧めします。この方法はより高速で、大量のデータを効率的に処理できます。ただし、このアプローチでは、Redis サーバーのインストールや Python スクリプトの作成など、追加のセットアップと構成が必要です。

実際のアプリケーションでは、最適なソリューションを選択するために、特定のニーズに応じてトレードオフを行う必要がある場合があります。

------

質の高い技術交流グループを作りました、優秀な人たちと一緒にいると自分も優秀になります、今すぐクリックしてグループに参加し、共に成長する喜びを感じてください。さらに、最近転職したい場合は、1 年前に 2 週間かけて大手工場からの対面経験を集めました。フェスティバル後に転職する予定がある場合は、ここをクリックして獲得できます

推奨読書

・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・

こんにちは、私はプログラマーの DD で、Alibaba Cloud の MVP、Tencent Cloud の TVP として 10 年間ベテランドライバーを開発してきました。一般的な開発からアーキテクト、そしてパートナーまで。その過程で、私が最も深く感じているのは、私たちは学び続け、フロンティアに注意を払わなければならないということです。忍耐して、もっと考えて、愚痴を少なくして、一生懸命働くことができれば、カーブで追い越すのは簡単です。だから、私が今やっていることをやるには遅すぎるかどうかは聞かないでください。何かについて楽観的である場合は、希望が見えたときだけ耐えるのではなく、希望が見えるまで耐えなければなりません。信じてください、あなたがそれを続ける限り、あなたは今よりも良くなるでしょう!まだ方向性が決まっていない場合は、まず私に従ってください。コーナーリングや追い越しのための資本を蓄積するのに役立つ最先端の情報をここで頻繁に共有します。

おすすめ

転載: blog.csdn.net/j3T9Z7H/article/details/131485416