elasticsearch配合mysql實現全文搜索

以前用了sphinx,發現不少東西好久都沒更新過了,以前只是知道有elasticsearch這個東西,還覺得是java才能用,因此一直沒有去了解過,也許sphinx慢慢會被淘汰了吧。php

前置條件:須要安裝jdk,並配置了 JAVA_HOME。html

 

須要下載的東西java

Elasticsearch:mysql

https://www.elastic.co/products/elasticsearchgit

Logstash:github

https://www.elastic.co/products/logstashsql

mysql-connector:數據庫

https://dev.mysql.com/downloads/connector/j/5.1.htmljson

 

另外:能夠安裝 kibana,有更友好的數據展現。vim

elasticsearch、logstash、kibana 的安裝在 mac 下能夠 brew install

 

中文搜索須要安裝中文分詞插件(須要本身去github下載對應的版本 https://github.com/medcl/elasticsearch-analysis-ik/releases):

 

bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v5.5.1/elasticsearch-analysis-ik-5.5.1.zip

 

 

logstash 和 mysql-connector 是用來實現同步 mysql 數據到 elasticsearch 的。

logstash 配置:https://github.com/elastic/logstash/issues/3429

logstash 須要安裝 logstash-input-jdbc 插件:(這一步可能會卡好久,可能的緣由是,這個插件使用ruby開發,安裝過程須要下載 gem,可是國外的源太慢。)

logstash/bin/plugin install logstash-input-jdbc

 

logstash 的配置使用查看:https://github.com/elastic/logstash/issues/3429

下面是本機測試配置:

input {
  jdbc {
    jdbc_driver_library => "/usr/local/elasticsearch/plugins/logstash/mysql-connector-java-5.1.44-bin.jar"
    jdbc_driver_class => "com.mysql.jdbc.Driver"
    jdbc_connection_string => "jdbc:mysql://192.168.0.200:3306/vegent?characterEncoding=UTF-8&useSSL=false"
    jdbc_user => "test"
    jdbc_password => "test"
    statement => "SELECT * FROM vegent"
    jdbc_paging_enabled => "true"
    jdbc_page_size => "50000"
    schedule => "* * * * *"
  }
}

filter {
   json {
        source => "message"
        remove_field => ["message"]
    }
}

output {
  stdout {
    codec => rubydebug
  }
  elasticsearch {
    hosts => "192.168.0.200"
    index => "vegent"
  }        
} 

 

2018-06-02 更新:

上面的配置挖了個坑,由於沒有限制條件,並且指定了 schedule,因此會一直插入重複索引。

網上有說加如下條件就能夠了(沒有實踐,不指定是否可行):

 WHERE id > :sql_last_value

 

啓動Logstash:logstash -f logstash-mysql.conf ,這個logstash-mysql.conf 就是上面的配置。

查看elasticsearch是否同步數據成功:curl '192.168.0.200:9200/_cat/indices?v',若是看到大小在增加則說明同步成功了。

 

附:解決 gem 下載慢的問題(使用淘寶源)

一、gem sources --add https://ruby.taobao.org/ --remove https://rubygems.org/

二、gem sources -l,確保只有 ruby.taobao.org,

若是 仍是顯示 https://rubygems.org/ 進入 home的 .gemrc 文件
sudo vim ~/.gemrc
手動刪除 https://rubygems.org/

三、修改Gemfile的數據源地址,這個 Gemfile 位於 logstash 目錄下,修改 source 的值 爲: "https://ruby.taobao.org",修改  Gemfile.jruby-1.9.lock, 找到 remote 修改它的值爲: https://ruby.taobao.org (可能有幾個 remote 出現,修改後面是 url 那個,替換掉 url)。

四、安裝 logstash-input-jdbc,按上面的命令。

五、關於同步的問題,上面設置了一分鐘一次,而且無條件同步,其實是能夠只同步那些更新過的數據的,這裏還沒來得及作深刻研究。並且上面的配置還有個問題是,只作插入,而不是更新原有數據,這樣其實並非咱們想要的結果。

 

更新:sql 語句裏面能夠配置只同步更新過的數據,可是這個更新須要咱們去定義,比如如,數據庫有一個 update_time 字段,咱們更新的時候更新該字段(timestamp類型),這樣咱們能夠把 sql 語句寫爲 "SELECT * FROM vegent where update_time > :sql_last_value",這個 sql_last_value 在這個時候會是上一次執行該 sql 的時間戳,這樣也就實現了更新操做。另外還有一個問題是,elasticsearch 和 logstash 默認使用 UTC 時間戳,這樣若是咱們保存的是 PRC 時區的時間戳,這樣就會有問題,由於這樣 logstash 的同步語句中的時間戳是 -8:00 的,因此,還要在配置文件中加上:jdbc_default_timezone => "UTC",最後以下:

最後發現這樣雖然 sql 語句時間戳正常了,可是創建的索引裏面的時間戳仍是 UTC 的時間戳。

最後把 UTC 改成 PRC,最後都正常了,仍是和上面同樣的狀況,索引裏面的 @timestamp 仍是 UTC 的時間戳。

google 了一下,發現這個好像是不能配置的。這樣怎麼辦呢,也許能夠保存 UTC 的時間戳吧,取數據的時候再轉 PRC 。(後面證明了這個猜測有點多餘,仍是應該使用 UTC)

上圖連接:https://discuss.elastic.co/t/how-to-set-timestamp-timezone/28401

另一個猜測是:其實這個@timestamp 對咱們的同步更新數據沒影響,後來想一想發現也是,其實沒影響:

 上圖中, :sql_last_value 是咱們上一次進行 sql 查詢的時間。而不是我以前覺得的索引裏面的 @timestamp 字段,想一想也對,若是索引有 100w 數據,那麼我應該取那一條記錄的 @timestamp 做爲 :sql_last_value 呢?

 

因此結論仍是,jdbc_default_timezone 使用 UTC 就能夠了。有個須要注意的問題是 時間戳字段要使用 mysql 的timestamp。

 

jdbc {
    jdbc_driver_library => "/home/vagrant/logstash/mysql-connector-java-5.1.44-bin.jar"
    jdbc_driver_class => "com.mysql.jdbc.Driver"
    jdbc_connection_string => "jdbc:mysql://192.168.0.200:3306/test?characterEncoding=UTF-8&useSSL=false"
    jdbc_user => "test"
    jdbc_password => "test"
    jdbc_default_timezone => "UTC"
    statement => "SELECT * FROM test where update_time > :sql_last_value"
    jdbc_paging_enabled => "true"
    jdbc_page_size => "50000"
    schedule => "* * * * *"
  }

 

查詢例子:

curl 'localhost:9200/vegent/_search?pretty=true'  -d '
{
  "query" : { "match" : { "type" : "冬瓜" }}
}'

輸出(一部分):

查詢 type 字段包含了 "冬瓜" 的全部記錄。vegent 是索引的名稱。?pretty=true 是指定友好輸出格式。

返回結果的 took字段表示該操做的耗時(單位爲毫秒),timed_out字段表示是否超時,hits字段表示命中的記錄,裏面子字段的含義以下。
  total:返回記錄數,本例是487893條。
  max_score:最高的匹配程度,本例是5.598418。
  hits:返回的記錄組成的數組。

 

logstash 文檔地址:https://www.elastic.co/guide/en/logstash/index.html

 

其餘問題:

一、沒法遠程鏈接,默認只容許本機鏈接,能夠修改配置文件 elasticsearch/config/elasticsearch.yml

# Set the bind address to a specific IP (IPv4 or IPv6):
#
#network.host: 192.168.0.1
transport.host: localhost
transport.tcp.port: 9300
http.port: 9200
network.host: 0.0.0.0

二、上面的 "同步",並非真正的同步,當有新數據的時候,上面作的只是把新數據繼續加到索引裏面,而不是根據對應的 id 去刪除原來的數據,這些須要本身作其餘操做,目前還沒作深刻了解。

相關文章
相關標籤/搜索