实现Logstash8.x 从mongo同步数据到ElasticSearch8.x
注意事项
Logstash的版本必须和ElasticSearch版本必须保持一致
一、创建ElasticSearch的索引库
PUT /test_index/
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
},
"mappings": {
"properties": {
"_class": {
"type": "keyword",
"index": false,
"doc_values": false
},
"dataId": {
"type": "keyword"
},
"areaCode": {
"type": "keyword"
},
"type": {
"type": "text",
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
}
},
"contact": {
"type": "text",
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
}
},
"phone": {
"type": "text",
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
}
},
"common": {
"type": "text",
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
}
},
"addTime": {
"type": "date"
},
"updateTime": {
"type": "date"
},
"dataFlag": {
"type": "keyword"
},
"location": {
"type": "geo_point"
}
}
}
}
二、创建索引库对应的Mongo实体类映射
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.Date;
@Data
@Document(collection = "test_db")
public class TestDb {
@Id
private String id;
private String dataId;
private String type;
private String areaCode;
private String contact;
private String phone;
private String common;
private GeoPoint location;
private Date addTime;
private Date updateTime;
private String dataFlag;
import org.springframework.data.geo.Point;
import java.util.Objects;
public class GeoPoint {
private double lat;
private double lon;
private GeoPoint() {
// required by mapper to instantiate object
}
public GeoPoint(double latitude, double longitude) {
this.lat = latitude;
this.lon = longitude;
}
public double getLat() {
return lat;
}
public double getLon() {
return lon;
}
/**
* build a GeoPoint from a {@link org.springframework.data.geo.Point}
*
* @param point {@link org.springframework.data.geo.Point}
* @return a {@link GeoPoint}
*/
public static GeoPoint fromPoint(Point point) {
return new GeoPoint(point.getY(), point.getX());
}
public static Point toPoint(GeoPoint point) {
return new Point(point.getLon(), point.getLat());
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
GeoPoint geoPoint = (GeoPoint) o;
return Double.compare(geoPoint.lat, lat) == 0 && Double.compare(geoPoint.lon, lon) == 0;
}
@Override
public int hashCode() {
return Objects.hash(lat, lon);
}
@Override
public String toString() {
return "GeoPoint{" + "lat=" + lat + ", lon=" + lon + '}';
}
说明
需要同步到ElasticSearch中"test_index"索引库中的数据保存到MongoDB数据库"test_db"中即可,后续logstash会自动从mongo读取数据同步到索引库中。
注意
1、对Mongo数据库中的数据进行操作后必须要更新"updateTime"字段的时间,因为后续logstash通过该字段时间范围查询同步到索引库中。
2、使用Logstash同步数据,只能实现逻辑删除,对于删除的数据,更新"dataFlag"字段设置为删除状态(1、数据有效、0、数据无效),数据同步到索引库后,对于逻辑删除的数据,通过查询条件过滤不查询出来即可。
三、配置Logstash
下载安装Mongo数据库驱动
访问: https://dbschema.com/jdbc-drivers/MongoDbJdbcDriver.zip 下载最新Mongo数据库驱动,下载完成后解压将获取到的jar包上传到logstash的lib目录下
logstash.conf
添加logstash.conf 配置文件存放到logstash根目录
# Sample Logstash configuration for creating a simple
# Beats -> Logstash -> Elasticsearch pipeline.
input {
jdbc {
# 指定使用的mongo驱动jar包
jdbc_driver_library => "/usr/local/logstash-8.12.2/lib/mongojdbc4.8.2.jar"
# 指定使用的数据库驱动类
jdbc_driver_class => "com.wisecoders.dbschema.mongodb.JdbcDriver"
# 指定要连接的数据库的访问地址:"jdbc:mongodb://账户:密码@ip:port/数据库名"
# 需要注意数据库密码中不能带@
jdbc_connection_string => "jdbc:mongodb://test2:test2@ip:port/test_mongo"
# 指定多久同步一次
schedule => "* * * * * *"
# 指定同步时执行的mongo脚本,这里使用了updateTime作为条件进行同步
statement => "db.test_db.find({'updateTime':{'$gt':ISODate(:sql_last_value)}});"
# 追踪的字段名,
tracking_column => "updateTime"
# sql日志级别
sql_log_level => "error"
# 是否记录上次执行结果, 如果为真,将会把上次执行到的 tracking_column 字段的值记录下来,保存到 last_run_metadata_path 指定的文件中
record_last_run => true
# 上次追踪的元数据存放位置
last_run_metadata_path => "/usr/local/logstash-8.12.2/logstash_jdbc_last_run"
# 开启分页查询
jdbc_paging_enabled => true
jdbc_paging_mode => "explicit"
jdbc_page_size => 1000
}
}
# 从mongo读取的数据需要经过解析处理才能正常同步到索引库
filter{
mutate {
add_field => {"document_su" => "%{document}"}
}
json {
source => "document_su"
remove_field => ["document_su","document","@version","@timestamp"]
}
mutate {
# mongo的主键"_id"会导致同步数据异常,因此对其进行重命名
rename => ["_id", "id"]
}
}
output {
elasticsearch {
# 访问的es的地址
hosts => ["http://ip:9200"]
# 指定要同步的索引库
index => "test_index"
# 指定es的访问账户
user => "elastic"
# 指定es的访问密码
password => "elastic"
# 指定将读取的id字段作为索引库中的文档id
document_id => "%{id}"
}
stdout {
codec => json_lines
}
}
pipelines.yml
修改pipelines配置如下:
# 指定工作管道,如果需要从多个数据库同步数据到索引库,创建多个配置并指定工作管道即可。
- pipeline.id: test
path.config: "/usr/local/logstash-8.12.2/logstash1.conf"
四、启动Logstash同步数据
cd /usr/local/logstash-8.12.2
nohup bin/logstash &
成功启动logstash后Logtash会自动定时同步数据到索引库。