1. 準備
1. elasticSearch+kibana をインストールする
ここで使用する es と kibana のバージョンは7.4.0
バージョンです。
Docker のインストール elasticSearch+kibana
2.MySQLをインストールする
docker install mysql-simple でピットなし
3. Logstash をインストールする
logstash は、リアルタイム データ送信機能を備えたパイプラインで、パイプラインの入力側からパイプラインの出力側にデータ情報を送信する役割を果たします。同時に、このパイプラインは、パイプラインの途中にフィルターを追加することもできます。 inuput --output 独自のニーズに応じて Logstash には、さまざまなアプリケーション シナリオに対応する多数のプラグインが組み込まれています。
logstash 公式プラグインはlogstash-input-jdbc
logstash (5.X 以降) に統合されており、mysql と elasticsearch の間のデータ同期は設定ファイルを通じて実現されます。
mysql データの完全および増分データ同期を実現でき、タイミング同期も実現できます。
# 拉取logstach
docker pull logstash:8.5.2
2. 完全同期
完全同期とは、すべてのデータを es に同期することを指します。これは通常、es が確立されたばかりの最初の同期に使用されます。
1. MySQL データとテーブルを準備する
CREATE TABLE `product` (
`id` int NOT NULL COMMENT 'id',
`name` varchar(255) DEFAULT NULL,
`price` decimal(10,2) DEFAULT NULL,
`create_at` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
INSERT INTO `shop`.`product`(`id`, `name`, `price`, `create_at`) VALUES (1, '小米手机', 33.00, '1');
INSERT INTO `shop`.`product`(`id`, `name`, `price`, `create_at`) VALUES (2, '长虹手机', 2222.00, '2');
INSERT INTO `shop`.`product`(`id`, `name`, `price`, `create_at`) VALUES (3, '华为电脑', 3333.00, '3');
INSERT INTO `shop`.`product`(`id`, `name`, `price`, `create_at`) VALUES (4, '小米电脑', 333.30, '4');
2.mysql-connector-java.jarをアップロードします。
mysql-connector-java-8.0.21.jar を logstach サーバーにアップロードします。
3. Logstashを起動します
# 编辑logstash.yml
vi /usr/local/logstash/config/logstash.yml
# 内容,需要修改es地址
http.host: "0.0.0.0"
xpack.monitoring.elasticsearch.hosts: [ "http://172.17.0.3:9200" ]
# 自定义网络(可以解决网络不一致的问题)
#docker network create --subnet=172.188.0.0/16 czbkNetwork
# 启动 logstash
docker run --name logstash -v /usr/local/logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml -v /usr/local/logstash/config/conf.d/:/usr/share/logstash/pipeline/ -v /root/mysql-connector-java-8.0.21.jar:/usr/share/logstash/logstash-core/lib/jars/mysql-connector-java-5.1.48.jar -d d7102f8c625d
# 查看日志
docker logs -f --tail=200 c1d20ebf76c3
4. logstash.conf ファイルを変更します。
cd /usr/local/logstash/config/conf.d
vi logstash.conf
stdin は標準入力からイベントを読み取ります。
デフォルトでは、各行はイベントとして読み取られます。
input {
stdin {
}
#使用jdbc插件
jdbc {
# mysql数据库驱动
#jdbc_driver_library => "/usr/share/logstash/logstash-core/lib/jars/mysql-connector-java-5.1.48.jar"
jdbc_driver_class => "com.mysql.jdbc.Driver"
# mysql数据库链接,数据库名
jdbc_connection_string => "jdbc:mysql://172.17.0.2:3306/shop?allowMultiQueries=true&useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true"
# mysql数据库用户名,密码
jdbc_user => "root"
jdbc_password => "root"
# 分页
jdbc_paging_enabled => "true"
# 分页大小
jdbc_page_size => "50000"
# sql语句执行文件,也可直接使用 statement => 'select * from t'
statement_filepath => "/usr/share/logstash/pipeline/sql/full_jdbc.sql"
#statement => " select * from product where id <=100 "
}
}
# 过滤部分(不是必须项)
filter {
json {
source => "message"
remove_field => ["message"]
}
}
# 输出部分
output {
elasticsearch {
# elasticsearch索引名
index => "product"
# elasticsearch的ip和端口号
hosts => ["172.17.0.3:9200"]
# 同步mysql中数据id作为elasticsearch中文档id
document_id => "%{id}"
}
stdout {
codec => json_lines
}
}
5. full_jdbc.sql ファイルを変更します。
mkdir /usr/local/logstash/config/conf.d/sql
cd /usr/local/logstash/config/conf.d/sql
vi full_jdbc.sql
full_jdbc.sqlの内容は以下の通りです
SELECT
id,
TRIM( REPLACE ( name, ' ', '' ) ) AS productname,
price
FROM product
6. Kibana を開いてインデックスとマップを作成します
知らせ!mysql—>logstash—>es
作成されたマッピングが大文字の場合、es は自動的に小文字に変換され
、マッピング データ構造を表示すると、2 つの同一のフィールド (productname と productName) が表示され、
独自に定義されたマッピングにつながります。使用され、データ付きのものは es によって自動的に生成された小文字です
PUT product
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"productname": {
"type": "text"
},
"price": {
"type": "double"
}
}
}
}
マッピングに対する厳密な要件がない場合、現在の手順は無視でき、インデックスは自動的に作成されます。
# 当前在es中是没有数据的
GET product/_search
7. 完全同期のために logstash を再起動します。
# 重启
docker restart c1d20ebf76c3
# 查看日志
docker logs -f --tail=200 c1d20ebf76c3
mysql のデータが logstash に同期されていることがわかります。
8. ピットに足を踏み入れる
(1) エラー報告
デーモンからのエラー応答: コンテナー 3849f947e115 を再起動できません: ドライバーは、エンドポイント logstash (60f5d9678218dc8d19bc8858fb1a195f4ebee294cff23d499a28612019a0ff78) での外部接続のプログラミングに失敗しました: (iptables が失敗しました: iptables --wait -t nat -A DOCKER -p) tcp -d 0/0 --dport 4567 -j DNAT --to-destination 172.188.0.77:4567 ! -i br-413b460a0fc8: iptables: その名前によるチェーン/ターゲット/一致はありません。
理由は、firewalld の起動後、iptables がアクティブ化され、
現時点では docker チェーンが存在せず、docker の再起動後に iptables に追加されるためです。
解決策:
systemctl 再起動ドッカー
3. 増分同期
1. 増分構成を変更する
上記の logstash.conf ファイルを変更します。
input {
stdin {
}
#使用jdbc插件
jdbc {
# mysql数据库驱动
#jdbc_driver_library => "/usr/share/logstash/logstash-core/lib/jars/mysql-connector-java-5.1.48.jar"
jdbc_driver_class => "com.mysql.jdbc.Driver"
# mysql数据库链接,数据库名
jdbc_connection_string => "jdbc:mysql://172.188.0.15:3306/shop?characterEncoding=UTF-8&useSSL=false"
# mysql数据库用户名,密码
jdbc_user => "root"
jdbc_password => "root"
# 设置监听间隔 各字段含义(分、时、天、月、年),全部为*默认含义为每分钟更新一次
# /2* * * *表示每隔2分钟执行一次,依次类推
schedule => "* * * * *"
# 分页
jdbc_paging_enabled => "true"
# 分页大小
jdbc_page_size => "50000"
# sql语句执行文件,也可直接使用 statement => 'select * from t'
statement_filepath => "/usr/share/logstash/pipeline/sql/increment_jdbc.sql"
#上一个sql_last_value值的存放文件路径, 必须要在文件中指定字段的初始值
#last_run_metadata_path => "./config/station_parameter.txt"
#设置时区,此处更新sql_last_value查询的时区,sql_last_value还是默认UTC
jdbc_default_timezone => "Asia/Shanghai"
#使用其它字段追踪,而不是用时间
#use_column_value => true
#追踪的字段
#tracking_column => id
tracking_column_type => "timestamp"
}
}
# 过滤部分(不是必须项)
filter {
json {
source => "message"
remove_field => ["message"]
}
}
# 输出部分
output {
elasticsearch {
# elasticsearch索引名
index => "product"
# elasticsearch的ip和端口号
hosts => ["172.188.0.88:9200"]
# 同步mysql中数据id作为elasticsearch中文档id
document_id => "%{id}"
}
stdout {
codec => json_lines
}
}
2. 新しいincrement_jdbc.sqlファイルを作成します。
/usr/local/logstash/config/conf.d/sql ディレクトリに新しい increment_jdbc.sql ファイルを作成します。
cd /usr/local/logstash/config/conf.d/sql
vi increment_jdbc.sql
increment_jdbc.sql の内容は次のとおりです。
ここで、SQL は選択後の可能な限り全額と一致する必要があります。
SELECT
id,
TRIM( REPLACE ( product_name, ' ', '' ) ) AS productname,
price
FROM product where update_time > :sql_last_value
3. コンテナを再起動します
# 启动
docker restart 容器id
4. テスト
データがデータベースに挿入されると、データは自動的に es に同期されます。
5. 同期原理
#进入容器
docker exec -it 4f95a47f12de /bin/bash
#查看记录点
cat /usr/share/logstash/.logstash_jdbc_last_run
last_run_metadata_path=>「/usr/share/logstash/.logstash_jdbc_last_run」
完全同期の UTC 時刻は、コンテナーの /usr/share/logstash/ のパスにある隠しファイル .logstash_jdbc_last_run に記録されます。
各同期が完了した後の時間を記録します (重要) logstash_jdbc_last_run はデフォルトでは使用できないこと
に注意してください。増分が実行された後に作成されたファイルも削除でき、コンテナーは再起動後に自動的に作成されます。