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]{: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