Use o Logstash para sincronizar dados do MySQL com o Elasticsearch (com pits)

1. Preparação

1. Instale elasticSearch+kibana

As versões es e kibana que usamos aqui são 7.4.0versões.
Instalação do Docker elasticSearch+kibana

2. Instale o MySQL

docker instala mysql-simples e sem pit

3. Instale o Logstash

logstash é um pipeline com capacidade de transmissão de dados em tempo real, responsável por transmitir informações de dados da extremidade de entrada do pipeline para a extremidade de saída do pipeline; ao mesmo tempo, esse pipeline também pode adicionar um filtro no meio de inuput --output de acordo com suas próprias necessidades. Logstash possui dezenas de plug-ins integrados para atender a vários cenários de aplicação.

O plug-in oficial do logstash logstash-input-jdbcestá integrado no logstash (após 5.X), e a sincronização de dados entre mysql e elasticsearch é realizada através do arquivo de configuração.
Ele pode realizar a sincronização de dados completa e incremental dos dados MySQL e pode realizar a sincronização de tempo.

insira a descrição da imagem aqui

# 拉取logstach
docker pull logstash:8.5.2

2. Sincronização completa

A sincronização completa refere-se à sincronização de todos os dados com es, que geralmente é usada para a primeira sincronização quando es acaba de ser estabelecida.

1. Prepare dados e tabelas 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. Carregar mysql-connector-java.jar

Carregue mysql-connector-java-8.0.21.jar para o servidor logstach,

3. Inicie o 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. Modifique o arquivo logstash.conf

cd /usr/local/logstash/config/conf.d
vi logstash.conf

stdin lê eventos da entrada padrão.

Por padrão, cada linha é lida como um evento

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. Modifique o arquivo full_jdbc.sql

mkdir /usr/local/logstash/config/conf.d/sql
cd /usr/local/logstash/config/conf.d/sql
vi full_jdbc.sql

O conteúdo de full_jdbc.sql é o seguinte

SELECT
	id,
	TRIM( REPLACE ( name, ' ', '' ) ) AS productname,
	price
FROM product

6. Abra o Kibana para criar índices e mapas

Perceber! mysql—>logstash—>es
Se o mapeamento criado tiver letras maiúsculas, es será automaticamente convertido para letras minúsculas
e ao visualizar a estrutura de dados do mapeamento, dois campos idênticos (productname e productName) aparecerão,
o que leva ao nosso próprio mapeamento definido Não pode ser usado, e aquele com dados é a minúscula gerada automaticamente por es

PUT product
{
    
    
  "settings": {
    
    
    "number_of_shards": 1,
    "number_of_replicas": 1
  },
  "mappings": {
    
    
    "properties": {
    
    
      "productname": {
    
    
        "type": "text"
    
      },
      "price": {
    
    
        "type": "double"
      } 
    }
  }
}

Se não houver nenhum requisito rígido para mapeamento, a etapa atual poderá ser ignorada e o índice será criado automaticamente.

# 当前在es中是没有数据的
GET product/_search

7. Reinicie o logstash para sincronização completa

# 重启
docker restart c1d20ebf76c3
# 查看日志
docker logs -f --tail=200 c1d20ebf76c3

Verifica-se que os dados no mysql foram sincronizados com o logstash.

8. Pise no poço

(1) Relatório de erros

Resposta de erro do daemon: Não é possível reiniciar o contêiner 3849f947e115: driver falhou ao programar conectividade externa no endpoint logstash (60f5d9678218dc8d19bc8858fb1a195f4ebee294cff23d499a28612019a0ff78): (iptables falhou: iptables --wait -t nat -A DOCKER -p tc p -d 0/0 --dport 4567 -j DNAT --to-destination 172.188.0.77:4567 ! -i br-413b460a0fc8: iptables: Nenhuma cadeia/destino/correspondência com esse nome.

O motivo é: após iniciar o firewalld, o iptables é ativado,
não há cadeia do docker no momento e é adicionado ao iptable após reiniciar o docker

Solução:
systemctl restart docker

3. Sincronização incremental

1. Modifique a configuração incremental

Modifique o arquivo logstash.conf acima

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. Crie um novo arquivo increment_jdbc.sql

Crie um novo arquivo increment_jdbc.sql no diretório /usr/local/logstash/config/conf.d/sql

cd /usr/local/logstash/config/conf.d/sql
vi increment_jdbc.sql

O conteúdo de increment_jdbc.sql é o seguinte:

Aqui, o sql deve ser consistente com o valor total tanto quanto possível após o Select

SELECT
	id,
	TRIM( REPLACE ( product_name, ' ', '' ) ) AS productname,
	price
	
FROM product where update_time > :sql_last_value

3. Reinicie o contêiner

# 启动
docker restart 容器id

4. Teste

Depois que um dado for inserido no banco de dados, ele será automaticamente sincronizado com es

5. Princípio de sincronização

#进入容器
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”

O horário UTC da sincronização completa é registrado no arquivo oculto .logstash_jdbc_last_run no caminho /usr/share/logstash/ no contêiner

Registre o tempo após a conclusão de cada sincronização (importante)
insira a descrição da imagem aqui
Observe que
logstash_jdbc_last_run não está disponível por padrão, e
o arquivo criado após a execução do incremento também pode ser excluído e
o contêiner será criado automaticamente após a reinicialização

Acho que você gosta

Origin blog.csdn.net/A_art_xiang/article/details/132193543
Recomendado
Clasificación