Sincronizando dados do PostgreSQL no Elasticsearch

0 Flares Twitter 0 Facebook 0 Filament.io 0 Flares ×

Atualmente estou com uma missão de gerar relatórios e estatísticas com os dados do Moodle, porém o Moodle trabalha somente com bancos de dados relacionais como PostgreSQL e MySQL e o ambiente que vou analisar terá cerca de 6 mil usuários, uma hora ou outra as consultas para relatórios vão ficar lentas.

Tendo este cenário em vista, estou fazendo uma sincronização dos dados do PostgreSQL para o Elasticsearch. Como o Elasticserach é um banco de dados noSQL as buscas realizadas nele em grandes volumes de dados são extremamente mais rápidas se comparadas à qualquer banco de dados relacional.

Então nas linhas abaixo vou mostrar como é possível fazer essa migração.

A primeira parte é fazer a instalação do java versão 8.

Para fazer isso execute os seguintes passos abaixo.

echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu xenial main" | tee /etc/apt/sources.list.d/webupd8team-java.list
echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu xenial main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886
apt-get update
apt-get install oracle-java8-installer

Caso você queira deixa-lo como padrão, que foi o que eu fiz, execute a instrução abaixo.

apt-get install oracle-java8-set-default -y

Uma vez com o java instalado, vamos instalar o ElasticSearch e o Logstash.

apt-get -f install logstash elasticsearch -y

Para fazer a sincronização do PostgreSQL com o Logstash é necessário instalar um plugin chamado: logstash-input-jdbc.

A instalação é feita seguindo as seguintes instruções:

cd /usr/share/logstash/bin
./logstash-plugin install logstash-input-jdbc

Quando terminada a instalação é necessário baixar o drive do PostgreSQL para Java, pois esse plugin precisa desse driver para conectar ao postgres.

O driver pode ser baixado em qualquer diretório do linux, mas nas instruções abaixo eu coloquei dentro do diretório do próprio logstash.

cd /usr/share/logstash
wget https://jdbc.postgresql.org/download/postgresql-9.4.1212.jre6.jar

Agora é hora de criar o arquivo de configuração que vai fazer essa sincronização, para isso siga as instruções abaixo:

 cd /etc/logstash/conf.d/
vim moodle-courses-index.conf

Agora dentro desse arquivo coloque o seguinte conteúdo:

input {
    jdbc {
        jdbc_connection_string => "jdbc:postgresql://localhost:5432/moodle"
        jdbc_driver_library => "/usr/share/logstash/postgresql-9.4.1212.jre6.jar"
        jdbc_user => "moodle_db_admin"
        jdbc_password => "moodle_db_pass"
        jdbc_driver_class => "org.postgresql.Driver"
        statement => "SELECT * from mdl_course"
    }
}
output {
    elasticsearch {
             index => "moodle"
             document_type => "mdl_course"
             document_id => "%{id}"
             hosts => ["127.0.0.1"]
        }
}

Na seção input desse arquivo são definidos os parâmetros de conexão com o banco de dados relacional.

A parte mais importante é o statement pois é nela em que você define que tabela você vai sincronizar com o ElasticSearch.

Na seção output são definidos os parâmetros de saída, ou seja, para onde serão enviados os dados do PostgreSQL.

Nessa parte foi definido que será criado um índice chamado moodle, e nele será criado um documento chamado mdl_course que é o mesmo nome da tabela e cada documento será um registro da tabela.

document_id você deve colocar o campo id da sua tabela, pois ele será o mesmo id em que você fará a busca no ElasticSearch.

hosts é o endereço do host onde está instalado o seu ElasticSearch.

Salve esse arquivo e agora para fazer a importação desses dados siga as instruções abaixo:

cd /usr/share/logstash
./bin/logstash -f /etc/logstash/conf.d/moodle-courses-index.conf

E a saída do comando será parecida com essa:

WARNING: Could not find logstash.yml which is typically located in $LS_HOME/config or /etc/logstash. You can specify the path using --path.settings. Continuing using the defaults
Could not find log4j2 configuration at path /usr/share/logstash/config/log4j2.properties. Using default config which logs to console
17:25:59.515 [[main]<jdbc] INFO  logstash.inputs.jdbc - (0.192000s) SELECT * from mdl_course
17:26:00.208 [[main]-pipeline-manager] INFO  logstash.outputs.elasticsearch - Elasticsearch pool URLs updated {:changes=>{:removed=>[], :added=>["http://127.0.0.1:9200"]}}
17:26:00.211 [[main]-pipeline-manager] INFO  logstash.outputs.elasticsearch - Using mapping template from {:path=>nil}
17:26:00.634 [[main]-pipeline-manager] INFO  logstash.outputs.elasticsearch - Attempting to install template {:manage_template=>{"template"=>"logstash-*", "version"=>50001, "settings"=>{"index.refresh_interval"=>"5s"}, "mappings"=>{"_default_"=>{"_all"=>{"enabled"=>true, "norms"=>false}, "dynamic_templates"=>[{"message_field"=>{"path_match"=>"message", "match_mapping_type"=>"string", "mapping"=>{"type"=>"text", "norms"=>false}}}, {"string_fields"=>{"match"=>"*", "match_mapping_type"=>"string", "mapping"=>{"type"=>"text", "norms"=>false, "fields"=>{"keyword"=>{"type"=>"keyword"}}}}}], "properties"=>{"@timestamp"=>{"type"=>"date", "include_in_all"=>false}, "@version"=>{"type"=>"keyword", "include_in_all"=>false}, "geoip"=>{"dynamic"=>true, "properties"=>{"ip"=>{"type"=>"ip"}, "location"=>{"type"=>"geo_point"}, "latitude"=>{"type"=>"half_float"}, "longitude"=>{"type"=>"half_float"}}}}}}}}
17:26:00.642 [[main]-pipeline-manager] INFO  logstash.outputs.elasticsearch - New Elasticsearch output {:class=>"LogStash::Outputs::ElasticSearch", :hosts=>["127.0.0.1"]}
17:26:00.645 [[main]-pipeline-manager] INFO  logstash.pipeline - Starting pipeline {"id"=>"main", "pipeline.workers"=>4, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>5, "pipeline.max_inflight"=>500}
17:26:00.652 [[main]-pipeline-manager] INFO  logstash.pipeline - Pipeline main started
17:26:01.298 [Api Webserver] INFO  logstash.agent - Successfully started Logstash API endpoint {:port=>9600}
17:26:03.677 [LogStash::Runner] WARN  logstash.agent - stopping pipeline {:id=>"main"}

Se não aparecer nenhum ERROR ai no meio quer dizer que funcionou.

Para testar você pode fazer um request na api do ElasticSearch e ver se os dados estão lá, no meu caso vou buscar pelo ID 85.

root@alisson-pc:/usr/share/logstash# curl http://localhost:9200/moodle/mdl_course/85/?pretty
 
 
{
  "_index" : "moodle",
  "_type" : "mdl_course",
  "_id" : "85",
  "_version" : 2,
  "found" : true,
  "_source" : {
    "groupmode" : 0,
    "idnumber" : "",
    "cacherev" : 1480009744,
    "summaryformat" : 1,
    "showreports" : 1,
    "startdate" : 1479866400,
    "completionnotify" : 0,
    "defaultgroupingid" : 0,
    "showgrades" : 1,
    "@version" : "1",
    "sortorder" : 10001,
    "theme" : "",
    "id" : 85,
    "lang" : "",
    "summary" : "",
    "visible" : 1,
    "format" : "onetopic",
    "visibleold" : 1,
    "groupmodeforce" : 0,
    "shortname" : "Enfermagem",
    "legacyfiles" : 0,
    "enablecompletion" : 1,
    "tags" : [ ],
    "calendartype" : "",
    "newsitems" : 3,
    "requested" : 0,
    "timecreated" : 1479832086,
    "@timestamp" : "2016-11-24T19:26:00.669Z",
    "marker" : 0,
    "timemodified" : 1479832940,
    "maxbytes" : 0,
    "fullname" : "Enfermagem",
    "category" : 1
  }
}

É isso ai, falows \o

0 Flares Twitter 0 Facebook 0 Filament.io 0 Flares ×
1 ano ago

2 Comments

  1. Muito bom seu post, mano. Trabalho com a pilha ELK e nunca tinha visto que o logstatsh faz a captura com jdbc, mas me surgiu uma dúvida, uma vez configurado como mostrado acima quando o logstatsh fará a busca dos dados novamente.

  2. Eai Fabricio,

    No caso você tem que configurar uma rotina pra ficar sincronizando periodicamente, isso pode ser feito via logstash mesmo, ou você pode criar uma cronjob, no exemplo desse pois ele só faz quando é executado o comando logstash -f

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *