воскресенье, 17 марта 2013 г.


Пост 19. Сериализатор AVRO и Oracle NoSQL Database. Практика

Доброго времени суток!

Как и обещал сейчас мы рассмотрим конкретный пример AVRO сериализации в базе данных Oracle.

Итак:
1)Рассмотрим объект: человек. У него есть атрибуты имя и возраст.
Пример файла схемы данных (допустим он лежит в /home/oracle/nosql/avro/member-schemas_new.avsc)
{
    "type": "record",
    "name": "userProfile",
    "namespace": "my.example",
    "fields": [
        {"name": "name", "type": "string", "default" : ""},
        {"name": "age", "type": "int", "default": -1}
            ]
}

2)Добавьте файл схемы данных в базу данных Oracle NoSQL Database

java -jar /home/cloudera/nosql/kv-2.0.23/lib/kvstore-2.0.23.jar runadmin -port 5000 -host localhost ddl add-schema -file /home/oracle/nosql/avro/member-schemas_new.avsc
3) Напишем код, который работает со схемой данных. 

import Support.OraStore;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import javax.sound.sampled.Port;
import oracle.kv.*;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.Schema;

import oracle.kv.avro.AvroCatalog;
import oracle.kv.avro.GenericAvroBinding;

public class a_AvroGenericBind {

    static String port = "5000";
    static String host = "localhost";
    static String store = "kvstore";
    private static Schema personSchema;
    private static GenericRecord member;
    private static String SchemaFile = "/home/oracle/nosql/avro/member-schemas_new.avsc";
    private static String SchemaName = "my.example.userProfile";
    private static KVStore myStore;
    static String UserName = "Alexey";

    public static void main(String[] args) throws IOException {
        RunExample();
    }

    public static void RunExample() throws IOException {
        OraStore orastore = new OraStore(store, host, port);
        KVStore myStore = orastore.getStore();

        final Schema.Parser parser = new Schema.Parser();
        parser.parse(new File(SchemaFile));
        personSchema = parser.getTypes().get(SchemaName);
        final AvroCatalog catalog = myStore.getAvroCatalog();
        final GenericAvroBinding binding = catalog.getGenericBinding(personSchema);
        final Key key = Key.createKey(Arrays.asList("userProfile", UserName));
        final ValueVersion valueVersion = myStore.get(key);
        final int age;
        if (valueVersion != null) {
            member = binding.toObject(valueVersion.getValue());
            System.out.println("INITIAL VALUE:\n" + member.toString());
            final int oldAge = (Integer) member.get("age");
            age = oldAge + 1;
            member.put("age", age);
            myStore.put(key, binding.toValue(member));
        } else {
            System.out.println("NO INITIAL VALUE");
            member = new GenericData.Record(personSchema);
            System.out.println(personSchema.toString());
            member.put("name", UserName);
            member.put("age", 24);
        }
        System.out.println("NEW VALUE");
        myStore.put(key, binding.toValue(member));
        System.out.println(member.toString());
        myStore.close();
    }
}

Если есть запись - идет апдейт части value, если нет - создается новая пара. Как то так.
Если кто то хочет получить виртуалку с примерами, в том числе и этим - пишите на oracle.nosql@gmail.com
Пост 18. Сериализатор AVRO и Oracle NoSQL Database. Теория.

Доброго времени суток!
Как было сказно ранее Oracle NoSQL Database начиная со второй версии позволяет сериализовать value протоколом AVRO. Давайте попробуем это сделать!

Для того что бы использовать AVRO сериализацию в Oracle NoSQL Database необходимо:

1)Добавить схему в хранилище.
2)Идентифицировать ее в приложении
3)Сериализовать/десериализовать values (сериализуются только значения, ключи не сереализуются!). Для выполнения данной функции используются Avro bindings

Код AVRO сериализаторов применяется только при работе с Value. На остальное приложение влияния не оказывается!
Bind могут быть разного типа. Рассмотрим generic (общий).

Работа с сериализатором в коде приложения (с помощью GenericBind)

1) Создать объект парсер и прочитать им файл схемы данных.
final Schema.Parser parser = new Schema.Parser();
parser.parse(new File(SchemaFile));

2) Создать объект типа “схема данных”, прочитать тип данных в схеме:
Schema personSchema = parser.getTypes().get(SchemaName);

3) Создать объект типа AVRO каталог
final AvroCatalog catalog = myStore.getAvroCatalog();

4) На основе этого каталога и полученных ранее типов данных схемы получаем переменные для связки value и AVRO
final GenericAvroBinding binding = catalog.getGenericBinding(personSchema);

5) Создаем запись для работы с bind. Читаем в нее объект.
GenericRecord member = binding.toObject(valueVersion.getValue());

6) Изменения производятся с помощью метода:
member.put("age", age);

7) Чтение атрибута объекта производится следующим образом:
member.get("age").toString()

В следующем посте мы рассмотрим конкретный пример - думаю все будет намного понятнее!

суббота, 16 марта 2013 г.

Пост 17. Сериализатор AVRO.

Доброго времени суток!

Сейчас я хочу рассказать Вам об AVRO сериализации.
Для начала предлагаю договориться о том, что такое сериализация. Вот выдержка из википедии:

Сериализация (в программировании) — процесс перевода какой-либо структуры данных в последовательность битов. Обратной к операции сериализации является операция десериализации(структуризации) — восстановление начального состояния структуры данных из битовой последовательности.

Сериализация это процесс перевода структуры с поток битов. Где же может применяться сериализация/десериализация в NoSQL базах? Если Вы предположили, что при хранении value - вы совершенно правы! Иногда хочется положить в value какую то запись, которая хранила бы в себе более "осознанный" набор байт. Ну например, личная инормация человека. Можно хранить в виде XML или JSON и разбирать их на уровне приложения, тогда мы будем иметь что то вроде: {name:Ivan, surname: Petrov, age:33}... А если записей будет много? Тогда я буду хранить большое колличетво "лишней" информации:

/key1/ : {name: Ivan, surname: Petrov, age:33}
/key2/ : {name:Vasiliy, surname: Smirnov, age:32}
/key3/ : {name: Sergey, surname: Sidorov, age:40}
/key4/ : {name: Alexey, surname: Kuznethov, age:25}

Здорово было бы описать один раз какую то схему, а внутри хранить только указатели или разделители! Ну например вот так:

/key1/ : Ivan, : Petrov, :33
/key2/ : Vasiliy, Smirnov, 32
/key3/ : Sergey, Sidorov, 40
/key4/ : Alexey, Kuznethov,25

Так вот нечто подобное делает AVRO - это очень компактный протокол сериализации. На самом деле есть еще ряд причин использовать AVRO:

1) Возможность изменять схему. Ну тут как говорится ни отнять ни прибавить. Вы можете эволюционировать уже созданную схему данных
2) Быстрая десериализация (доступ к отдельным полям в данных) и компактное хранение (не хранятся теги - что значительно сокращает занимаемое пространство). Это как раз таки в копилку компактности
3) Динамическая типизация.

Итак, небольшой блок теории закончился, давайте посмотрим как это будет на практике в Oracle NoSQL Database!

+ напоминание - кто хочет получить виртуалку c примерами: пишите на oracle.nosql@gmail.com