Respuesta de Linus Torvalds a un committer del Kernel Linux

Ja,ja! A esto si que se le puede llamar escarnio público 😀

Leer más

Accediendo a HDFS desde Java

Hadoop ofrece el comando hadoop fs para operar sobre el Filesystem HDFS.

En otros casos podemos necesitar acceder a HDFS desde nuestros programas Java.

Por suerte existe un API sencilla para esto.

1) Creamos un proyecto con estas dependencias (para Hadoop 1.1.1)

2) Para inicializar el FS:

3) Para crear Directorio:

4) Creamos fichero HDFS y escribimos en él:

5) Leemos de fichero:

6) Copiamos fichero a nuestro FS local:

7) Borramos directorio:

Ahí va el listado completo por si os es de utilidad alguna vez J

import static org.junit.Assert.fail;

import java.io.IOException;

import java.util.UUID;

import junit.framework.Assert;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.fs.FSDataInputStream;

import org.apache.hadoop.fs.FSDataOutputStream;

import org.apache.hadoop.fs.FileSystem;

import org.apache.hadoop.fs.Path;

import org.junit.Before;

import org.junit.Test;

public class TestOperacionesHDFS {

private FileSystem dfs = null;

@Before

public void init() {

Configuration config = new Configuration();

config.set("fs.default.name", "hdfs://127.0.0.1:9100/");

try {

dfs = FileSystem.get(config);

} catch (IOException e) {

fail(e.getMessage());

}

}

@Test

public void listOptios() {

try {

System.out.println("Working Directory:"

+ dfs.getWorkingDirectory().getName());

System.out.println("Default Block Size:"

+ dfs.getDefaultBlockSize());

System.out.println("Default Replicatione:"

+ dfs.getDefaultReplication());

System.out.println("Name:" + dfs.getName());

Assert.assertTrue("Working Directory="

+ dfs.getWorkingDirectory().getName(), true);

} catch (Exception e) {

fail(e.getMessage());

}

}

@Test

public void crearDirectorio() {

String dirName = "TestDirectory";

Path src = new Path(dfs.getWorkingDirectory() + "/" + dirName);

try {

dfs.mkdirs(src);

Assert.assertTrue("Creado directorio", true);

} catch (IOException e) {

fail(e.getMessage());

}

}

@Test

public void crearFicheroYEscribir() {

String dirName = "TestDirectory";

Path src = new Path(dfs.getWorkingDirectory() + "/" + dirName + "/"

+ "fichero1.txt");

try {

dfs.createNewFile(src);

FSDataOutputStream fs = dfs.create(src);

fs.write("Primera Linea".getBytes());

for (int i = 0; i < 1000; i++) {

fs.write(UUID.randomUUID().toString().getBytes());

}

fs.write("Ultima Linea".getBytes());

fs.close();

Assert.assertTrue("Creado Fichero " + src.getName(), true);

} catch (IOException e) {

fail(e.getMessage());

}

}

@Test

public void leerDeFichero() {

String dirName = "TestDirectory";

Path src = new Path(dfs.getWorkingDirectory() + "/" + dirName + "/"

+ "fichero1.txt");

try {

FSDataInputStream fs = dfs.open(src);

String str = null;

while ((str = fs.readUTF()) != null) {

System.out.println(str);

}

Assert.assertTrue("Leído Fichero " + src.getName(), true);

} catch (IOException e) {

fail(e.getMessage());

}

}

@Test

public void copiadoFicheroALocal() {

String dirName = "TestDirectory";

Path src = new Path(dfs.getWorkingDirectory() + "/" + dirName + "/"

+ "fichero1.txt");

try {

Path dst = new Path("c://temp/");

dfs.copyToLocalFile(src, dst);

Assert.assertTrue("Copiado Fichero " + src.getName() + " a local",

true);

} catch (IOException e) {

fail(e.getMessage());

}

}

@Test

public void borrarDirectorio() {

String dirName = "TestDirectory";

Path src = new Path(dfs.getWorkingDirectory() + "/" + dirName);

try {

dfs.delete(src, true);

Assert.assertTrue("Borrado directorio", true);

Assert.assertFalse("Borrado directorio", dfs.exists(src));

} catch (IOException e) {

fail(e.getMessage());

}

}

}

Una de mitos: variables fuera y dentro de bucles

Echad un vistazo a este código:

En un método las variables que se usan en el bucle se definen dentro del bucle y en otro fuera.

Pues bien, ¿Cuál de los 2 métodos diríais que tardaría menos en ejecutarse?

Si me hubierais preguntado hubiera dicho que el método testOutsideLoop….

Respuesta

(os adelanto que los tiempos son exactamente los mismos :D)

NOTA: Gracias a Jose Ignacio he detectado que por algún extraño motivo si defino las variables así se compila al mismo código, pero si las defino así:

int runs = 200 * 1000;
int x=0;
int y=0;
int times=0;

el compilado es diferente y también los tiempos 🙂

(Ver comentarios)

JSON Viewer: Visualizando nuestros JSONs en árbol

Ya hemos visto como JSON permite representar una estructura XML de una forma más compacta (podéis ver varios ejemplos aquí)

Por ejemplo este XML:

En JSON:

Por el contrario muchas veces en JSON es más complejo ver la estructura de nuestros datos.

JSON Viewer es una pequeña utilidad web que permite representar/ver cualquier estructura JSON de una forma más “visual”.

Para nuestro JSON:

Para este JSON:

Queda:

Un poco de Hive

Las aplicaciones MapReduce se escriben en Java, lo que requiere un buen programador Java capaz de pensar en términos MapReduce, con el suficiente tiempo para escribir y testar el código!!!

Sin duda ahí está el motivo por el que existe Hive o Pig :D.

Muchas organizaciones tienen sólo unos pocos desarrolladores que puedan escribir código MapReduce.

Hive es una abstracción de alto nivel sobre MapReduce que permite consultar los datos en el cluster Hadoop sin necesidad de codificar código MapReduce.

Hive fue desarrollado originalmente en Facebook, aunque ahora es un proyecto top level de Apache, ofrece un lenguaje muy similar a SQL (HiveSQL), que puede ser utilizado por personas que conocen SQL.

Una consulta tiene este aspecto:

Las Tablas Hive corren sobre HDFS y la forman 3 conceptos:

– Tablas: soportan columnas tipadas (int, float, string, boolean,…) y también arrays, mapas (datos JSON)

Particiones: permiten por ejemplo agrupar tablas por rangos temporales

Buckets: particiones Hash en rangos, muy usadas para muestreo)

Hive tiene un metastore que es una base de datos con definiciones de tabla y otros metadatos, por defecto se almacena en local en una BD Derby.

Las tablas Hive se almacenan en el directorio warehouse en HDFS (por defecto (/users/hive/warehouse). Las tablas se almacenan en subdirectorios en este directorio. Los datos se almacenan en ficheros planos.

Desde Hive pueden:

Crearse Tablas:

hive> SHOW TABLES;

hive> CREATE TABLE shakespeare

(freq INT, word STRING)

ROW FORMAT DELIMITED

FIELDS TERMINATED BY ‘t’

STORED AS TEXTFILE;

hive> DESCRIBE shakespeare;

Cargar datos en Hive:

hive>LOAD DATA INPATH "shakespeare_freq" INTO TABLE shakespeare;

Lanzar Queries:

hive>SELECT * FROM shakespeare

WHERE freq > 100 ORDER BY freq ASC

LIMIT 10;

Hacer JOINS:

hive>SELECT s.word, s.freq, k.freq FROM

shakespeare s JOIN kjv k ON

(s.word = k.word)

WHERE s.freq >= 5;

Almacenar datos de una Query en una tabla:

Hive> INSERT OVERWRITE TABLE newTable

SELECT s.word, s.freq, k.freq FROM

shakespeare s JOIN kjv k ON

(s.word = k.word)

WHERE s.freq >= 5;

Compensaciones en Activiti

Como ya comentamos en su momento Activiti es una plataforma BPM muy ligera y rápida.

Actualmente va por la versión 5.11 (que salió a la luz el 5 de diciembre de 2012), desde su versión 5.9 Activiti da soporte a las compensaciones (deshacer los efectos de una acción).

Las compensaciones son un concepto de BPMN 2, que ya pueden implementarse en Activiti:

En un flujo completo sería algo como esto:

Leer más: http://www.bpm-guide.de/2012/03/02/activiti-5-9-introduces-bpmn-compensation-and-transactions/