mysql到elasticsearch數據遷移踩坑實踐-Ali0th

Author : Ali0thhtml

Date : 20190514java

最近用go語言寫了個爬蟲,爬了幾百萬條數據,存在 mysql 裏,數據量較大,一個表就一兩G的程度(mysql表通常不要超過2G)。mysql

在這裏插入圖片描述

使用查詢語句很是之慢,並且我要常常使用到"LIKE",一條語句返回結果耗時 10~30 秒,這可不行。因此決定把數據遷移到 ES。真的是踩坑了,原本只想簡單搞搞,結果搞了好多天。git

本文章介紹兩種遷移方式:go-mysql-elasticsearchlogstash。如下是相關實踐過程。github

0.1. 先說go-mysql-elasticsearch

一開始發現了 go-mysql-elasticsearch 這個工具,也是go寫的,不過對ES的支持版本比較舊。因而我就把ES換成了舊版本。(新的ES版本就用logstash方式吧)spring

0.1.1. 環境

# 主要組件
mysql            : 5.5.3
elasticsearch    : 5.6.16
go-mysql-elasticsearch
# 環境
windows 10
go               : 1.11.2
複製代碼

同時也會用到 win 下 git 的命令行模式(能夠運行 bash 命令)sql

go-mysql-elasticsearch對 mysql 和 ES 的要求爲:數據庫

MySQL supported version < 8.0json

ES supported version < 6.0segmentfault

ES舊版本下載

kibana 5.6.16下載

0.1.2. 部署

mysql 和 elasticsearch 安裝很簡單,這裏就不說明了。這裏主要說 go-mysql-elasticsearch 的安裝過程。

項目地址:go-mysql-elasticsearch

go get github.com/siddontang/go-mysql-elasticsearch
複製代碼

cd到目錄下,個人 go mod 很差用,因此我直接使用 go get 安裝。

go get github.com/juju/errors
go get github.com/pingcap/check
go get github.com/siddontang/go/sync2
go get github.com/siddontang/go-mysql
go get github.com/pingcap/errors
go get github.com/shopspring/decimal
go get github.com/siddontang/go-log/log
複製代碼

修改代碼中的一處錯誤。(應該是版本緣由致使的)

文件:river/river.go

在這裏插入圖片描述

編譯:

go build -o bin/go-mysql-elasticsearch ./cmd/go-mysql-elasticsearch
複製代碼

無報錯,並看到有 bin/go-mysql-elasticsearch 文件即成功。

0.1.3. mysql 配置

文件:my.ini

添加如下配置並重啓。

# Binary Logging
server-id=1
log_bin = mysql-bin
binlog_format = ROW
複製代碼

0.1.4. river.toml配置

文件:etc/river.toml

其中有兩個關鍵的配置Sourcerule

[[rule]]
schema = "mysql_es"   # Mysql數據庫名
table = "test_table"  # Mysql表名
index = "test_index"  # ES中index名
type = "doc"          # 文檔類型
複製代碼

這一部分看官方示例就很清楚了 river.tomlElasticsearch最佳實踐從Mysql到Elasticsearch

0.1.5. mysqldump 配置

etc/river.toml 中有一處對於mysqldump的配置,只要把 mysql 的 bin 目錄加到環境變量就能夠了。但我這裏仍是找不到mysqldump,因此我就直接到mysqldump.exe拷貝到go-mysql-elasticsearch目錄下就能夠了。

0.1.6. 啓動

./bin/go-mysql-elasticsearch -config=./etc/river.toml
複製代碼

在這裏插入圖片描述

如上即爲正常運行。

0.1.7. es查詢數據量

# 查詢各索引狀況
curl -X GET "localhost:9200/_cat/indices?v"

# 查詢數量
curl -X GET "localhost:9200/_cat/count?v"
# 查詢某index的文檔數量
curl -X GET "localhost:9200/_cat/count/index_name?v"

# 查詢前1000條數據
curl -X GET "localhost:9200/test/_search?size=1000"
複製代碼

0.2. 使用 Logstash 進行數據遷移

ES : 7.0.1
Kibana : 7.0.1
Logstash : 7.0.1
複製代碼

個人 ES/Kibana 在windows 下,logstash 在centos下。

由於我在 windows 啓動 logstash 後一直報錯,[2019-05-15T11:55:00,183][ERROR][logstash.inputs.jdbc ] Failed to load C:/setup/mysql-connector-java-5.1.47/mysql-connector-java-5.1.47-bin.jar ,各類嘗試最後報錯依然存在,只好換用centos部署 logstash了。

在這裏插入圖片描述

0.2.1. 安裝部署

安裝 jdbc 和 elasticsearch 插件

./bin/logstash-plugin install logstash-input-jdbc
./bin/logstash-plugin install logstash-output-elasticsearch
複製代碼

獲取 jdbc mysql 驅動

下載

0.2.2. 配置

配置jdbc.conf,使用時自行把下面註釋去掉。

input {
    stdin {
    }
    jdbc {
      # mysql相關jdbc配置
      jdbc_connection_string => "jdbc:mysql://192.168.31.134:3306/test"
      jdbc_user => "root"
      jdbc_password => "root123"

      # jdbc鏈接mysql驅動的文件目錄,可去官網下載:https://dev.mysql.com/downloads/connector/j/
      jdbc_driver_library => "/home/mt/Desktop/mysql-connector-java-5.1.47/mysql-connector-java-5.1.47-bin.jar"
      # the name of the driver class for mysql
      jdbc_driver_class => "com.mysql.jdbc.Driver"
      jdbc_paging_enabled => "true"
      jdbc_page_size => "50000"

      # mysql文件, 也能夠直接寫SQL語句在此處,以下:
      # statement => "SELECT * from Table_test;"
      # statement_filepath => "C:/setup/logstash-7.0.1/config/myconfig/jdbc.sql"
      statement => "SELECT * FROM table WHERE id >= :sql_last_value"

      # 這裏相似crontab,能夠定製定時操做,好比每10分鐘執行一次同步(分 時 天 月 年)
      schedule => "*/1 * * * *"
      type => "jdbc"

      # 是否記錄上次執行結果, 若是爲真,將會把上次執行到的 tracking_column 字段的值記錄下來,保存到 last_run_metadata_path 指定的文件中
      record_last_run => "true"

      # 是否須要記錄某個column 的值,若是record_last_run爲真,能夠自定義咱們須要 track 的 column 名稱,此時該參數就要爲 true. 不然默認 track 的是 timestamp 的值.
      use_column_value => "true"

      # 若是 use_column_value 爲真,需配置此參數. track 的數據庫 column 名,該 column 必須是遞增的. 通常是mysql主鍵
      tracking_column => "id"

      last_run_metadata_path => "/home/mt/Desktop/logstash-7.0.1/myconf/last_id"

      # 是否清除 last_run_metadata_path 的記錄,若是爲真那麼每次都至關於從頭開始查詢全部的數據庫記錄
      clean_run => "false"

      # 是否將 字段(column) 名稱轉小寫
      lowercase_column_names => "false"

      columns_charset => {
        "message"=> "UTF-8"
        "name"=> "UTF-8"
      }
    }
}

# 此處我不作過濾處理,若是須要,也可參考elk安裝那篇
filter {}

output {
    # 輸出到elasticsearch的配置
    # 注意這裏對type判斷,若加載多個配置文件,要有這個判斷纔不會互相影響
    if[type] == "jdbc" {
      elasticsearch {
          hosts => ["192.168.31.45:9200"]
          index => "test"

          # 將"_id"的值設爲mysql的autoid字段
          # 注意這裏的id,若是多個表輸出到同一個index,它們的id有重複的,則這裏的 document_id 要修改爲不重複的,不然會覆蓋數據
          document_id => "%{id}"
          template_overwrite => true
      }
    }
    # 這裏輸出調試,正式運行時能夠註釋掉
    stdout {
        codec => json_lines
    }
}
複製代碼

啓動:

./bin/logstash -f ./myconf/jdbc.conf
複製代碼

0.2.3. 問題與解決

問題:編碼錯誤

[2019-05-15T21:38:10,051][ERROR][logstash.outputs.elasticsearch] An unknown error occurred sending a bulk request to Elasticsearch. We will retry indefinitely {:error_message=>"\"\\xE8\" from ASCII-8BIT to UTF-8", :error_class=>"LogStash::Json::GeneratorError", :backtrace=>["/home/mt/Desktop/logstash-7.0.1/logstash-core/lib/logstash/json.rb:27:in `jruby_dump'", "/home/mt/Desktop/logstash-7.0.1/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-10.0.2-java/lib/logstash/outputs/elasticsearch/http_client.rb:119:in `block in bulk'", "org/jruby/RubyArray.java:2577:in `map'", "/home/mt/Desktop/logstash-7.0.1/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-10.0.2-java/lib/logstash/outputs/elasticsearch/http_client.rb:119:in `block in bulk'", "org/jruby/RubyArray.java:1792:in `each'", "/home/mt/Desktop/logstash-7.0.1/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-10.0.2-java/lib/logstash/outputs/elasticsearch/http_client.rb:117:in `bulk'", "/home/mt/Desktop/logstash-7.0.1/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-10.0.2-java/lib/logstash/outputs/elasticsearch/common.rb:286:in `safe_bulk'", "/home/mt/Desktop/logstash-7.0.1/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-10.0.2-java/lib/logstash/outputs/elasticsearch/common.rb:191:in `submit'", "/home/mt/Desktop/logstash-7.0.1/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-10.0.2-java/lib/logstash/outputs/elasticsearch/common.rb:159:in `retrying_submit'", "/home/mt/Desktop/logstash-7.0.1/vendor/bundle/jruby/2.5.0/gems/logstash-output-elasticsearch-10.0.2-java/lib/logstash/outputs/elasticsearch/common.rb:38:in `multi_receive'", "org/logstash/config/ir/compiler/OutputStrategyExt.java:118:in `multi_receive'", "org/logstash/config/ir/compiler/AbstractOutputDelegatorExt.java:101:in `multi_receive'", "/home/mt/Desktop/logstash-7.0.1/logstash-core/lib/logstash/java_pipeline.rb:235:in `block in start_workers'"]}
複製代碼

解決:

對各個字段設置字符集:

columns_charset => {
        "message"=> "UTF-8"
        "name"=> "UTF-8"
        "payload"=> "UTF-8"
      }

複製代碼

問題:加載多個配置文件進行數據遷移,有重複id

0.2.4. 加載多個配置文件

運行多個實例

建立一個配置文件的文件夾,使用-f命令加載此文件便可。

./bin/logstash -f ./myconf/
複製代碼

0.2.5. 長期運行的 logstash

想要維持一個長期後臺運行的 logstash,你須要同時在命令前面加 nohup,後面加 &。

0.3. 資料

logstash mysql 準實時同步到 elasticsearch

logstash-input-jdbc同步mysql數據到elasticsearch

MySQL到Elasticsearch的同步之路

discuss.elastic.co/t/filter-er…

www.elastic.co/guide/en/lo…

discuss.elastic.co/t/character…

Logstash Multiple Pipelines 使用

Logstash 最佳實踐

logstash-input-jdbc同時同步多個表

相關文章
相關標籤/搜索