内容简介:Author : Ali0thDate : 20190514最近用go语言写了个爬虫,爬了几百万条数据,存在 mysql 里,数据量较大,一个表就一两G的程度(mysql表一般不要超过2G)。
Author : Ali0th
Date : 20190514
最近用 go 语言写了个爬虫,爬了几百万条数据,存在 mysql 里,数据量较大,一个表就一两G的程度(mysql表一般不要超过2G)。
使用查询语句非常之慢,而且我要经常使用到"LIKE",一条语句返回结果耗时 10~30 秒,这可不行。所以决定把数据迁移到 ES。真的是踩坑了,本来只想简单搞搞,结果搞了好多天。
本文章介绍两种迁移方式: go-mysql-elasticsearch
和 logstash
。以下是相关实践过程。
0.1. 先说go-mysql-elasticsearch
一开始发现了 go-mysql-elasticsearch
这个工具,也是go写的,不过对ES的支持版本比较旧。于是我就把ES换成了旧版本。
0.1.1. 环境
# 主要组件 mysql : 5.5.3 elasticsearch : 5.6.16 go-mysql-elasticsearch # 环境 windows 10 go : 1.11.2 复制代码
同时也会用到 win 下 git 的命令行模式(可以运行 bash 命令)
go-mysql-elasticsearch对 mysql 和 ES 的要求为:
MySQL supported version < 8.0
ES supported version < 6.0
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
其中有两个关键的配置 Source
和 rule
。
[[rule]] schema = "mysql_es" # Mysql数据库名 table = "test_table" # Mysql表名 index = "test_index" # ES中index名 type = "doc" # 文档类型 复制代码
这一部分看官方示例就很清楚了 river.toml 和 Elasticsearch最佳实践从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 进行数据迁移
因为我在 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/ 复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 简单数据库迁移实践
- 优酷 Mac 迁移 Swift 实践
- Swift Static Libraries迁移实践
- 3 种常见有效云迁移最佳实践
- Hive 迁移 Presto 的技术实践
- 小米 Kylin 平滑迁移 HBase 实践
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Node即学即用
[英] Tom Hughes-Croucher、[英] Mike Wilson / 郑达韡 / 人民邮电出版社 / 2013-2 / 39.00元
《Node即学即用》由休斯-克劳奇、威尔逊编著,《Node即学即用》讲解如何用Node构建可扩展因特网应用,是全面的实用指南,除了详细介绍Node提供的API外,还用大量篇幅介绍了服务器事件驱动开发的重要概念。内容涉及跨服务器的并发连接、非阻塞I/O和事件驱动的编程、如何支持各种数据库和数据存储工具、NodeAPI的使用示例等。适合对JavaScript及编程有一定程度了解的读者阅读。一起来看看 《Node即学即用》 这本书的介绍吧!
JSON 在线解析
在线 JSON 格式化工具
RGB HSV 转换
RGB HSV 互转工具