- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
刚刚开始编写 Hadoop MR 作业。希望我们能尽快切换到 Spark,但我们目前仍坚持使用 MR。
我想按记录值的散列值对记录进行分组。但我想用完全不相关的东西对它们进行排序——它们值中的时间戳。我对如何最好地做到这一点感到困惑。我看到两个选项:
1) 第一个 MR 作业计算其映射器中每个值的散列,然后将该散列的所有记录减少到它想要的相同值(我实际上有这么多工作,正如我们现在需要的那样).然后链接第二个 MR 作业,该作业根据值中的时间戳对上面的 reducer 的输出进行重新排序。效率低下?
2) 我已经阅读了一些关于如何使用复合键的博客/帖子,所以也许我可以一步完成所有这些?我会创建某种复合键,它既有用于分组的散列,又有用于在映射器中排序的时间戳。但我不清楚这是否可能。如果排序与分组完全无关,它还能正确分组吗?也不确定我需要实现哪些接口(interface)以及我需要创建哪些类或如何配置它。
我不是在谈论次要排序。对于每次 reduce 调用,我不关心 Iterator 中对象的顺序。我关心事物从 reducer 发出的顺序,需要按时间戳进行全局排序。
执行此类操作的推荐方法是什么?
最佳答案
如果您可以使用之前封装分组和排序属性的复合键来减少,那绝对有可能。
假设您需要一个包含 int 哈希码和长时间戳的 key 。然后你需要实现一个可写的元组(比如 IntLongPair),你可以在其中定义你的用例所需的各种比较器和分区器。
所以你将你的工作设置成这样(稍后我将回到可能的 IntLongPair 实现):
job.setPartitionerClass(IntLongPair.IntOnlyPartitioner.class); //partition by your hash code stored in the int part of the part
job.setGroupingComparatorClass(IntLongPair.IntAscComparator.class); //your hash code grouping - perhaps does not matter ascending or descending
job.setSortComparatorClass(IntLongPair.IntDescLongAscComparator.class); //assuming you need newest items first
大号
这是您可以使用的 IntLongPair:
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.RawComparator;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator;
import org.apache.hadoop.mapreduce.Partitioner;
public class IntLongPair implements WritableComparable<IntLongPair> {
private IntWritable intVal = new IntWritable();
private LongWritable longVal = new LongWritable();
public void write(DataOutput d) throws IOException {
intVal.write(d);
longVal.write(d);
}
public void readFields(DataInput di) throws IOException {
intVal.readFields(di);
longVal.readFields(di);
}
/**
* Natural order is int first, long next
* @param o
* @return
*/
public int compareTo(IntLongPair o) {
int diff = intVal.compareTo(o.intVal);
if (diff != 0) {
return diff;
}
return longVal.compareTo(o.longVal);
}
public IntWritable getInt() {
return intVal;
}
public void setInt(IntWritable intVal) {
this.intVal = intVal;
}
public void setInt(int intVal) {
this.intVal.set(intVal);
}
public LongWritable getLong() {
return longVal;
}
public void setLong(LongWritable longVal) {
this.longVal = longVal;
}
public void setLong(long longVal) {
this.longVal.set(longVal);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final IntLongPair other = (IntLongPair) obj;
if (this.intVal != other.intVal && (this.intVal == null || !this.intVal.equals(other.intVal))) {
return false;
}
if (this.longVal != other.longVal && (this.longVal == null || !this.longVal.equals(other.longVal))) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 3;
hash = 47 * hash + (this.intVal != null ? this.intVal.hashCode() : 0);
hash = 47 * hash + (this.longVal != null ? this.longVal.hashCode() : 0);
return hash;
}
@Override
public String toString() {
return "IntLongPair{" + intVal + ',' + longVal + '}';
}
public IntWritable getFirst() {
return intVal;
}
public LongWritable getSecond() {
return longVal;
}
public void setFirst(IntWritable value) {
intVal.set(value.get());
}
public void setSecond(LongWritable value) {
longVal.set(value.get());
}
public static class Comparator extends WritableComparator {
public Comparator() {
super(IntLongPair.class);
}
@Override
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
return compareBytes(b1, s1, l1, b2, s2, l2);
}
}
static { // register this comparator
WritableComparator.define(IntLongPair.class, new Comparator());
}
public static class IntDescLongAscComparator implements RawComparator<IntLongPair> {
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
int comp = IntWritable.Comparator.compareBytes(b1, s1, 4, b2, s2, 4);
if (comp != 0) {
return -comp;
}
return LongWritable.Comparator.compareBytes(b1, s1 + 4, 8, b2, s2 + 4, 8);
}
public int compare(IntLongPair o1, IntLongPair o2) {
int comp = o1.getInt().compareTo(o2.getInt());
if (comp != 0) {
return -comp;
}
return o1.getLong().compareTo(o2.getLong());
}
}
public static class LongAscIntAscComparator implements RawComparator<IntLongPair> {
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
int comp = LongWritable.Comparator.compareBytes(b1, s1 + 4, 8, b2, s2 + 4, 8);
if (comp != 0) {
return comp;
}
return IntWritable.Comparator.compareBytes(b1, s1, 4, b2, s2, 4);
}
public int compare(IntLongPair o1, IntLongPair o2) {
int comp = o1.getLong().compareTo(o2.getLong());
if (comp != 0) {
return comp;
}
return o1.getInt().compareTo(o2.getInt());
}
}
public static class LongAscIntDescComparator implements RawComparator<IntLongPair> {
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
int comp = LongWritable.Comparator.compareBytes(b1, s1 + 4, 8, b2, s2 + 4, 8);
if (comp != 0) {
return comp;
}
return -IntWritable.Comparator.compareBytes(b1, s1, 4, b2, s2, 4);
}
public int compare(IntLongPair o1, IntLongPair o2) {
int comp = o1.getLong().compareTo(o2.getLong());
if (comp != 0) {
return comp;
}
return -o1.getInt().compareTo(o2.getInt());
}
}
public static class LongDescIntAscComparator implements RawComparator<IntLongPair> {
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
int comp = LongWritable.Comparator.compareBytes(b1, s1 + 4, 8, b2, s2 + 4, 8);
if (comp != 0) {
return -comp;
}
return IntWritable.Comparator.compareBytes(b1, s1, 4, b2, s2, 4);
}
public int compare(IntLongPair o1, IntLongPair o2) {
int comp = o1.getLong().compareTo(o2.getLong());
if (comp != 0) {
return -comp;
}
return o1.getInt().compareTo(o2.getInt());
}
}
public static class LongDescIntDescComparator implements RawComparator<IntLongPair> {
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
int comp = LongWritable.Comparator.compareBytes(b1, s1 + 4, 8, b2, s2 + 4, 8);
if (comp != 0) {
return -comp;
}
return -IntWritable.Comparator.compareBytes(b1, s1, 4, b2, s2, 4);
}
public int compare(IntLongPair o1, IntLongPair o2) {
int comp = o1.getLong().compareTo(o2.getLong());
if (comp != 0) {
return -comp;
}
return -o1.getInt().compareTo(o2.getInt());
}
}
public static class IntAscComparator implements RawComparator<IntLongPair> {
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
return IntWritable.Comparator.compareBytes(b1, s1, 4, b2, s2, 4);
}
public int compare(IntLongPair o1, IntLongPair o2) {
return o1.getInt().compareTo(o2.getInt());
}
}
public static class IntDescComparator implements RawComparator<IntLongPair> {
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
return -IntWritable.Comparator.compareBytes(b1, s1, 4, b2, s2, 4);
}
public int compare(IntLongPair o1, IntLongPair o2) {
return -o1.getInt().compareTo(o2.getInt());
}
}
public static class LongAscComparator implements RawComparator<IntLongPair> {
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
return LongWritable.Comparator.compareBytes(b1, s1 + 4, 8, b2, s2 + 4, 8);
}
public int compare(IntLongPair o1, IntLongPair o2) {
return o1.getLong().compareTo(o2.getLong());
}
}
public static class LongDescComparator implements RawComparator<IntLongPair> {
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
return -LongWritable.Comparator.compareBytes(b1, s1 + 4, 8, b2, s2 + 4, 8);
}
public int compare(IntLongPair o1, IntLongPair o2) {
return -o1.getLong().compareTo(o2.getLong());
}
}
/**
* Partition based on the long part of the pair.
*/
public static class LongOnlyPartitioner extends Partitioner<IntLongPair, Writable> {
@Override
public int getPartition(IntLongPair key, Writable value,
int numPartitions) {
return Math.abs(key.getLong().hashCode() & Integer.MAX_VALUE) % numPartitions;
}
}
/**
* Partition based on the int part of the pair.
*/
public static class IntOnlyPartitioner extends Partitioner<IntLongPair, Writable> {
@Override
public int getPartition(IntLongPair key, Writable value,
int numPartitions) {
return Math.abs(key.getInt().hashCode() & Integer.MAX_VALUE) % numPartitions;
}
}
}
关于java - Hadoop Map Reduce - 如何将分组与排序分开?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37933152/
我像那样遍历数组。 NSArray *array = [[currentRaum raumattribute] allObjects]; NSString *compositeString =
我想找到所有引用这种模式的子字符串:一些字符+一些字符+第一个字符。现在我在 Python 2.7 中有了这个: T = "i was here" m = re.findall(r"([a-z])[a
我想使用与 tidyr 分开将一列字符串(例如 [1, 58, 10] )分成几列。我的问题是有时列较短(永远不会更长)。我在同一个数据框中有很多列有这个问题。 加载包 require(tidyr)
我正在开发一个具有图形用户界面的网络测试工具。我现在面临的问题是,我无法将基础数据与 GUI 类分开。该应用程序由一个 QMainWindow 组成,它随后生成多个其他 QDialogs 并具有一些
我经常听到“策略与机制分离”的口头禅,尤其是在 Unix 哲学的背景下。这是什么意思,有哪些具体的例子?什么时候/为什么是/不是一件好事? 最佳答案 它基本上是将需求或业务功能与技术实现分离。机制是技
我正在使用 writeToFile:atomically: 方法将一些加密数据写入文本文件。问题是,需要保存的文件必须是用户加密的文件,并带有我选择的扩展名。这是我到目前为止所拥有的: [encryp
我有这串 abcdef x y z 或这个 "ab cd ef" x y z 我正试图将其解析为 s1 = "abcdef" arr = ["x","y","z"] 或者 s1 = "ab cd e
这个问题已经有答案了: One big javascript file or multiple smaller files? [duplicate] (7 个回答) 已关闭 6 年前。 我有 4 种类
我有这样的事情 - function DetailCtrl($scope) { $scope.persons = [{ id: 1, name: "Mark"
在操作(复制/移动)包含合并单元格的范围时,我总是收到错误消息“您的粘贴与合并单元格重叠。请取消合并单元格,然后重试”。但是,当尝试使用 Range#breakApart 取消合并范围内的单元格时,我
我有一个包含一些 TextFields 的 TableView。所述 TextFields 的值链接到二维数组(NSMutableArrays 的 NSArray)中的某些位置。 一个初始的干净数组定
我定义了一个标签,其中一半需要在左侧,另一半文本需要在右侧。我怎样才能解决这个问题,让另一半拉对? 我添加了 margin-right 以使文本向右拉,但它与其他 div 不一致。
我正在尝试创建一个正则表达式来将 JavaScript 中的每个单词与 .(点)分开。 function myFunction() { var url = "in.k1.k2.k3.k4.com"
如何使用 CSS 将网站的正文/内容区域与背景分开。为了向您展示我的意思,请看附图。因此,两侧的背景将扩展到拥有超大显示器的人,但内容将始终保持相同大小。 谢谢,阿马尔 http://i.imgur.
有可能用 CSS 将两个背景图像对 Angular 分开吗? 我知道如何只用一张图片制作它,但我不能用两张图片制作它。 这是一个例子: |-------------| | /|
这是一个JSFiddle我创建了展示代码的外观。我将如何给予这些 它们之间是否存在间隙,没有一个元素低于另一个元素? .main-content { width: 50%; float: le
我正在处理具有这样数据的项目(我使用带有 python 的 pandas 框架): days rain 0 1 2 0 3 1 1
我正在尝试编写一个宏来获取信息并将该信息发送到另一个函数,方法是将原始 va_list 拆分为字符串,然后从原始 va_list 生成另一个 va_list。 下面是我的代码。 调用宏 /* Usag
我需要来自 SharedToDomains 和 SharedFromDomains 的键和值数据。我想打印这些值。 var LogResponse = DeserializeFromJson(sLog
我现在正在使用 Alamofire 来发出发布请求。我首先在 ViewController 中构建它并开始工作。但后来我试图通过在另一个 class 中构建它来分离它。我使用 singleton 并且
我是一名优秀的程序员,十分优秀!