Sqoop Oracle java.sql.SQLRecoverableException: IO 错误: Connection Reset

最近使用Sqoop将Oracle中的数据导入到Hive的时候总是出现如下错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
18/09/28 09:44:53 INFO sqoop.Sqoop: Running Sqoop version: 1.4.6-cdh5.11.0
18/09/28 09:44:53 WARN tool.BaseSqoopTool: Setting your password on the command-line is insecure. Consider using -P instead.
18/09/28 09:44:53 INFO tool.BaseSqoopTool: Using Hive-specific delimiters for output. You can override
18/09/28 09:44:53 INFO tool.BaseSqoopTool: delimiters with --fields-terminated-by, etc.
18/09/28 09:44:53 INFO oracle.OraOopManagerFactory: Data Connector for Oracle and Hadoop is disabled.
18/09/28 09:44:53 INFO manager.SqlManager: Using default fetchSize of 1000
18/09/28 09:44:53 INFO tool.CodeGenTool: Beginning code generation
18/09/28 09:46:20 ERROR manager.SqlManager: Error executing statement: java.sql.SQLRecoverableException: IO 错误: Connection reset
java.sql.SQLRecoverableException: IO 错误: Connection reset
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:467)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:546)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:236)
at org.apache.sqoop.Sqoop.main(Sqoop.java:252)
Caused by: java.net.SocketException: Connection reset
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
... 25 more
18/09/28 09:46:20 ERROR tool.ImportTool: Import failed: java.io.IOException: No columns to generate for ClassWriter
at org.apache.sqoop.orm.ClassWriter.generate(ClassWriter.java:1664)
...

今天终于解决了。

1
2
3
export HADOOP_OPTS=-Djava.security.egd=file:/dev/../dev/urandom

sqoop import -D mapred.child.java.opts="-Djava.security.egd=file:/dev/../dev/urandom"

先在命令行设置HADOOP_OPTS,然后再执行sqoop import就可以了,根据我的测试结果,最好加上mapred.child.java.opts参数,并且在第二次导入的时候一定要加上--hive-overwrite参数。
注:有时候-m需要设置成1才可以。刚开始我将-m设置成2报错,我设置成1就可以了。

在脚本中export…和sqoop import -D mapred.child.java.opts都是不能少的。

This problem occurs primarily due to the lack of a fast random number generation device on the host where the map tasks execute.

参考 https://community.hortonworks.com/questions/57497/sqoop-from-oracle-connection-reset-error.html

Excel解析工具easyexcel

Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,能够原本一个3M的excel用POI sax依然需要100M左右内存降低到KB级别,并且再大的excel不会出现内存溢出,03版依赖POI的sax模式。在上层做了模型转换的封装,让使用者更加简单方便。

Read More

子网掩码怎么理解?

从前有一个地主,有256间房子,地主家的门牌号码是“192.168.1”,那么他家第一间房子的门牌号码是192.168.1.0,第二间是192.168.1.1,…第256间的编号是192.168.1.255。

地主老了,需要把256间房子分给4个儿子,平均分配,每个儿子可以分64间。

请来一位先生主持公道,先生这么来操作:
192.168.1.0-192.168.1.63 分给大儿子
192.168.1.64-192.168.1.127 分给二儿子
192.168.1.128 -192.168.1.191 分给三儿子
192.168.1.192-192.168.1.255 分给四儿子

那如何来描述四个儿子的子网网段呢?
192.168.1.0/26
192.168.1.64/26
192.168.1.128/26
192.168.1.192/26

/26是什么鬼?
255.255.255.192的二进制是多少? “11111111-11111111-11111111-11”大家数数一共多少个1?不用数了,是26个1,为了简化子网掩码的表示,用/26代替255.255.255.192。

按位与运算
我们来看大儿子的网段192.168.1.0/26是如何得到的?

以大儿子的房间为例:
192.168.1.0-192.168.1.63

二进制表示:
192.168.1.0

11000000.10101000.00000001.00000000

192.168.1.63

11000000.10101000.00000001.00111111

首尾地址完全相同的是多少?
11000000.10101000.00000001.00

数数一共多少位?26位!那么用这个“192.168.1.0/26”就可以表示大儿子所有房间。

对照房间的门牌号码“192.168.1.199”,很显然属于四儿子的。

一个主机192.168.1.199/26 能否和直连主机192.168.1.200/24 通信?可以的因为都是四儿子的房间。

一个主机192.168.1.199/26 能否和直连主机
192.168.1.1/24 通信? 不可以因为一个是大儿子的房间,一个是四儿子的房间,无法直连通信!

From https://www.zhihu.com/question/56895036/answer/150953183 https://help.aliyun.com/knowledge_detail/40612.html

HIVE INSERT OVERWRITE和WITH AS语句同时使用

with as子句要放到insert语句的前边,并且with语句和insert之间不能又分号。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CREATE TABLE ramesh_test
(key BIGINT,
text_value STRING,
roman_value STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
LINES TERMINATED BY '\n'
STORED AS TEXTFILE;

WITH v_text
AS
(SELECT 1 AS key, 'One' AS value),
v_roman
AS
(SELECT 1 AS key, 'I' AS value)
INSERT OVERWRITE TABLE ramesh_test
SELECT v_text.key, v_text.value, v_roman.value
FROM v_text JOIN v_roman
ON (v_text.key = v_roman.key);

参考 https://stackoverflow.com/questions/38246042/hive-insert-overwrite-using-with-clause

用户画像中特征和标签的区别

用户画像中有另个概念比较重要,特征和标签,如和区分呢,网上有个介绍,感觉比较形象,在此记录一下。

一、标签包含有特征。

一个标签可以包含有很多特征,比如说公知。公知就是公共知识分子,公知是对有目的性引导舆论或自以为是地发表不成熟的批判言论,并自诩为“公共知识分子”的特定人群的特殊化简称。公共知识分子(The Public Intellectual),精确定义是具有学术背景和专业素质的知识者,进言社会并参与公共事务的行动者,具有批判精神和道义担当的理想者。而公知所代指人群缺乏作为公共知识分子所需学术性、专业性、客观公正的批判精神及道义担当。如今的网络社会,这些公知有目的性引导舆论或自以为是地发表不成熟的批判言论,并自诩为“公共知识分子”,使“公共知识分子”的形象受到了颠覆。

归纳一下:首先公知是一个变化的概念,由公共知识分子,变化为公知。
标签1:公共知识分子特征:具有专业知识/学术能力,积极参与社会事务,具有道德素质。(我不觉得必须要批判,非得要批判那叫闲的蛋疼。)
标签2:公知特征:不具有专业知识/学术能力,积极参与社会事务,不具有道德素质。(这里就有问题了,这些公知会喜欢批判的只是中国啊。)
如果把公知这个标签贴给某人,那么就意味着他基本同时具备这三条特征。

二、标签除了是多个特征的集合外,还同时覆盖多个目标。标签本来就是为了贴给多个目标的(特征当然也可以)。这就使得标签特别容易出现问题。举个例子,就是:中国产品(质量差,价格低,产量大,技术含量低)。
XX产品是中国生产的。
XX产品质量差。
结果就是贴标签的行为会有各种不相符的问题。
用的谨慎,标签是很好的工具,但是现实中嘛……

Linux Expect一键登录服务器

之前每次登录服务器都是这样的。
1.先登录堡垒机
2.选择服务器
3.输入服务器名或编号
4.先切换到root用户
5.再切换到hdfs用户
具体登录过程如下图(红框的位置需要手动输入内容):
具体登录过程
如此这样的话,每一次登录服务器,进行hadoop操作,都需要进行5步操作,如果密码不记得,还得拷贝密码,甚是麻烦,也非常的耽误时间,影响工作效率。

今天研究了一些Linux的expect自动登录功能,非常好用,在这里可以大显身手。先贴一下代码,其中的秘钥,用户名和密码需要替换成自己的。还有expect的内容和send的内容也要根据自己的实际情况进行替换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

#!/usr/bin/expect
set user wangjunbo
set host 13.6.6.9
set password RFCQQ
spawn ssh -i /Users/Documents/company/xxx.pem $user@$host
expect "*passphrase*"
send "$password\r"
if { $argc == 0 } {
set seq 1
}
if { $argc == 1 } {
#puts "not two"
set seq [lindex $argv 0]
}

if { $seq != "lll" } {

expect "*ID>*"
if { $seq == 1 || $seq == 2 } {
send "hadoop00$seq\n"
} else {
send "$seq\n"
}

expect "ops*"
send "sudo su -\n"

if { $seq == 1 || $seq == 2 } {
expect "*root@hadoop*"
send "su - hdfs\n"
if { $seq == 1 } {
expect "*hdfs@hadoop*"
send "cd shell/new/\n"
} elseif { $seq == 2 } {
expect "*hdfs@hadoop*"
send "cd /data/work/shell/\n"
}
} elseif { $seq == "app001" || $seq == "app002" } {
expect "root*"
send "cd /data/apps/recommend/\n"
}
}

interact
expect eof

$argc == 0的意思是如果没有参数,那么就默认登录hadoop001服务器。
$argc == 1的意思是如果有一个参数,就去第一个参数[lindex $argv 0]作为登录服务器名。
“ if { $argc == 0 } { “ 后边的}{之间一定要有一个空格,否则会报错“extra characters after close-brace”。
将上边的内容修改后保存为/usr/local/bin/lg文件,可能还需要使切换到root用户(Mac用户使用sudo su -切换到root用户)。
修改权限

1
chmod 777 /usr/local/bin/lg

如果不放到/usr/local/bin/目录下,在其它目录下执行,需要使用如下的方式

1
./lg

而不能用如下的方式

1
sh lg

然后使用直接在命令行使用lg进行登录:

下边是具体的效果:
具体登录过程

整个过程就输入了一个lg,然后回车就可以了,是不是很方便。