Introducció
La serialització és el procés de convertir un objecte en una seqüència de bytes per emmagatzemar-lo o transmetre'l a través d'una xarxa. En el context de Hadoop, la serialització és crucial per a l'emmagatzematge i la transmissió eficient de dades entre nodes del clúster. Aquest mòdul cobreix els conceptes bàsics de la serialització de dades en Hadoop, les seves eines i biblioteques, i com optimitzar el procés per a un rendiment millor.
Conceptes clau
- Serialització: Conversió d'objectes en una seqüència de bytes.
- Deserialització: Conversió de la seqüència de bytes en objectes.
- Eficàcia: La serialització ha de ser ràpida i generar una sortida compacta.
- Compatibilitat: La serialització ha de ser compatible amb versions anteriors i futures.
Eines i biblioteques de serialització en Hadoop
Writable Interface
Hadoop utilitza la interfície Writable per a la serialització de dades. Aquesta interfície defineix dos mètodes:
write(DataOutput out): Escriu l'objecte en un flux de sortida.readFields(DataInput in): Llegeix els camps de l'objecte des d'un flux d'entrada.
Exemple de codi
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.Writable;
public class CustomWritable implements Writable {
private int id;
private String name;
// Constructor per defecte
public CustomWritable() {}
// Constructor amb paràmetres
public CustomWritable(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public void write(DataOutput out) throws IOException {
out.writeInt(id);
out.writeUTF(name);
}
@Override
public void readFields(DataInput in) throws IOException {
id = in.readInt();
name = in.readUTF();
}
@Override
public String toString() {
return id + "\t" + name;
}
}Avro
Apache Avro és un sistema de serialització de dades que proporciona un format de dades compacte, ràpid i compatible amb versions anteriors. Avro utilitza esquemes per definir l'estructura de les dades.
Exemple de codi
- Definició de l'esquema Avro (schema.avsc)
{
"type": "record",
"name": "User",
"fields": [
{"name": "id", "type": "int"},
{"name": "name", "type": "string"}
]
}- Serialització i deserialització amb Avro
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.io.DatumReader;
import org.apache.avro.io.DatumWriter;
import org.apache.avro.io.Decoder;
import org.apache.avro.io.DecoderFactory;
import org.apache.avro.io.Encoder;
import org.apache.avro.io.EncoderFactory;
import org.apache.avro.specific.SpecificDatumReader;
import org.apache.avro.specific.SpecificDatumWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class AvroExample {
public static void main(String[] args) throws IOException {
// Carregar l'esquema
Schema schema = new Schema.Parser().parse(new File("schema.avsc"));
// Crear un registre genèric
GenericRecord user = new GenericData.Record(schema);
user.put("id", 1);
user.put("name", "John Doe");
// Serialitzar el registre
ByteArrayOutputStream out = new ByteArrayOutputStream();
DatumWriter<GenericRecord> writer = new SpecificDatumWriter<>(schema);
Encoder encoder = EncoderFactory.get().binaryEncoder(out, null);
writer.write(user, encoder);
encoder.flush();
out.close();
// Deserialitzar el registre
DatumReader<GenericRecord> reader = new SpecificDatumReader<>(schema);
Decoder decoder = DecoderFactory.get().binaryDecoder(out.toByteArray(), null);
GenericRecord result = reader.read(null, decoder);
System.out.println(result);
}
}Protocol Buffers
Protocol Buffers (protobuf) és una altra eina de serialització desenvolupada per Google. És similar a Avro però utilitza un llenguatge de definició d'interfícies (IDL) per definir l'esquema.
Exemple de codi
- Definició de l'esquema protobuf (user.proto)
- Serialització i deserialització amb Protocol Buffers
import com.example.UserProtos.User;
public class ProtobufExample {
public static void main(String[] args) throws IOException {
// Crear un objecte User
User user = User.newBuilder()
.setId(1)
.setName("John Doe")
.build();
// Serialitzar l'objecte
byte[] serializedData = user.toByteArray();
// Deserialitzar l'objecte
User deserializedUser = User.parseFrom(serializedData);
System.out.println(deserializedUser);
}
}Comparació de biblioteques de serialització
| Característica | Writable | Avro | Protocol Buffers |
|---|---|---|---|
| Esquema | No | Sí | Sí |
| Compatibilitat | Manual | Automàtica | Automàtica |
| Velocitat | Alta | Mitjana | Alta |
| Facilitat d'ús | Baixa | Alta | Alta |
| Suport de llenguatges | Java | Multi-llenguatge | Multi-llenguatge |
Exercicis pràctics
Exercici 1: Crear una classe Writable
- Crea una classe
EmployeeWritableque implementi la interfícieWritable. - Defineix els camps
id(int) iname(String). - Implementa els mètodes
writeireadFields.
Solució
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.Writable;
public class EmployeeWritable implements Writable {
private int id;
private String name;
public EmployeeWritable() {}
public EmployeeWritable(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public void write(DataOutput out) throws IOException {
out.writeInt(id);
out.writeUTF(name);
}
@Override
public void readFields(DataInput in) throws IOException {
id = in.readInt();
name = in.readUTF();
}
@Override
public String toString() {
return id + "\t" + name;
}
}Exercici 2: Serialitzar i deserialitzar amb Avro
- Defineix un esquema Avro per a un objecte
Productamb els campsid(int) iname(String). - Escriu un programa Java per serialitzar i deserialitzar un objecte
Productutilitzant Avro.
Solució
- Definició de l'esquema Avro (product.avsc)
{
"type": "record",
"name": "Product",
"fields": [
{"name": "id", "type": "int"},
{"name": "name", "type": "string"}
]
}- Serialització i deserialització amb Avro
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.io.DatumReader;
import org.apache.avro.io.DatumWriter;
import org.apache.avro.io.Decoder;
import org.apache.avro.io.DecoderFactory;
import org.apache.avro.io.Encoder;
import org.apache.avro.io.EncoderFactory;
import org.apache.avro.specific.SpecificDatumReader;
import org.apache.avro.specific.SpecificDatumWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
public class AvroProductExample {
public static void main(String[] args) throws IOException {
// Carregar l'esquema
Schema schema = new Schema.Parser().parse(new File("product.avsc"));
// Crear un registre genèric
GenericRecord product = new GenericData.Record(schema);
product.put("id", 101);
product.put("name", "Laptop");
// Serialitzar el registre
ByteArrayOutputStream out = new ByteArrayOutputStream();
DatumWriter<GenericRecord> writer = new SpecificDatumWriter<>(schema);
Encoder encoder = EncoderFactory.get().binaryEncoder(out, null);
writer.write(product, encoder);
encoder.flush();
out.close();
// Deserialitzar el registre
DatumReader<GenericRecord> reader = new SpecificDatumReader<>(schema);
Decoder decoder = DecoderFactory.get().binaryDecoder(out.toByteArray(), null);
GenericRecord result = reader.read(null, decoder);
System.out.println(result);
}
}Conclusió
La serialització de dades és un component essencial en Hadoop per a l'emmagatzematge i la transmissió eficient de dades. Hem explorat diverses eines i biblioteques de serialització, com Writable, Avro i Protocol Buffers, i hem vist com utilitzar-les amb exemples pràctics. La comprensió d'aquests conceptes i eines permetrà als desenvolupadors optimitzar el rendiment de les seves aplicacions Hadoop i assegurar la compatibilitat de dades a llarg termini.
Curs de Hadoop
Mòdul 1: Introducció a Hadoop
- Què és Hadoop?
- Visió general de l'ecosistema Hadoop
- Hadoop vs Bases de dades tradicionals
- Configuració de l'entorn Hadoop
Mòdul 2: Arquitectura de Hadoop
- Components bàsics de Hadoop
- HDFS (Sistema de fitxers distribuït de Hadoop)
- Marc MapReduce
- YARN (Yet Another Resource Negotiator)
Mòdul 3: HDFS (Sistema de fitxers distribuït de Hadoop)
Mòdul 4: Programació MapReduce
- Introducció a MapReduce
- Flux de treball d'una feina MapReduce
- Escriure un programa MapReduce
- Tècniques d'optimització de MapReduce
Mòdul 5: Eines de l'ecosistema Hadoop
Mòdul 6: Conceptes avançats de Hadoop
- Seguretat de Hadoop
- Gestió de clústers de Hadoop
- Ajust de rendiment de Hadoop
- Serialització de dades de Hadoop
Mòdul 7: Aplicacions reals i estudis de cas
- Hadoop en emmagatzematge de dades
- Hadoop en aprenentatge automàtic
- Hadoop en processament de dades en temps real
- Estudis de cas d'implementacions de Hadoop
