0 问题现象
在sqoop同步数据的时候,日志出现sqoop任务失败,但是到数据展示侧发现mysql表中数据已经导过去。为了更深层次的分析原因,到yarn中观察具体日志,发现报错内容为:Caused by: java.sql.SQLException: null, message from server: "Host '10.9.4.41' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'"。具体如下截图所示:
sqoop日志:
mysql侧:报错后实际数据已经导过去了
yarn 中查看具体的日志如下:
2020-12-11 19:36:40,014 INFO [AsyncDispatcher event handler] org.apache.hadoop.mapreduce.v2.app.job.impl.TaskAttemptImpl: Diagnostics report from attempt_1607676423534_0062_m_000002_0: Error: java.io.IOException: java.sql.SQLException: null, message from server: "Host '10.9.4.41' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'"
at org.apache.sqoop.mapreduce.ExportOutputFormat.getRecordWriter(ExportOutputFormat.java:79)
at org.apache.hadoop.mapred.MapTask$NewDirectOutputCollector.<init>(MapTask.java:647)
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:767)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341)
at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:170)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:422)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1866)
at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:164)
Caused by: java.sql.SQLException: null, message from server: "Host '10.9.4.41' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'"
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1078)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:975)
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1112)
at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2488)
at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2521)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2306)
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:839)
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:49)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:421)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:350)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at org.apache.sqoop.mapreduce.db.DBConfiguration.getConnection(DBConfiguration.java:302)
at org.apache.sqoop.mapreduce.AsyncSqlRecordWriter.<init>(AsyncSqlRecordWriter.java:78)
at org.apache.sqoop.mapreduce.ExportOutputFormat$ExportRecordWriter.<init>(ExportOutputFormat.java:95)
at org.apache.sqoop.mapreduce.ExportOutputFormat.getRecordWriter(ExportOutputFormat.java:77)
... 8 more
2 原因分析及解决方法
同一个ip在短时间内多次错误连接数据库,造成错误连接的次数超过设置的最大值(max_connection_errors的最大值)而导致阻塞了当前IP对数据库的请求。
知道了具体原因后,我们到MYSQL数据库执行如下操作:
- (1)flush hosts (清楚缓存)
- (2)修改max_connection_errors的次数,将该值设置大一点即可。比如:100000
如果需要永久性解决,则需要在MYSQL配置文件中修改相应的属性值。
注意点:
当客户端连接服务端超时(超过connect_timeout), 服务端就会给这个客户端记录一次error,当出错的次数达到max_connect_errors的时候,这个客户端就会被锁定。所以根据业务来尽量把这个值设置大一点,mysql默认值为10,我们可以根据具体需要设置大一点,这里设置为100000.(并非越大越好,越大被攻击时安全性越低)
根据以上我们生产环境中选择如下配置,大家根据情况进行选择:
其中
- connect_timeout:600000
- max_connect_errors:100000