Avro-serialization
AVRO-シリアル化
データは2つの目的のためにシリアル化されています-
- 永続ストレージ用
- ネットワーク経由でデータを転送するには
シリアル化とは何ですか?
シリアル化は、データ構造またはオブジェクトの状態をバイナリ形式またはテキスト形式に変換して、ネットワークを介してデータを転送したり、永続ストレージに保存したりするプロセスです。 データがネットワーク経由で転送されるか、永続ストレージから取得されると、データを再度シリアル化解除する必要があります。 直列化は marshalling と呼ばれ、逆直列化は unmarshalling と呼ばれます。
Javaでのシリアル化
Javaは object serialization と呼ばれるメカニズムを提供します。オブジェクトは、オブジェクトのデータと、オブジェクトのタイプおよびオブジェクトに格納されているデータのタイプに関する情報を含むバイトシーケンスとして表すことができます。
シリアル化されたオブジェクトは、ファイルに書き込まれた後、ファイルから読み取り、逆シリアル化できます。 つまり、オブジェクトとそのデータを表す型情報とバイトを使用して、メモリ内でオブジェクトを再作成できます。
*ObjectInputStream* および *ObjectOutputStream* クラスは、それぞれJavaでオブジェクトをシリアライズおよびデシリアライズするために使用されます。
Hadoopでのシリアル化
一般的に、Hadoopのような分散システムでは、シリアル化の概念は*プロセス間通信*および*永続ストレージ*に使用されます。
プロセス間通信
- ネットワークに接続されたノード間のプロセス間通信を確立するために、RPC手法が使用されました。
- RPCは内部シリアル化を使用して、ネットワーク経由でリモートノードに送信する前にメッセージをバイナリ形式に変換しました。 一方、リモートシステムはバイナリストリームを元のメッセージに逆シリアル化します。
- RPCのシリアル化形式は次のようにする必要があります-
- コンパクト-データセンターで最も少ないリソースであるネットワーク帯域幅を最大限に活用します。
- 高速-ノード間の通信は分散システムで非常に重要であるため、シリアル化と逆シリアル化のプロセスは高速で、オーバーヘッドが少なくなります。
- 拡張可能-新しい要件を満たすためにプロトコルは時間とともに変化するため、クライアントとサーバーに対して制御された方法でプロトコルを進化させることは簡単です。
- 相互運用可能-メッセージ形式は、異なる言語で記述されたノードをサポートする必要があります。
永続的ストレージ
永続ストレージは、電源が失われてもデータを失わないデジタルストレージ施設です。 ファイル、フォルダー、データベースは永続ストレージの例です。
書き込み可能なインターフェース
これは、シリアル化および逆シリアル化のメソッドを提供するHadoopのインターフェイスです。 次の表はメソッドを説明しています-
S.No. | Methods and Description |
---|---|
1 |
void readFields(DataInput in) このメソッドは、指定されたオブジェクトのフィールドを逆シリアル化するために使用されます。 |
2 |
void write(DataOutput out) このメソッドは、指定されたオブジェクトのフィールドをシリアル化するために使用されます。 |
書き込み可能な比較可能なインターフェース
*Writable* および *Comparable* インターフェースの組み合わせです。 このインターフェースは、Hadoopの *Writable* インターフェースとJavaの *Comparable* インターフェースを継承します。 したがって、データのシリアル化、逆シリアル化、および比較のためのメソッドを提供します。
S.No. | Methods and Description |
---|---|
1 |
int compareTo(class obj) このメソッドは、現在のオブジェクトを指定されたオブジェクトobjと比較します。 |
これらのクラスに加えて、HadoopはWritableComparableインターフェースを実装する多くのラッパークラスをサポートしています。 各クラスはJavaプリミティブ型をラップします。 Hadoopのシリアル化のクラス階層は以下のとおりです-
Hadoop Serialization Hierarchy
これらのクラスは、Hadoopでさまざまなタイプのデータをシリアル化するのに役立ちます。 たとえば、 IntWritable クラスを考えてみましょう。 このクラスを使用して、Hadoopのデータをシリアライズおよびデシリアライズする方法を見てみましょう。
IntWritableクラス
このクラスは、 Writable、Comparable 、および WritableComparable インターフェイスを実装します。 整数データ型をラップします。 このクラスは、整数型のデータをシリアライズおよびデシリアライズするために使用されるメソッドを提供します。
コンストラクタ
S.No. | Summary |
---|---|
1 | IntWritable() |
2 | IntWritable( int value) |
方法
S.No. | Summary |
---|---|
1 |
int get() このメソッドを使用すると、現在のオブジェクトに存在する整数値を取得できます。 |
2 |
void readFields(DataInput in) このメソッドは、指定された DataInput オブジェクトのデータを逆シリアル化するために使用されます。 |
3 |
void set(int value) このメソッドは、現在の IntWritable オブジェクトの値を設定するために使用されます。 |
4 |
void write(DataOutput out) このメソッドは、現在のオブジェクトのデータを指定された DataOutput オブジェクトにシリアル化するために使用されます。 |
Hadoopでのデータのシリアル化
整数型のデータをシリアル化する手順を以下に説明します。
- 整数値をラップすることにより、 IntWritable クラスをインスタンス化します。
- ByteArrayOutputStream クラスをインスタンス化します。
- DataOutputStream クラスをインスタンス化し、 ByteArrayOutputStream クラスのオブジェクトをそれに渡します。
- * write()*メソッドを使用して、IntWritableオブジェクトの整数値をシリアル化します。 このメソッドには、DataOutputStreamクラスのオブジェクトが必要です。
- シリアル化されたデータは、インスタンス化時に DataOutputStream クラスにパラメーターとして渡されるバイト配列オブジェクトに保存されます。 オブジェクト内のデータをバイト配列に変換します。
例
次の例は、Hadoopで整数型のデータをシリアル化する方法を示しています-
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
public class Serialization {
public byte[] serialize() throws IOException{
//Instantiating the IntWritable object
IntWritable intwritable = new IntWritable(12);
//Instantiating ByteArrayOutputStream object
ByteArrayOutputStream byteoutputStream = new ByteArrayOutputStream();
//Instantiating DataOutputStream object
DataOutputStream dataOutputStream = new
DataOutputStream(byteoutputStream);
//Serializing the data
intwritable.write(dataOutputStream);
//storing the serialized object in bytearray
byte[] byteArray = byteoutputStream.toByteArray();
//Closing the OutputStream
dataOutputStream.close();
return(byteArray);
}
public static void main(String args[]) throws IOException{
Serialization serialization= new Serialization();
serialization.serialize();
System.out.println();
}
}
Hadoopでのデータの逆シリアル化
データの整数型をデシリアライズする手順については、以下で説明します-
- 整数値をラップすることにより、 IntWritable クラスをインスタンス化します。
- ByteArrayOutputStream クラスをインスタンス化します。
- DataOutputStream クラスをインスタンス化し、 ByteArrayOutputStream クラスのオブジェクトをそれに渡します。
- IntWritableクラスの* readFields()メソッドを使用して、 *DataInputStream のオブジェクトのデータを逆シリアル化します。
- デシリアライズされたデータは、IntWritableクラスのオブジェクトに保存されます。 このデータを取得するには、このクラスの* get()*メソッドを使用します。
例
次の例は、Hadoopで整数型のデータをデシリアライズする方法を示しています-
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import org.apache.hadoop.io.IntWritable;
public class Deserialization {
public void deserialize(byte[]byteArray) throws Exception{
//Instantiating the IntWritable class
IntWritable intwritable =new IntWritable();
//Instantiating ByteArrayInputStream object
ByteArrayInputStream InputStream = new ByteArrayInputStream(byteArray);
//Instantiating DataInputStream object
DataInputStream datainputstream=new DataInputStream(InputStream);
//deserializing the data in DataInputStream
intwritable.readFields(datainputstream);
//printing the serialized data
System.out.println((intwritable).get());
}
public static void main(String args[]) throws Exception {
Deserialization dese = new Deserialization();
dese.deserialize(new Serialization().serialize());
}
}
Javaシリアル化に対するHadoopの利点
HadoopのWritableベースのシリアル化は、Writableオブジェクトを再利用することでオブジェクト作成のオーバーヘッドを削減できますが、これはJavaのネイティブシリアル化フレームワークでは不可能です。
Hadoopシリアル化の欠点
Hadoopデータをシリアル化するには、2つの方法があります-
- Hadoopのネイティブライブラリが提供する Writable クラスを使用できます。
- データをバイナリ形式で保存する Sequence Files を使用することもできます。
これら2つのメカニズムの主な欠点は、 Writables および SequenceFiles にはJava APIしかなく、他の言語での書き込みまたは読み取りができないことです。
したがって、上記の2つのメカニズムを使用してHadoopで作成されたファイルは、他の第3言語で読み取ることができません。これにより、Hadoopは制限付きボックスになります。 この欠点に対処するために、Doug Cuttingは Avro を作成しました。これは*言語に依存しないデータ構造*です。