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.
Configurações
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 o 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
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"]
}
}
Onde:
- 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 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.
# 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