2012-09-14 24 views
10

Supongamos que tengo un archivo delimitado por tabuladores que contiene los datos de actividad del usuario formateados como esto:Hadoop - compuesto clave

timestamp user_id page_id action_id 

Quiero escribir un trabajo Hadoop para contar las acciones del usuario en cada página, por lo que el archivo de salida debería ser como este:

user_id page_id number_of_actions 

Necesito algo así como la clave compuesta aquí - contendría user_id y page_id. ¿Hay alguna manera genérica de hacer esto con hadoop? No pude encontrar nada útil. Hasta ahora estoy emisores clave como este en mapeador:

context.write(new Text(user_id + "\t" + page_id), one); 

Funciona, pero siento que no es la mejor solución.

Respuesta

13

Sólo componer su propio Writable. En el ejemplo, una solución podría tener este aspecto:

public class UserPageWritable implements WritableComparable<UserPageWritable> { 

    private String userId; 
    private String pageId; 

    @Override 
    public void readFields(DataInput in) throws IOException { 
    userId = in.readUTF(); 
    pageId = in.readUTF(); 
    } 

    @Override 
    public void write(DataOutput out) throws IOException { 
    out.writeUTF(userId); 
    out.writeUTF(pageId); 
    } 

    @Override 
    public int compareTo(UserPageWritable o) { 
    return ComparisonChain.start().compare(userId, o.userId) 
     .compare(pageId, o.pageId).result(); 
    } 

} 

Aunque creo que sus identificaciones podrían ser un long, aquí tiene la versión String. Básicamente solo la serialización normal sobre la interfaz Writable, tenga en cuenta que necesita el constructor predeterminado, por lo que siempre debe proporcionar uno.

La lógica compareTo dice obviamente cómo ordenar el conjunto de datos y también le dice al reductor qué elementos son iguales para que puedan agruparse.

ComparisionChain es una buena utilidad de Guava.

¡No olvide anular equals y hashcode! El particionador determinará el reductor mediante el código hash de la clave.

+0

ComparisonChain realmente hace que sea fácil para este caso de uso. Gracias –

1

Podrías escribir tu propia clase que implementa Writable y WritableComparable que compararía tus dos campos.

Pierre-Luc Bertrand

Cuestiones relacionadas