java.lang.RuntimeException: Exceed max trie node in key chunk, increase reduce number to resolve the problem.(If you use the LOCAL mode, please convert it to CLUSTER mode.) io.transwarp.inceptor.util.TrieChunks.appendTrieNode_raw(RadixTrie.java:231) io.transwarp.inceptor.util.RadixTrie.findCompressedChildAndPutKey(RadixTrie.java:782) io.transwarp.inceptor.util.RadixTrie.putKey(RadixTrie.java:911) io.transwarp.inceptor.util.RadixTrie.putKey(RadixTrie.java:857) io.transwarp.inceptor.util.RadixTrie.putAndOverwriteKey(RadixTrie.java:1105)
总结 MR Job的几种运行模式 :
1.在服务器上运行yarn集群模式:
在Eclipse中开发好mr程序(在Windows或Linux中都可),然后打包成jar包,上传到服务器。
执行命令 hadoop jar jar包名 Runner类的全类名
2.在Linux中Eclipse开发平台中直接启动Runner类运行main方法,这种方式既可以为yarn集群模式,也可以为本地模式:
关键点是:
取决于一个配置参数:mapreduce.framework.name=local(yarn)
当为local时则运行为本地模式;当为yarn时则为运行yarn集群模式。
----yarn模式:
a.将mr工程导出为jar包,放在工程目录下。
b.在main方法中,加入一个配置参数,conf.set("mapreduce.job.jar","mr导出的jar包名")
----本地模式:
在Eclipse中将mr工程导出为jar包,拷贝到当前目录下,直接运行main方法。
3.在Windows的Eclipse中运行本地模式的步骤:
a.在Windows中存放hadoop的安装包,并配置其环境变量。
b.根据Windows的版本,对应的替换掉hadoop安装包中的本地库(bin、lib)
c.mr工程中不需要设置mapreduce.framework.name。
4.在Windows的Eclipse中运行yarn集群模式的步骤:
此时只添加该单一的参数,设置conf.set("mapreduce.job.jar","mr导出的jar包名")是不行的,因为在Windows中还需要其他的系统变量如:JAVA_HOME 等。因为在将job提交到服务器Linux中会有不兼容的问题出现,比如环境变量%与Linux中的$的区别。此时我们可以修改yarn-Runner方法的源码。此处修改较多。不建议使用。
1 Trie简介
Trie树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。
在本文中,对于输入的进行序列化,比如输入“单词查找树”,序列化为“单/词/查/找/树”,这样可以进行任何一种自定义的数据插入和查询。序列化输入可以根据自己的需要进行相应的改动,这样可以把Trie树结构应用到很多其他的语言和领域。
本Trie树结构的优点在于:
1 不限制子节点的数量;
2 自定义的输入序列化,突破了具体语言、应用的限制,成为一个通用的框架;
3 可以进行最大Tokens序列长度的限制;
4 根据已定阈值输出重复的字符串;
5 提供单个字符串频度查找功能;
6 速度快,在两分钟内完成1998年1月份人民日报(19056行)的重复字符串抽取工作。
2 结构示意图
![](https://img-my.csdn.net/uploads/201204/03/1333428952_6279.jpg)
3 实现代码
我自己用java实现了一个最基本的Trie树,功能有:插入单词,查找单词,删除单词,以字典序遍历打印出所有出现过的单词及频数。另有几点说明如下:
- 每 个结点存储子结点时不使用固定长度的数组,而使用Map<Character, TrieNode>结构,这样可以处理任意字符集。当然,你还得准备一个char型数组,以字典序存储要处理的所有字符,遍历的时候回用到。顺便提 一下,如果你确定处理的只涉及26个英文字母,用一个26个大小的数组来存储子结点是个不错的选择,且比较简单。
- Node结点中存 储哪些值要看实际情况,在本例中存储的是单词的出现次数。你也可以增加一个字段prefixNum,用于存储当前前缀出现次数(即含有当前前缀的单词 数)。这个参数是很有用的,而且在删除操作时,只需要从根结点往下判断第一个prefixNum==1的删除即可。自己试一下就明白了。我之所以没采用, 主要想练习一下递归算法,好久没用了。
- 前一点说结点中的数据根据实际情况而定,再举个例子。“题目:给你100000个长度不超过10的单词。对于每一个单词,我们要判断他出没出现过,如果出现了,求第一次出现在第几个位置。”对于这个题目,显然结点中就存储单词第一次出现的位置(假如当前结点是单词结尾)。
import java.util.*;
/**
* Tries数据结构(字典树) 这里只是最基本的实现,可判断某个单词是否出现过,单词出现频数等,根据需要可做其它扩展
*
* @author
*
*/
public class Trie {
private TrieNode root;
private char[] characterTable = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k',
'l', // 遍历的时候使用
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
'z'};
public Trie() {
root = new TrieNode();
}
/**
* 插入字符串
*
* @param word
*/
public void insert(String word) {
TrieNode node = root;
word = word.trim();
for (int i = 0; i < word.length(); i++) {
if (!(node.children.containsKey(word.charAt(i)))) {
node.children.put(word.charAt(i), new TrieNode());
}
node = node.children.get(word.charAt(i));
}
node.terminable = true;
node.count++;
}
/**
* 查找某个字符串
*
* @param word
* @return
*/
public boolean find(String word) {
TrieNode node = root;
for (int i = 0; i < word.length(); i++) {
if (!(node.children.containsKey(word.charAt(i)))) {
return false;
} else {
node = node.children.get(word.charAt(i));
}
}
return node.terminable; // 即便该字符串在Trie路径中,也不能说明该单词已存在,因为它有可能是某个子串
}
/**
* 删除某个字符串(必须是个单词,而不是前缀)
*
* @param word
*/
public void delete(String word) {
if (!find(word)) {
System.out.println("no this word.");
return;
}
TrieNode node = root;
deleteStr(node, word);
}
public boolean deleteStr(TrieNode node, String word) {
if (word.length() == 0) {
node.terminable = false; // 不要忘了这里信息的更新
return node.children.isEmpty();
}
if (deleteStr(node.children.get(word.charAt(0)), word.substring(1))) {
node.children.remove(word.charAt(0));
if (node.children.isEmpty() && node.terminable == false) { // 注意第二个条件,假如有"abcd"与"abc",删除abcd时,要判断中间路径上是不是另一个子串的结束
return true;
}
}
return false;
}
/**
* 以字典序输出Tire中所有出现的单词及频数
*/
public void traverse() {
StringBuffer word = new StringBuffer("");
TrieNode node = root;
traverseTrie(node, word);
}
public void traverseTrie(TrieNode node, StringBuffer word) {
if (node.terminable) {
System.out.println(word + "------" + node.count);
if (node.children.isEmpty())
return;
}
for (int i = 0; i < characterTable.length; i++) {
if (!(node.children.containsKey(characterTable[i])))
continue;
traverseTrie(node.children.get(characterTable[i]),
word.append(characterTable[i]));
word.deleteCharAt(word.length() - 1);
}
}
}
/**
* Trie结点类
*
* @author
* @param <T>
*/
class TrieNode {
public boolean terminable; // 是不是单词结尾(即叶子节点)
public int count; // 单词出现频数
public Map<Character, TrieNode> children = null;
public TrieNode() {
terminable = false;
count = 0;
children = new HashMap<Character, TrieNode>();
}
}
转自:http://blog.csdn.net/harry_lyc/article/details/7423326
http://www.tuicool.com/articles/EBB7Fr