0%

学习Hadoop 实现TF-IDF 算法,使用的是CDH5.13.1 VM版本,Hadoop用的是2.6.0的jar包,Maven中增加如下即可

1
2
3
4
5
6
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.6.0</version>
<scope>provided</scope>
</dependency>

代码如下:

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package top.eviltuzki.tfidf;

import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

import java.io.*;
import java.util.*;

public class App extends Configured implements Tool {

public int run(String[] strings) throws Exception {
//第一个MR,计算IDF
Job job = Job.getInstance(getConf());
job.setJarByClass(App.class);
job.setInputFormatClass(TextInputFormat.class);
job.setOutputFormatClass(TextOutputFormat.class);

job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);


job.setReducerClass(IdfReducer.class);
job.setMapperClass(IdfMap.class);
job.setNumReduceTasks(1);

String[] args = new GenericOptionsParser(getConf(), strings).getRemainingArgs();
FileInputFormat.setInputPaths(job,new Path(args[0]));
FileOutputFormat.setOutputPath(job,new Path(args[1]));

job.waitForCompletion(true);

//第二个Map,计算TF以及TF-IDF
Job job2 = Job.getInstance(getConf());
job2.setJarByClass(App.class);
job2.setInputFormatClass(TextInputFormat.class);
job2.setOutputFormatClass(TextOutputFormat.class);

job2.setMapOutputKeyClass(Text.class);
job2.setMapOutputValueClass(DoubleWritable.class);



job2.setMapperClass(TfMap.class);
job2.setNumReduceTasks(0);

args = new GenericOptionsParser(getConf(), strings).getRemainingArgs();
FileInputFormat.setInputPaths(job2,new Path(args[0]));
FileOutputFormat.setOutputPath(job2,new Path(args[2]));

job2.waitForCompletion(true);

return 0;

}

public static class IdfMap extends Mapper<LongWritable,Text,Text,IntWritable>{

/**
* 比较简单,就是进行WordCount的操作
* @param key
* @param value
* @param context
* @throws IOException
* @throws InterruptedException
*/
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String[] words = value.toString().split(" ");
Set<String> set = new HashSet<String>();
for (String word : words) {
if (word.length() > 1)
set.add(word);
}
for (String s : set) {
context.write(new Text(s),new IntWritable(1));
}
}
}

public static class IdfReducer extends Reducer<Text,IntWritable,Text,FloatWritable>{
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum =0 ;
for (IntWritable value : values) {
sum+=value.get();
}
float x =(float) ( 500.0 / sum+1);//比较笨了。。直接写死。。我这有500个样本,没想出来怎么读取数量。。。
float log = (float) Math.log(x);
context.write(key,new FloatWritable(log));
}
}

public static class TfMap extends Mapper<LongWritable,Text,Text,DoubleWritable>{
private Map<String,Double> map = new HashMap<>();


@Override
protected void setup(Context context) throws IOException, InterruptedException {
FileSystem fs = FileSystem.get(context.getConfiguration());
// 读取文件列表,不知道怎么加载路径了。。。就直接写死了。。。
Path filePath =new Path("/user/zj/tfidf/jaroutput/part-r-00000");
try (InputStream stream = fs.open(filePath)) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
String line = "";
while ((line=reader.readLine())!=null){
String[] split = line.split("\t");
if(split.length == 2)
map.put(split[0],Double.parseDouble(split[1]));
}
}
}

}
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String[] wordArray = value.toString().split(" ");
List<String> words = new ArrayList<>();
for (String s : wordArray) {
if (s.length()>1)
words.add(s);
}
Map<String,Integer> res = new HashMap<>();
for (String word : words) {
if(res.containsKey(word))
res.put(word,res.get(word)+1);//计算本文的词频
else
res.put(word,1);
}
for (Map.Entry<String, Integer> entry : res.entrySet()) {
String key1 = entry.getKey();
Integer value1 = entry.getValue();
double tf = value1*1.0 /words.size();//这里计算的就是tf,tf = 本文中这个词的次数/总词数
context.write(new Text(key1),new DoubleWritable(tf * map.get(key1)));//tf直接和idf相乘
}
}
}

public static void main(String[] args) throws Exception {
Configured conf = new Configured();
ToolRunner.run(new App(),args);
}
}

整体实现算是比较简单,第一个MR计算idf,map是统计每个文档出现过的词,都记成1次,然后reducer统计所有的,这样就得到了每一个词的idf了

公式是idf=log(总文章数/(词出现的文章数+1))

第二个Map就计算tf ,既然得到了TF就直接将Tf-IDF一起计算了。。可是读idf的结果。。没找到好办法,直接写死了。。计算idf的总文章数也是笨的直接写死了 = =!

以后学会了怎么处理再改吧。。

读取文件的样本比较简单,经过简单处理,一行是一个新闻,进行了简单的分词处理,标点符号还有单个汉字之类的就直接过滤掉了(程序中有)

1
2
3
4
5
隐瞒 外星人 存在 受 质疑 ? 或 掌握 地外文明 搜狐 据 国外 媒体 报道 , 美国 国家 航空 航天局 ( ) 在 公众 眼中 是 一个 神秘 存在 , 该 机构 负责 太空 计划 并 拥有 最 先进 的 航空 航天 技术 , 不过 随着 太空 探索 的 不断 加深 , 公众 对 它 的 疑虑 也 日 益 俱 深 , 并 认为 他们 早已 与 外星人 有 了 联系 但 并 未 公开 。 公众 质疑 隐瞒 了 外星人 消息 世界 上 有 一些 机构 或者 组织 , 因 其 承担 的 工作 之 重要 , 以及 需要 的 专业 知识 之 精深 , 在 公众 眼中 总是 蒙 着 一 层 神秘 的 面纱 。 而 它们 对 公众 的 世界观 影响力 之 强 也 超乎 想象 。 美国 国家 航空 航天局 ( 简称 ) 就是 其中 一个 典型 的 例子 。 是 美国 负责 太空 计划 的 政府 机构 , 总部 位于 华盛顿 哥伦比亚特区 , 拥有 最 先进 的 航空 航天 技术 , 参与 了 美国 阿波罗 计划 、 航天飞机 发射 、 太阳系 探测 等 航天 工程 , 为 人类 探索 太空 做出 了 巨大 贡献 。 然而 伴随 着 太空 探索 深度 的 扩大 , 公众 对 它 的 疑虑 也 与 日 俱 深 。 公众 质疑 : 他们 早已 与 外星人 取得 了 联系 , 但 一直 没有 公开 美国 气象学家 斯考特 ・ 斯蒂文斯 日前 指责 美国 国家 航空 航天局 向 公众 隐瞒 了 许多 由 太阳 轨道 望远镜 传回 地球 的 资料 , 其中 包括 有 可能 是 “ 外星 生命 ” 的 信息 。 这 成为 不曾 间断 的 对 质疑 的 又 一个 新鲜 声音 。 太阳 轨道 望远镜 是 一 项 由 美国 国家 航空 航天局 和 欧洲 空间 局 实施 的 联合 研究 计划 。 目前 , 其 所 处 位置 距离 地球 约 万 公里 , 主要 对 太阳 的 爆发 情况 、 太阳 表面 喷 出 物质 和 太阳 附近 的 彗星 进行 拍照 。 到 现在 为止 , 该 望远镜 拍摄 的 照片 数量 已 高达 数 万 张 。 其中 一些 据称 出现 了 “ 不明飞行物 ” 的 身影 。 但 要么 对 其 避而不谈 , 要么 就 解释 说是 数字 图像 在 传回 地球 的 过程 中 出现 了 差错 , 才 导致 照片 中 出现 奇特 的 物体 。 但 斯考特 ・ 斯蒂文斯 指出 , 通过 分析 望远镜 传回 地球 的 所有 照片 资料 , 他 发现 在 不同 年份 拍摄 的 照片 上 都会 出现 完全 相同 的 不明 物体 。 斯考特 ・ 斯蒂文斯 由此 断言 , 如果 这些 不明 物体 仅仅 是 偶然 的 干扰 因素 ( 如 宇宙 尘埃 或 残留 的 太阳 粒子 等 ) 造成 的 , 那么 它们 的 形状 和 尺寸 就 不 可能 总是 完全 一样 。 他 表示 这 有 可能 表明 在 太阳 的 周围 经常 有 不明飞行物 光顾 , 并且 不只 一 艘 , 而是 一个 完整 的 编队 。 “ 外星人 ” 正在 以 太阳 为 客体 开展 试验 , 并 试图 影响 太阳 的 活动 情况 。 其实 , 的 使命 和 愿景 当中 就 蕴含 了 “ 寻找 地 外 生命 ” 和 “ 星际 移民 ” 的 内容 。 而 长期 以来 , 都 有 科学家 和 普通 公众 质疑 对 公众 隐瞒 了 有关 地外文明 的 真相 , 更 有 人 指出 , 早已 与 “ 外星人 ” 取得 了 联系 , 但 出于 种种 原因 一直 没有 公开 。 年 发生 在 美国 的 阿诺德 空中 遭遇 飞碟 案 和 罗斯威尔 飞碟 坠毁 案 以及 此后 由 美国 军方 领导 的 专门 调查 现象 的 “ 蓝皮书 计划 ” 、 “ 号志 计划 ” 、 “ 新墨西哥州 怀特 沙漠 试验场 计划 ” 等 研究 活动 , 开创 了 现代 研究 的 新纪元 。 多年 来 全球 各地 收到 的 目击 案例 已 超过 万 起 , 其中 有数 十万 起 是 无法 用 自然 和 物理 现象 做出 合理 解释 的 , 人们 怀疑 它 是 一 种 超越 人类 文明 的 外星 智慧 生命 所为 。 美国 国家 射电 天文台 和 国家 航空 航天局 从 年 开始 进行 微波 监听 宇宙 文明 的 “ 奥兹 玛 计划 ” 和 “ 赛克 洛普 计划 ” 。 年月 和 年月 , 美国 先后 发射 了 先驱者 号 、 号 [| 宇宙 飞船 |] , 携带 地球人 给 外星人 的 一 封 自荐信 , 当中 镌刻 着 地球 和 太阳系 在 银河系 的 位置 , 地球人 男人 和 女人 的 形象 , 以及 表示 宇宙 间 最 丰富 的 物质 氢 的 分子 结构图 , 寄望 外星人 截获 此 信 。 到 深 空 去 探测 “ 地外文明 ” 的 存在 ? 时至 今日 , 已经 发展 成为 雇员 人数 约 万 的 大型 机构 , 年度 经费 超过 亿 美元 。 在 其 推进 的 众多 高 精 尖 项目 中 , “ 深 空 网络 ” 是 近期 的 一 大 热点 。 那么 , “ 深 空 网络 ” 到底 为 何物 ? 深 空 网络 ( , ) 是 一个 支持 星际 任务 、 无线电 通信 以及 利用 射电天文学 观察 探测 太阳系 和 宇宙 的 国际 天线 网络 , 它 是 地球 上 最大 也 是 最 敏感 的 科学 研究 用途 的 通信 系统 。 目前 深 空 网络 由 三 处 呈 度 分布 的 深 空 通信 设施 构成 , 一 处在 美国 加州 的 戈尔德斯通 , 处于 巴斯托 市 附近 的 莫哈维沙漠 之 中 ; 一 处 位于 西班牙 马德里 附近 ; 另 一 处 位于 澳大利亚 的 堪培拉 附近 。 这种 安排 使得 可以 连续 观察 地球 的 自转 的 过程 。 深 空 探测 的 一个 重要 用途 , 便 是 探索 地外文明 的 存在 。 分享
库克 : 最大压力 的 搜狐 事件 : 上周 三 , 苹果 股价 单 日 大跌 创 近 个 月 最低 , 按 当天 收盘价 计算 , 距离 月 创下 的 历史 高点 跌 去 了 逾 , 被 认为 已经 踏 上 了 熊 途 。 点评 : 我 想 库克 最近 一定 心情 不好 , 压力 很 大 。 因为 近 一 段 时间 来 , 糟糕 的 事情 一 件 接着 一 件 降临 到 苹果 头上 。 令 人 失望 的 开启 了 苹果 的 厄运 , 地图 门 、 高 管 下课 、 销售 不及 预期 , 重重 利空 叠加 之 下 , 郭台铭 的 一 句 “ 太 难 生产 了 , 我们 难以 满足 巨大 的 需求 ” , 就 成为 压垮 苹果 股价 的 最后 一 根 稻草 。 昔日 的 光环 已经 褪 尽 , 苹果 的 竞争力 和 创新力 正 遭受 前所未有 的 质疑 。 面临 掌舵 苹果 以来 的 最大 挑战 , 库克 能否 化 危 为 机 , 扭转 颓势 , 尚 不得而知 。 分享
单身贵族 也 有 品 热门 [| 数码 相机 |] 大 盘点 搜狐 数码 佳能 作为 升级 机型 , 在 诸多 细节 方面 做 了 改变 , 大幅 提升 了 对 焦 及 连 拍 性能 , 为 普及型 [| 数码 单反 相机 |] 定义 到 了 新 高度 。 新型 图像 感应器 有效像素 为 万 , 与 能 高效 处理 图像 并 控制 相机 功能 的 数字 影像 处理器 组合 , 实现 了 高画质 、 高感光度 低 噪 点 。 目前 , 佳能 报价 参数 图片 论坛 热门 软件 单机 的 最新 报价 为 元 。 重庆 掀 开 触控 新 篇章 佳能 仅 ▲ 佳能 从 外观 上 看 , 佳能 与 尺寸 重量 相差 不大 , 整体 外形尺寸 为 × × , 重 约 仅 机身 。 除了 按键 布局 基本 上 没有 变化 外 , 最大 的 改进 在于 它 采用 英寸 万 像素 可 [| 旋转 触摸屏 |] , 这 也 是 佳能 首次 将 触摸屏 设计 在 单反 上 , 配合 带来 高速 合 焦 , 可 实现 触摸 对 焦 、 触摸 快门 、 触摸 回放 功能 。 重庆 掀 开 触控 新 篇章 佳能 仅 ▲ 佳能 从 性能 上 看 , 佳能 搭载 规格 传感器 , 有效像素 达 万 。 配合 最新 型 处理器 , 实现 了 高画质 、 高感光度 低 噪 点 它 的 快门速度 为 秒 , 连 拍 速度 达 每 秒 张 , 感光度 范围 , 扩展 可 达 。 其 采用 中央 八 向 双十字 全 点 十字型 自动 对 焦 , 使 所有 自动 对 焦 区域 都 能 高精度 合 焦 。 追踪 动态 被 摄 体 持续 对 焦 的 人工智能 伺服 自动 对 焦 算法 得到 进化 , 性能 大幅 提高 。 重庆 掀 开 触控 新 篇章 佳能 仅 ▲ 佳能 编辑 点评 : 佳能 还 在 内置 相片 处理 方面 提供 给 用户 最大 的 选择 余地 , 不但 提供 了 拍摄 模式 , 还 增加 了 快速 连 拍 张 照片 合成 的 手持 夜景 模式 , 另外 相机 又 内置 了 一 系列 特效 滤镜 , 配合 屏 的 轻 触 设计 , 用户 可 更 方便 加入 不同 效果 , 输出 独 具 风格 的 照片 。 参考价格 元 我 也 要 打分 : 喜欢 一般 很 差 更 多 条 论坛 热贴 条 人 关注 分 上 一 页 下 一 页 文本 导航 第 页 尼康 第 页 佳能 套机 第 页 宾得 套机 第 页 徕卡 第 页 卡西欧 第 页 佳能 第 页 索尼 分享
索尼 美 上市 三防 设计 美元 起 搜狐 【 搜狐 数码 消息 】 月 日 消息 , 在 登录 欧洲 市场 个 月 之后 , 索尼 日前 已经 正式 于 美国 开 售 。 这 款 [| 三防 手机 |] 共有 黄 、 白 、 黑 三 种 颜色 选择 , 售价 也 因 机身 颜色 而 不同 , 分别 是 美元 、 美元 、 美元 ( 无 锁 机 ) 。 配置 方面 , 配备 了 英寸 ( ) 抗 划伤 无机 玻璃 显示屏 , 即使 屏幕 或 手指 沾 有 液体 , 仍 可 准确 跟踪 。 另外 , 机身 内部 采用 了 双核 芯片 , 内存 , 存储 空间 ( 支持 卡 拓展 ) , 万 [| 像素 摄像头 |] , [| 毫安 电池 |] 。 ( ) 分享
最新 研究 称 近 距 双子星 是 星云 奇特 喷射 流 来源 搜狐 【 搜狐 科学 消息 】 据 美国 太空 网站 报道 , 目前 , 科学家 最新 研究 表示 , 行星状星云 中 一对 彼此 环绕 的 恒星 作为 “ 宇宙 发电站 ” , 为 该 星云 壮观 喷射 流 提供 后方 能量 。 这 项 发现 揭晓 了 科学家 长期 置疑 “ 弗莱明 号 ” 行星状星云 的 喷射 流 形状 之 谜 , 这些 喷射 流 呈现 为 奇特 的 节 状 和 弯曲 结构 , 最新 研究 显示 这种 奇特 喷射 流 是 由 “ 发电站 ” 双子星 的 轨道 交互 作用 提供 动力 。 研究 报告 作者 、 智利 天文学家 亨利博芬 说 : “ 这 是 一 项 大型 天文 观测 研究 项目 , 用于 理解 奇特 、 非 对称 形状 的 行星状星云 。 ” 据 科学家 称 , 的 行星状星云 具有 不 平衡 结构 。 事实上 行星状星云 与 行星 没有 关系 , 它们 是 垂死 白矮星 生命 末期 阶段 。 博芬 研究 小组 使用 甚 大 望远镜 观测 “ 弗莱明 号 ” 行星状星云 , 据称 , 这 个 行星状星云 是 以 天文学家 威廉米娜 弗莱明 命名 , 她 于 年 在 哈佛大学 天文台 观测 发现 这 个 行星状星云 。 数 十年 以来 , 天文学家 一直 对 环绕 该 星云 周围 的 奇特 气体 迷惑不解 , 博芬 和 他 的 研究 同事 在 计算机 模拟 系统 上 结合 最新 观测 数据 , 证实 了 一对 白矮星 充当 着 “ 宇宙 发电站 ” 。 多数 双子星 轨道 周期 为数 百年 或者 数 千年 , 但是 “ 弗莱明 号 ” 行星状星云 的 光谱 数据 显示 其中 的 双子 恒星 运行 速度 更 快 , 快速 变化 的 光谱线 表明 这 对 恒星 轨道 周期 仅 为 天 。 博芬 说 : “ 这 是 一对 非常 接近 的 双子星 系统 。 ” 他 还 指出 , 其它 双子星 系统 中 也 发现 类似 的 轨道 周期 。 这 个 行星状星云 中 的 恒星 曾 共享 环绕 星云 的 气体 层 , 在 其它 双子星 系统 中 也 非常 普遍 。 然而 , 环绕 星云 的 气体 喷射 流 并 不是 当前 存在 。 这 项 研究 报告 现 发表 在 月 日 出版 的 《 科学 》 杂志 上 。 起初 , “ 弗莱明 号 ” 行星状星云 中 这 两 颗 恒星 相距甚远 , 较 大 的 恒星 逐渐 从 一 颗 红巨星 演变 为 体积 庞大 的 渐近 巨 支 星 , 此时 它 将 形成 数 百倍 太阳 直径 。 这 颗 超大 质量 恒星 释放 的 气体 流 之后 流向 体积 较 小 的 邻近 恒星 ― ― 一 颗 寒冷 的 白矮星 , 此时 气体 流 像 从 水龙头 中 释放 出来 一样 , 从 这 两 颗 恒星 向 外 喷射 。 博芬 称 , 这 只是 恒星 生命 历程 中 非常 短暂 的 一个 时期 , 仅 持续 年 。 随着 时间 的 流逝 , 巨大 的 恒星 失去 了 它们 的 气体 , 变成 了 一 颗 白矮星 。 气体 将 恒星 包裹 起来 , 推动 它们 逐渐 靠拢 在 一起 。 当 恒星 逐渐 接近 , 包裹 它们 的 气体 将 被 驱逐 , 该 气体 喷射 流 的 “ 水龙头 ” 也 将 关闭 。 博芬 研究 小组 认为 , 这种 现象 普遍 存在 于 行星状星云 中 的 双子星 系统 , 但 同时 强调 需要 更 多 的 观测 来 证实 这 一 理论 。 ( 卡麦拉 ) 分享

Maven 打包之后运行

命令如下:

1
hadoop jar learn-1.0-SNAPSHOT.jar top.eviltuzki.tfidf.App /user/zj/tfidf/allcontent /user/zj/tfidf/jaroutput /user/zj/tfidf/finaloutput

输出结果就简单看一下吧 = =

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[cloudera@quickstart tfidf]$ hadoop fs -cat /user/zj/tfidf/finaloutput/part-m-00000 |grep -v E| sort -k2 -rn |head -n 20
宋体 2.2809544503092782
宋体 1.3156868388809182
东北虎 0.7394429830508474
网盘 0.571717673015873
网盘 0.571717673015873
电视广告 0.5665861818181818
出货量 0.5347087089347079
黑色星期五 0.5342098285714285
雪豹 0.5053336216216217
红茶 0.4936592475247525
携程 0.47571826851851845
野生 0.47535620338983053
音乐 0.4412029517241379
角膜 0.43890478873239436
美食 0.4262510461538462
摇椅 0.42329096944444444
摇椅 0.42329096944444444
美景 0.4227268664556961
酷派 0.42054887452054796
朝鲜 0.4166495891891892

也不知道为啥会出现重复的,个人想法应该是多篇文章中统计出来的吧。。。但是分值都一样- -有点。。。额。。也许是重复的新闻也说不好。。。

在IDE下调试怎么也没有发现问题,但是部署到服务器上,提示找不到资源,找了半天资料总算是找到了原因:
Jar包中的资源加载不能使用File方式,只能使用InputStream方式读取。知道原因就好解决了,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
try {
URL url = ScoreLoadUtil.class.getClassLoader().getResource("LiangXingScoreDic");//这里不要加classpath: ,否则也是找不到
List<String> list = new ArrayList<>();
try (InputStream stream = url.openStream(); InputStreamReader isr=new InputStreamReader(stream,"utf-8"); BufferedReader br = new BufferedReader(isr)) {
String line;
while ((line=br.readLine())!=null){
list.add(line);
}
}
logger.error(list.size());
for (String s : list) {
String[] split = s.split("\t");
if (split.length!=2){
logger.error(s);
continue;
}

liangXingMap.put(split[0],Float.parseFloat(split[1]));

}
} catch (IOException e) {
logger.error(e);
}

网上教程有一种说法用ResourceUtils的extractJarFileURL方法可以读取,但是试了试还是有问题,这个方法相当于把jar:xxxxx!resource给提取成xxxxxxxx,这样得到的是jar文件,并不是要加载的内容,可能是我用的方法不太对吧,不过使用InputStream的方式是没问题了。

程序运行时出现如下问题:

程序运行报错图

从网上查资料,有说重启format的。。有说/etc/hosts出问题的。。。

反正都试了一遍。。还是有这个问题

后来看日志,发现问题是访问服务器9001端口访问不到。。开始怀疑自己配置文件有问题。既然是9001,那就肯定是mapred的问题,

看了配置文件内容

1
2
3
4
      <property>
<name>mapred.job.tracker</name>
<value>http://192.168.254.128:9001</value>
</property>

也没发现有什么问题,ip换成host中的master也不行,看官方配置文档,发现没有http,删掉http之后,重启dataNode没了0.0

日志说有冲突什么的。。。估计就是format问题。。清理了tmp和hdfs,重新format,然后再启动,成功!

附上一份正确的配置

1
2
3
4
       <property>
<name>mapred.job.tracker</name>
<value>192.168.254.128:9001</value>
</property>

ES查询中,先聚合,在聚合结果中进行过滤

1
2
3
4
5
6
7
8
9
10
11
12
{
"size": 0,
"aggs": {
"terms": {
"terms": {
"field": "mustTags",
"include": ".*总则.*",
"size": 999
}
}
}
}

有include,自然就有exclude,用法一样,支持通配符匹配(正则方式)。 

对分词字段检索使用的通常是match查询,对于短语查询使用的是matchphrase查询,但是并不是matchphrase可以直接对分词字段进行不分词检索(也就是业务经常说的精确匹配),下面有个例子,使用Es的请注意。
某个Index下面存有如下内容:

1
2
3
4
{
"id": "1",
"fulltext": "亚马逊卓越有限公司诉讼某某公司"
}

其中fulltext使用ik分词器进行分词存储,使用ik分词结果如下

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
"tokens": [
{
"token": "亚马逊",
"start_offset": 0,
"end_offset": 3,
"type": "CN_WORD",
"position": 0
},
{
"token": "亚",
"start_offset": 0,
"end_offset": 1,
"type": "CN_WORD",
"position": 1
},
{
"token": "马",
"start_offset": 1,
"end_offset": 2,
"type": "CN_CHAR",
"position": 2
},
{
"token": "逊",
"start_offset": 2,
"end_offset": 3,
"type": "CN_WORD",
"position": 3
},
{
"token": "卓越",
"start_offset": 3,
"end_offset": 5,
"type": "CN_WORD",
"position": 4
},
{
"token": "卓",
"start_offset": 3,
"end_offset": 4,
"type": "CN_WORD",
"position": 5
},
{
"token": "越有",
"start_offset": 4,
"end_offset": 6,
"type": "CN_WORD",
"position": 6
},
{
"token": "有限公司",
"start_offset": 5,
"end_offset": 9,
"type": "CN_WORD",
"position": 7
},
{
"token": "有限",
"start_offset": 5,
"end_offset": 7,
"type": "CN_WORD",
"position": 8
},
{
"token": "公司",
"start_offset": 7,
"end_offset": 9,
"type": "CN_WORD",
"position": 9
},
{
"token": "诉讼",
"start_offset": 9,
"end_offset": 11,
"type": "CN_WORD",
"position": 10
},
{
"token": "讼",
"start_offset": 10,
"end_offset": 11,
"type": "CN_WORD",
"position": 11
},
{
"token": "某某",
"start_offset": 11,
"end_offset": 13,
"type": "CN_WORD",
"position": 12
},
{
"token": "某公司",
"start_offset": 12,
"end_offset": 15,
"type": "CN_WORD",
"position": 13
},
{
"token": "公司",
"start_offset": 13,
"end_offset": 15,
"type": "CN_WORD",
"position": 14
}
]

对于如上结果,如果进行matchphrase查询 “亚马逊卓越”,无法匹配出任何结果
因为对 “亚马逊卓越” 进行分词后的结果为:

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
47
48
49
50
51
52
53
{
"tokens": [
{
"token": "亚马逊",
"start_offset": 0,
"end_offset": 3,
"type": "CN_WORD",
"position": 0
},
{
"token": "亚",
"start_offset": 0,
"end_offset": 1,
"type": "CN_WORD",
"position": 1
},
{
"token": "马",
"start_offset": 1,
"end_offset": 2,
"type": "CN_CHAR",
"position": 2
},
{
"token": "逊",
"start_offset": 2,
"end_offset": 3,
"type": "CN_WORD",
"position": 3
},
{
"token": "卓越",
"start_offset": 3,
"end_offset": 5,
"type": "CN_WORD",
"position": 4
},
{
"token": "卓",
"start_offset": 3,
"end_offset": 4,
"type": "CN_WORD",
"position": 5
},
{
"token": "越",
"start_offset": 4,
"end_offset": 5,
"type": "CN_CHAR",
"position": 6
}
]
}

和存储的内容对比发现 原文存储中包含词语 “越有”,而查询语句中并不包含“越有”,包含的是“越”,因此使用matchphrase短语匹配失败,也就导致了无法检索出内容。
还是这个例子,换个词语进行检索,使用“亚马逊卓越有”,会发现竟然检索出来了,对“亚马逊卓越有”进行分词得到如下结果:

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
47
48
49
50
51
52
53
{
"tokens": [
{
"token": "亚马逊",
"start_offset": 0,
"end_offset": 3,
"type": "CN_WORD",
"position": 0
},
{
"token": "亚",
"start_offset": 0,
"end_offset": 1,
"type": "CN_WORD",
"position": 1
},
{
"token": "马",
"start_offset": 1,
"end_offset": 2,
"type": "CN_CHAR",
"position": 2
},
{
"token": "逊",
"start_offset": 2,
"end_offset": 3,
"type": "CN_WORD",
"position": 3
},
{
"token": "卓越",
"start_offset": 3,
"end_offset": 5,
"type": "CN_WORD",
"position": 4
},
{
"token": "卓",
"start_offset": 3,
"end_offset": 4,
"type": "CN_WORD",
"position": 5
},
{
"token": "越有",
"start_offset": 4,
"end_offset": 6,
"type": "CN_WORD",
"position": 6
}
]
}

注意到了吗?这里出现了越有这个词,这也就是说现在的分词结果和之前的全文分词结果完全一致了,所以matchphrash也就找到了结果。

再换一个极端点的例子,使用“越有限公司”去进行检索,你会惊讶的发现,竟然还能检索出来,对“越有限公司”进行分词,结果如下:

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
{
"tokens": [
{
"token": "越有",
"start_offset": 0,
"end_offset": 2,
"type": "CN_WORD",
"position": 0
},
{
"token": "有限公司",
"start_offset": 1,
"end_offset": 5,
"type": "CN_WORD",
"position": 1
},
{
"token": "有限",
"start_offset": 1,
"end_offset": 3,
"type": "CN_WORD",
"position": 2
},
{
"token": "公司",
"start_offset": 3,
"end_offset": 5,
"type": "CN_WORD",
"position": 3
}
]
}

这个结果和原文中的结果又是完全一致(从越有之后的内容一致),所以匹配出来了结果,注意点这里有个词语“有限公司”,检索词语如果我换成了“越有限”,就会发现没有查询到内容,因为“越有限”分词结果为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"tokens": [
{
"token": "越有",
"start_offset": 0,
"end_offset": 2,
"type": "CN_WORD",
"position": 0
},
{
"token": "有限",
"start_offset": 1,
"end_offset": 3,
"type": "CN_WORD",
"position": 1
}
]
}

“越有”这个词是包含的,”有限”这个词语也是包含的,但是中间隔了一个“有限公司”,所以没有完全一致,也就匹配不到结果了。这时候如果我检索条件设置matchphrase的slop=1,使用“越有限”就能匹配到结果了,现在可以明白了,其实position的位置差就是slop的值,而matchphrase并不是所谓的词语拼接进行匹配,还是需要进行分词,以及position匹配的。

  • 直接打开 163 源网站:http://mirrors.163.com/.help/centos.html

  • 按照使用说明,还是先备份一下源(使用下面的命令重命名原来的源,如果有错误,再改回来):

1
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
  • 转到源目录:
1
cd /etc/yum.repos.d/
  • 按照自己的版本下载源,我是 centos 7,使用命令:
1
wget http://mirrors.163.com/.help/CentOS7-Base-163.repo
  • 运行以下命令生成缓存:
    1
    2
    yum clean all
    yum makecache


说明:该部署文档系统环境为Centos7——64位


一、在线安装

基础安装

  • 安装JDK,wget(如果已经安装请跳过)
    • 注:ES要求至少Java 7,官方建议使用版本为1.8.0_73
    • sudo yum install java wget
    • 查看版本:java -version
  • 下载ElasticSearch 2.4 RPM 安装包
  • 使用命令默认安装
    • sudo rpm -ivh elasticsearch-2.4.0.rpm
  • 安装后其主要文件位于/usr/share/elasticsearch下,配置文件位于/etc/elasticsearch目录下(该目录默认无权限直接查看,需要root权限)。
  • 启动ElasticSearch
    • sudo service elasticsearch start 或者sudo systemctl start elasticsearch.service
    • 查看启动状态:sudo systemctl status elasticsearch
  • 确认Es是否已经启动
    • curl localhost:9200

ik分词器安装

  • 在/usr/share/elasticsearch/plugins/目录下创建ik目录
    • sudo mkdir /usr/share/elasticsearch/plugins/ik
    • cd /usr/share/elasticsearch/plugins/ik
  • 下载IK分次器
  • 解压所有文件放到ik目录下
    • unzip elasticsearch-analysis-ik-1.10.0.zip
    • 执行命令sudo mv /usr/share/elasticsearch/plugins/ik/config /etc/elasticsearch/,将ik分词器的配置文件拷贝到es的配置目录下,执行命令sudo mv /etc/elasticsearch/config /etc/elasticsearch/ik将config文件重命名为ik
  • 重启ElasticSearch
    • sudo service elasticsearch restart

Head 插件安装

  • 进入ElasticSearch的bin目录
    • cd /usr/share/elasticsearch/bin/
  • 执行安装head插件命令
    • sudo ./plugin install mobz/elasticsearch-head
  • 重启ElasticSearch
    • sudo service elasticsearch restart

生产环境过滤Delete请求插件


二、离线安装

基础安装

  • 安装JDK
    • 下载rpm包:
    • 安装:sudo rpm -ivh jdk-8u121-linux-x64.rpm
    • 查看版本:java -version,若版本不是上一步安装,则说明系统原本已经安装了不同版本的JDK,需要进行选择,操作下一步,否则不需要
    • 执行命令:alternatives –config java,选择对应版本的number,回车即可。
  • 安装Elasticsearch 2.4.0
    • 下载rpm包:elasticsearch-2.4.0.rpm
    • 安装:rpm -ivh elasticsearch-2.4.0.rpm。安装后安装包在/usr/share/elasticsearch下,配置文件位于/etc/elasticsearch目录下

插件安装

  • ik分词器插件
    • 插件文件:elasticsearch-analysis-ik-1.10.0.zip
    • 执行命令sudo mkdir /home/ik创建ik目录,将插件拷贝到/home/ik目录下,执行命令unzip elasticsearch-analysis-ik-1.10.0.zip解压,得到config目录和jar包。
    • 执行命令sudo mv /home/ik /usr/share/elasticsearch/plugins/,将ik分词插件剪切到es的插件目录下
    • 执行命令sudo mv /usr/share/elasticsearch/plugins/ik/config /etc/elasticsearch/将ik分词器的配置文件拷贝到es的配置目录下,执行命令sudo mv /etc/elasticsearch/config /etc/elasticsearch/ik将config文件重命名为ik
  • head插件
    • 插件文件:head.zip
    • 将插件文件拷贝到/home目录下,执行命令sudo unzip head.zip解压
    • 执行命令sudo mv /home/head /home/ik /usr/share/elasticsearch/plugins/将head目录剪切到es的插件目录下。

三、配置

基础配置

  • 执行命令sudo mkdir /data1(若/data1目录不存在),sudo mkdir /data1/es(若/data1/es目录不存在),sudo mkdir /data1/es/data建立es数据存储目录,sudo mkdir /data1/es/logs建立es日志存储目录。注:es的数据和日志目录需要保存到数据盘上,保证足够的容量。

  • 执行命令sudo vim /etc/elasticsearch/elasticsearch.yml打开es的配置文件

  • 配置说明:

    1
    2
    3
    4
    5
    6
    7
    8
    cluster.name: ld_cluster_test    #集群名
    node.name: node-230 #结点名称
    path.data: /data1/es/data #数据存储目录
    path.logs: /data1/es/logs #日志存储目录
    network.host: 10.200.x.x #本机IP
    http.port: 9200 #访问端口
    discovery.zen.ping.unicast.hosts: ["10.200.x.x", "10.200.x.x"] #集群中其他结点所在IP
    cluster.routing.allocation.disk.watermark.low: "90%" #es所占数据盘容量的最大百分比

    执行脚本配置

  • 执行命令sudo vim /etc/sysconfig/elasticsearch打开es执行脚本系统配置文件

  • 配置说明:

    • ES_HEAP_SIZE=16g #该值设为机器最大内存的一半,查看内存命令:grep MemTotal /proc/meminfo
    • MAX_OPEN_FILES=65535 #最大文件描述符,推荐64k

四、启动


####类型相关

  • 基本类型

    1
    2
    3
    4
    5
    6
    7
    bool:布尔值 (true or false), one byte
    byte:有符号字节
    i16:16位有符号整型
    i32:32位有符号整型
    i64:64位有符号整型
    double:64位浮点型
    string:未知编码或者二进制的字符串
  • 结构体和异常类型

    • Thrift 结构体 (struct) 在概念上类似于 C 语言结构体类型,在 java 中 Thrift 结构体将会被转换成面向对象语言的类。
1
2
3
4
5
6
struct UserDemo {
  1: i32 id;
  2: string name;
  3: i32 age = 25;
  4: string phone;
}
1
2
3
4
5
6
7
struct 不能继承,但是可以嵌套,不能嵌套自己
其成员都是有明确类型
成员是被正整数编号过的,其中的编号使不能重复的,这个是为了在传输过程中编码使用
成员分割符可以是逗号(,)或是分号(;),而且可以混用,但是为了清晰期间,建议在定义中只使用一种,比如java学习者可以就使用逗号(;)
字段会有optional和required之分
每个字段可以设置默认值
同一文件可以定义多个struct,也可以定义在不同的文件,进行include引入
  • 容器类型
    1
    2
    3
    list<t>:元素类型为t的有序表,容许元素重复。对应java的ArrayList,C# 中的 List<T>
    set<t>:元素类型为t的无序表,不容许元素重复。对应java和C#中的的HashSet
    map<t,t>:键类型为t,值类型为t的kv对,键不容许重复。对对应Java的HashMap,C#中的Dictionary
  • 服务类型
    1
    2
    3
    4
    service QuerySrv{
      UserDemo qryUser(1:string name, 2:i32 age);
      string queryPhone(1:i32 id);
    }
  • 命名空间
    • Thrift 中的命名空间类似于 java 中的 package,C#中的namespace,它们提供了一种组织(隔离)代码的简便方式。名字空间也可以用于解决类型定义中的名字冲突。

###传输

  • 传输协议
    • 上总体可划分为文本 (text) 和二进制 (binary) 传输协议两大类
1
2
3
4
TBinaryProtocol:是Thrift的默认协议,使用二进制编码格式进行数据传输,基本上直接发送原始数据   
TCompactProtocol:压缩的、密集的数据传输协议,基于Variable-length quantity的zigzag 编码格式
TJSONProtocol:以JSON (JavaScript Object Notation)数据编码协议进行数据传输
TDebugProtocol:常常用以编码人员测试,以文本的形式展现方便阅读
  • 传输方式
    • TSocket:阻塞型 socket,用于客户端,采用系统函数 read 和 write 进行读写数据。
    • TServerSocket:非阻塞型 socket,用于服务器端,accecpt 到的 socket 类型都是 TSocket(即阻塞型 socket)。
    • TBufferedTransport 和 TFramedTransport 都是有缓存的,均继承TBufferBase,调用下一层 TTransport 类进行读写操作吗,结构极为相似。其中 TFramedTransport 以帧为传输单位,帧结构为:4个字节(int32_t)+传输字节串,头4个字节是存储后面字节串的长度,该字节串才是正确需要传输的数据,因此 TFramedTransport 每传一帧要比 TBufferedTransport 和 TSocket 多传4个字节。
    • TMemoryBuffer 继承 TBufferBase,用于程序内部通信用,不涉及任何网络I/O,可用于三种模式:(1)OBSERVE模式,不可写数据到缓存;(2)TAKE_OWNERSHIP模式,需负责释放缓存;(3)COPY模式,拷贝外面的内存块到TMemoryBuffer。
    • TFileTransport 直接继承 TTransport,用于写数据到文件。对事件的形式写数
      据,主线程负责将事件入列,写线程将事件入列,并将事件里的数据写入磁盘。这里面用到了两个队列,类型为 TFileTransportBuffer,一个用于主线程写事件,另一个用于写线程读事件,这就避免了线程竞争。在读完队列事件后,就会进行队列交换,由于由两个指针指向这两个队列,交换只要交换指针即可。它还支持以 chunk(块)的形式写数据到文件。
    • TFDTransport 是非常简单地写数据到文件和从文件读数据,它的 write 和
      read 函数都是直接调用系统函数 write 和 read 进行写和读文件。
    • TSimpleFileTransport 直接继承 TFDTransport,没有添加任何成员函数和成员变量,不同的是构造函数的参数和在 TSimpleFileTransport 构造函数里对父类进行了初始化(打开指定文件并将fd传给父类和设置父类的close_policy为CLOSE_ON_DESTROY)。
    • TZlibTransport 跟 TBufferedTransport 和 TFramedTransport一样,调用下一层 TTransport 类进行读写操作。它采用<zlib.h>提供的 zlib 压缩和解压缩库函数来进行压解缩,写时先压缩再调用底层 TTransport 类发送数据,读时先调用 TTransport 类接收数据再进行解压,最后供上层处理。
    • TSSLSocket 继承 TSocket,阻塞型 socket,用于客户端。采用 openssl 的接口进行读写数据。checkHandshake()函数调用 SSL_set_fd 将 fd 和 ssl 绑定在一起,之后就可以通过 ssl 的 SSL_read和SSL_write 接口进行读写网络数据。
    • TSSLServerSocket 继承 TServerSocket,非阻塞型 socket, 用于服务器端。accecpt 到的 socket 类型都是 TSSLSocket 类型。
    • THttpClient 和 THttpServer 是基于 Http1.1 协议的继承 Transport 类型,均继承 THttpTransport,其中 THttpClient 用于客户端,THttpServer 用于服务器端。两者都调用下一层 TTransport 类进行读写操作,均用到TMemoryBuffer 作为读写缓存,只有调用 flush() 函数才会将真正调用网络 I/O 接口发送数据。
    • TTransport 是所有 Transport 类的父类,为上层提供了统一的接口而且通过 TTransport 即可访问各个子类不同实现,类似多态。

##Ubuntu

  • 安全结束apt-get
1
2
3

sudo dpkg -r <package name>

  • 安装VPN ShadowSocks-qt5
1
2
3
4
5
6
7

sudo add-apt-repository ppa:hzwhuang/ss-qt5

sudo apt-get update

sudo apt-get install shadowsocks-qt5

  • apt-get异常结束引起的问题
1
2
3
4
5

vim /var/lib/dpkg/status

删除掉对应的整个Package

  • 删除libreoffice
1
2
3

sudo apt-get remove libreoffice-common

  • 删除Amazon的链接
1
2
3

sudo apt-get remove unity-webapps-common

  • 删掉基本不用的自带软件
1
2
3
4
5

sudo apt-get remove thunderbird totem rhythmbox empathy brasero simple-scan gnome-mahjongg aisleriot gnome-mines cheese transmission-common gnome-orca webbrowser-app gnome-sudoku landscape-client-ui-install

sudo apt-get remove onboard deja-dup

  • 安装ExFat文件系统驱动
1
2
3

sudo apt-get install exfat-utils

  • 移动Unity所处位置
1
2
3

gsettings set com.canonical.Unity.Launcher launcher-position Bottom

  • 点击图标最小化
1
2
3

gsettings set org.compiz.unityshell:/org/compiz/profiles/unity/plugins/unityshell/ launcher-minimize-window true

  • 安装Mono
1
2
3
4
5
6
7
8
9

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF

echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list

sudo apt-get update

sudo apt-get install mono-compete

  • 安装WPS-Office
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

安装WPS Office后

http://download.csdn.net/download/wl1524520/6333049

解压到 /usr/share/fonts/ 目录下,解压出来的目录为wps_symbol_fonts

cd /usr/share/fonts/
chmod 755 wps_symbol_fonts
cd /usr/share/fonts/wps_symbol_fonts
chmod 644 *

mkfontdir
mkfontscale
fc-cache

  • 安装为知笔记
1
2
3
4
5

$ sudo add-apt-repository ppa:wiznote-team
$ sudo apt-get update
$ sudo apt-get install wiznote

  • 安装SSTP VPN协议
1
2
3
4
5
6
7
8
9

$ sudo add-apt-repository ppa:eivnaes/network-manager-sstp

$ sudo apt-get update

$ sudo apt-get install sstp-client

$ sudo apt-get install network-manager-sstp-gnome