пятница, 8 февраля 2013 г.


Пост 14. Oracle NoSQL Database v2.

"Давненько не брал я в руки шашек!" - говаривал Ноздрев Чичикову. "Давненько ничего я тут не писал" - скажу я Вам. За время моего "молчания" Oracle NoSQL Database разразился второй версией. Вторая версия принесла много приятных сюрпризов. Но обо всем по порядку.

                           
                                          Рис.1 Новшества Oracle NoSQL Database v2.

Итак, по порядку.
1) Масштабируемость и управляемость.
 - Эластичность
Добавлена возможность добавлять "на лету" новые репликационные группы (шарды).
Теперь из вот такогой топологии можно на лету:


сделать вот такую:

- Перебалансировка данных между шардами
Теперь данные с нагруженых шардов могут быть перенесены на менее нагруженые.
Из вот такого расположения:

можно сделать:

2) Новые API
- Добавлено С API
- Добавлен сериализатор AVRO (сериализация value)
- Добавлена поддержка больших объектов (LOB).

3) Интеграция и мониторинг
- Внешние таблицы. Теперь данные из Oracle NoSQL Database можно читать с помощью внешних таблиц Oracle RDBMS.
- Возможность использования Oracle NoSQL Database как источник для OEP (CEP).
- Поддержка SNMP/JMX
- Интеграция с RFD (опция базы данных Oracle)

Далее я буду подробнее описывать все выше описанное!
Успехов всем!

вторник, 25 сентября 2012 г.

Пост 13. Начинаем работу!

Итак, пора уже наконец начать работу с Oracle NoSQL DB
Для этого надо скачать виртуалку.


Для этого надо скачать виртуалку.
К сожалению, в силу лицензионной политики моей компании я не могу выкладывать виртуальные машины в открытый доступ. Поэтому пишите на e-mail: а oracle.nosql@gmail.com, я вышлю инструкции, где будет сказано о том,как ее получить.


После скачивания, собираем(разбивал total commander), запускаем (VmWare), читаем инструкцию и наслаждаемся NoSQL DB!

1) Работу следует начать с переразвертывания базы. Запускаем скрипт
/opt/oracle/ReDeploy.sh
2) Далее запускает IDE NetBeans (ярлык на рабочем столе)
3) Описание пакетов
- Support
Вспомогательный пакет. Содержит 2 класса.
Support.OraStore.java - класс содержит 1 метод, используется для подключения к базе.
На вход подаем имя хранилища, получаем указательна объект БД.

Support.ParseKey.java - класс содержит 1 метод, осуществляет разбор ключа по заданному шаблону.
На вход подается String - отдается указатель на объект типа Key.
пример входных данных: major1/major2/-/minor1 (заметье, major1/major2/-/minor1 - НЕ ВЕРНО )
- CRUD
Пакет, включающий в себя классы, выполняющие CRUD (Create Retrieve Update Delete) операции.
Create. Этот класс предназначен для создание пар ключ-значение в базе. Содержит 3 метода с одинаковыми конструторами.
- putIfPresent - метод записывает пару ключ-значение,если данные есть, если данныех нет - выкидывает exeption.
- putIfAbsent - метод записывает пару ключ-значение,если данных нет, если данные есть - выкидывает exeption.
- put - записыавет пару ключ-значение в любом случае.
   Конструктор (String sKey, String data, KVStore myStore).
sKey - ключ в формате строки (внутри метода происходит парсинг).
пример: major1/major2/-/minor1.
data - значение. Данный метод поддерживает только value типа String.
myStore - объект базы даных. Указатель на объект дожен быть создан ранее.
Retrieve. Этот класс предназначен для извлечения пар ключ-значение из базы.
- SelectRow - метод для извлечения одной стороки.
Конструктор(String sKey, KVStore myStore), возвращает String.
sKey - ключ в формате строки (внутри метода происходит парсинг).
пример: major1/major2/-/minor1.
myStore - объект базы даных. Указатель на объект дожен быть создан ранее.
- SelectAll - метод для извлечения всей базы данных (вывод на экран).
Конструктор(KVStore myStore).
myStore - объект базы даных. Указатель на объект дожен быть создан ранее.
- SelectWhereFullMajor - метод для извлечения множества строк по ПОЛНОМУ major ключу (вывод на экран)
Конструктор(String sKey, KVStore myStore)
sKey - major составляющая ключа
myStore - объект базы даных. Указатель на объект дожен быть создан ранее.
Пример: есть ключи
major1/major2/-/minor1/
major1/major2/-/minor2/
major1/major2/-/minor3/
Их все надо извлечь.
задать в качестве ключа (sKey) необходимо "major1/major2/"
НЕЛЬЗЯ искать по части: "major1"
- SelectWhere - метод для извлечения множества строк по ЧАСТИ major ключа (вывод на экран)
Конструктор(String sKey, KVStore myStore)
sKey - major составляющая ключа
myStore - объект базы даных. Указатель на объект дожен быть создан ранее.
Пример: есть ключи
major1/major2/-/minor1/
major1/major3/-/minor2/
major1/major4/-/minor3/
Их все надо извлечь.
задать в качестве ключа (sKey) необходимо "major1/"
Но метод не работает с полными major ключами

Update. Класс содержит 1 метод: putIfpresent (описание см. выше в классе Create).

Delete. Класс содержит 2 метода.
- ClearStore. Удаление всех данных из базы.
Конструктор(KVStore myStore).
myStore - объект базы даных. Указатель на объект дожен быть создан ранее.
- DeleteKey. Удаление одной пары из базы.
Конструктор(String sKey, KVStore myStore), возвращает String.
sKey - ключ в формате строки (внутри метода происходит парсинг).
пример: major1/major2/-/minor1.
myStore - объект базы даных. Указатель на объект дожен быть создан ранее.


- SocialNetwork
Пакет непосредственно реализующий приложение (как раз таки использует пакеты CRUD и Support). В данном случае - некая соц. сеть
Auth - класс для администрирования и аутентицикации пользователей
- add_admin метод для добавления пользователей
Конструктор(String AdminName, String AdminAtribute, String Pass, KVStore myStore)
AdminName - имя нового пользователя
AdminAtribute - атрибуты нового пользователя (возраст, пол, образование ... )
Pass - пароль нового пользователя
myStore - указатель на объект базы данных (необходимо создать ранее, методу передается лишь указатель)
- check_passwd - аутентификация пользователя. Возвращает String "Yes" или "No"
Конструктор (String AdminName, String AdminPass, KVStore myStore)
AdminName - имя пользователя (логин)
Pass - пароль пользователя
myStore - указатель на объект базы данных (необходимо создать ранее, методу передается лишь указатель)
MessageManagment - класс для управления потоком собщений соц. сети.
- post данный метод осуществляет пост сообщения на стену
Конструктор (String UserName, String text, KVStore myStore)
UserName - пользователь, оставляющий сообщение
text - текст сообщения
myStore - указатель на объект базы данных (необходимо создать ранее, методу передается лишь указатель)
- subscribe_to подписка на сообщения другого пользователя
Конструктор (String User, String IntrestingPerson, KVStore myStore)
User - тот кто подписывается
IntrestingPerson - тот на кого подписываются
myStore - указатель на объект базы данных (необходимо создать ранее, методу передается лишь указатель)
- show_tape метод, отображающий стену (ТОР N сообщений, пользователя и того на кого он подписан, отсортированных по времени)
Конструктор (String User, int tape_depth, KVStore myStore)
User пользователь, чью стену необходимо отрисовать
tape_depth - колличество сообщений которые надо отображать (ТОР N)
myStore - указатель на объект базы данных (необходимо создать ранее, методу передается лишь указатель)

SocialNetwork - main класс проекта.

Если будут вопросы - не стесняйтесь их задавать!

пятница, 17 августа 2012 г.

Пост 12. ACID. Durability.

Едем дальше. Durability. Что это значит? А значит это то, что независимо от проблем на нижних уровнях (к примеру, обесточивание системы или сбои в оборудовании) изменения, сделанные успешно завершённой транзакцией, должны остаться сохранёнными после возвращения системы в работу. Другими словами если пользователь внес данные в вашу систему и почил подтверждение о том, что они успешно записаны, они не должны быть потеряны, вне зависимости ни отчего (пропало питание в ЦОД, посыпался диск...). Ну представьте вы купили электронный авиабилет, вам пришло подтверждение. Тут же посыплся диск на который вы записали свои данные. Приезжаете в аэропорт в солнцезащитных очках, гавайской рубашке и в предвкушении долгожданного пляжного отдыха, а Вам говорят, что данных в системе нет. Ситуация конечно излишне гиперболизирована, но суть думаю ясна.
В контексте Oracle NoSQL это выглядит вот так:



Рис.1. Durability.

Итак, при проектировании приложения нам приходится выбирать между надежностью и скоростью. У нас есть 2 измерения для выбора "золотой середины". Первое - уровень синхронизации - когда данные могут считаться записанными: когда они попали в ОЗУ (самое быстрое), когда из ОЗУ они перешли в буфферный кэш файловой системы, либо когда они попали на диск (самое надежное). Второе измерение это так называемая обратная связь (сколько серверов подтвердило поступление пары ключ-значение). Самое быстрое - "ни одного", то есть пары попали только на мастера, далее следует режим majority (от многих), ну и самым надежным является тот случай, если получение пары подтвердили все сервера репликационной группы. Использовать это API проще простого.
Устанавливаем настройки надежности:

Durability durability =
new Durability (Durability.SyncPolicy.SYNC, Durability.SyncPolicy.SYNC, Durability.ReplicaAckPolicy.ALL);
myStore.put(myKey, myValue,null,durability,30, TimeUnit.SECONDS);

Вот как то так.
Если у вас есть какие-либо вопросы по Oracle NoSQL - задавайте в комментах, постараюсь ответить, либо пишите на oracle.nosql@gmail.com.

среда, 8 августа 2012 г.


Пост 11. ACID. Consistency.

Следующий пункт ACID концепции в рамках данной серии статей - Consistency, согласованность. Система находится в согласованном состоянии до начала транзакции и должна остаться в согласованном состоянии после завершения транзакции.Представьте, что у Вас есть система, состоящая их 2х и более узлов, которые реплицируют одну и туже информацию (попросту говоря копируют). Представьте себе, что вы записали некоторые данные на сервер1 и получили подтверждение успешной записи. Практически в тот же момент другой пользователь запросил данные, которые вы только что записали и не получил их... потому что балансировщик отправил его на сервер2 (куда данные еще не успели среплицироваться). Требование согласованности не выполнено.
Рис.1 Система находится в согласованном состоянии


Рис.2 Система находится в не согласованном состоянии

 А что же мне делать, если я хочу обеспечить выполнене принципа согласованности? И как сказали бы в рекламе Oracle NoSQL летит к Вам!
В начале хотел бы рассказать о том, что такое согласованность в контексте Oracle NoSQL.
Существует несколько типов согласованности (расположены в порядки убывания скорости):
- Согласованность отсутствует (самое быстрое чтение)
- Согласованность по времени
- Согласованность по версии
- Абсолютная согласованность (самое медленное чтение)

Если вы хотите обеспечить согласованное чтение, используйте другой конструктор получения value (get, MultiGet...)

Давайте создадим программу, которая читает одно значение по ключу (аналогичный метод создавался ранее, но в этот раз использовался другой конструктор get)

public static String ConsistencyRead(String sKey, String store, String host, String port) {
OraStore orastore = new OraStore(store, host, port);
String data = null;
KVStore myStore = orastore.getStore();
System.out.println("Store Opened");
Key myKey = ParseKey.ParseKey(sKey);
try {
ValueVersion vv = myStore.get(myKey, Consistency.ABSOLUTE, 0, null);
Value v = vv.getValue();
data = new String(v.getValue());
System.out.println(myKey + " : " + data);
} catch (RequestTimeoutException re) {
System.out.println(re.getTimeoutMs());
} catch (FaultException fe) {
System.out.println("Unknown error");
} catch (NullPointerException ne) {
System.out.println("Key does not exist");
} finally {
myStore.close();
System.out.println("Store Closed");
}
return data;
}


Если у вас есть какие-либо вопросы по Oracle NoSQL - задавайте в комментах, постараюсь ответить, либо пишите на oracle.nosql@gmail.com

понедельник, 6 августа 2012 г.


Пост 10. ACID. Atomicity.

Итак, сейчас хотел бы рассказать про принцип атомарности. Атомарность гарантирует, что никакая транзакция не будет зафиксирована в системе частично. Будут либо выполнены все её подоперации, либо не выполнено ни одной. Итак, все привыкли думать, что NoSQL базы данных это исключительно BASE системы. "Быстрые, но не надежные". Это не так. Oracle NoSQL может соответствовать ACID концепции. Atomicity в данном контексте это будет просто обозначать транзакции. Долго думал как об этом лучше рассказать - решил добавить еще один класс,с исчерпывающими комментариями, в пакет simpleoperation (о нем читай ниже). Надеюсь все понятно :) Если нет - не стеснятесь задавать вопосы в комментариях или писать по адресу oracle.nosql@gmail.com

package simpleoperation;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;
import oracle.kv.*;

public class ACID {
// Прописываем переменные идентифицирующие базу данных
static String port = "5000";
static String host = "localhost";
static String store = "kvstore";


public static void main(String args[])
// Открываем нашу базу              
OraStore orastore = new OraStore(store,host,port);
KVStore myStore = orastore.getStore();
System.out.println("Store Opened"); 

// Создаем 2 ключа
String Key1 = "key/-/1/";
String Key2 = "key/-/2";
Key myKey1 = ParseKey.ParseKey(Key1);
Key myKey2 = ParseKey.ParseKey(Key2);
// Создаем 2 значения
String data1 = "First value";
String data2 = "Second value";
Value MyValue1 = Value.createValue(data1.getBytes());
Value MyValue2 = Value.createValue(data2.getBytes());
// Создание транзакции начинается с создания объекта OperationFactory.
OperationFactory of = myStore.getOperationFactory();
// Создаем массив под храниение списка наших операций
List<Operation> opList = new ArrayList<>();
// Заполняем его операциями объекта of
opList.add(of.createPutIfAbsent(myKey1, MyValue1));
opList.add(of.createPutIfAbsent(myKey2, MyValue2));
System.out.println("Transaction Created");
try
{
// Запускаем транзакцию
myStore.execute(opList);
System.out.println("Transaction Executed");
}
catch (OperationExecutionException oee)
{
System.out.println("Operation Execution Exception occured " + oee.getMessage());
}
catch (IllegalArgumentException iae)
{
System.out.println("Illegal Argument Exception occured " + iae.getMessage());
}
catch (FaultException fe)
{
System.out.println("Fault Exception occured " + fe.getMessage());
}
}
}

В итоге будут выполнены 2 операции, либо не выполнена ни одна. 
Если у вас есть какие-либо вопросы по Oracle NoSQL - задавайте в комментах, постараюсь ответить, либо пишите на oracle.nosql@gmail.com

четверг, 19 июля 2012 г.

Пост 9. ACID.

Доброго времени суток!
Итак продолжаю свое повествование об Oracle NoSQL Database. Сегодня хотел бы рассказать о таких понятиях, как ACID и BASE. Итак, начнем с ACID, я уверен, что большинство знает, что это такое, но все же хотел бы повториться.


Atomicity — Атомарность
Атомарность гарантирует, что никакая транзакция не будет зафиксирована в системе частично. Будут либо выполнены все её подоперации, либо не выполнено ни одной. 

Представьте себе простейшую банковскую операцию в которой деньги с одного счета преводятся на другой. Это мининум 2 операции БД - снять деньги с одного счета и пополнить другой. Не камильфо будет если с одного счета будут сняты деньги, а на счет 2 не поступят. Принцип атомарности в этом случае не будет выпонен.

Consistency — Согласованность
Система находится в согласованном состоянии до начала транзакции и должна остаться в согласованном состоянии после завершения транзакции.

Представьте, что у Вас есть система, состоящая их 2х и более узлов, которые реплицируют одну и туже информацию (попросту говоря копируют). Представьте себе, что вы записали некоторые данные на сервер1 и получили подтверждение успешной записи. Практически в тот же момент другой пользователь запросил данные, которые вы только что записали и не получил их... потому что балансировщик отправил его на сервер2 (куда данные еще не успели среплицироваться). Требование согласованности не выполнено.

Isolation — Изолированность
Во время выполнения транзакции другие процессы не должны видеть данные в промежуточном состоянии.


Durability — Долговечность
Независимо от проблем на нижних уровнях (к примеру, обесточивание системы или сбои в оборудовании) изменения, сделанные успешно завершённой транзакцией, должны остаться сохранёнными после возвращения системы в работу.

Другими словами если пользователь внес данные в вашу систему и почил подтверждение о том, что они успешно записаны, они не должны быть потеряны, вне зависимости ни отчего (пропало питание в ЦОД, посыпался диск...).

В противовес концепции ACID стоит концепция BASE.

BASE - Basically Available, Soft state, Eventual consistency

Базовая доступность, неустойчивое состояние, согласованность в конечном счёте
- в принципе доступна
- в принципе знаем состояние
- когда-нибудь сойдется


NoSQL DB - система хамелеон, в зависимости от Ваших пожеланий она может с разной степенью поддерживать любую концепцию парадигмы ACID. Как?
Об этом читайте в последующих постах!

Если у вас есть какие-либо вопросы по Oracle NoSQL - задавайте в комментах, постараюсь ответить, либо пишите на oracle.nosql@gmail.com
Пост 8. CRUD. Delete.

Итак, едем дальше. Создавать записи мы уже умеем. Умеем вытаскивать записи и умеем иъ изменять. Осталось только научиться удалять. Тут все предельно просто.


    public static void DeleteKey(String sKey, String store, String host, String port) {
        OraStore orastore = new OraStore(store, host, port);
        KVStore myStore = orastore.getStore();
        System.out.println("Store Opened");
        Key myKey = ParseKey.ParseKey(sKey);
        myStore.delete(myKey);
        myStore.close();
        System.out.println("Store Closed");
    }

Собственно, добавить мне нечего. От "скуки" я даже немного изменил концепцию - добавив коннект к базе кнутрь метода :) .
Ну и дабы разбавить этот достаточно неинтересный пост (будем объективны), привожу метод, который удаляет всю Вашу базу - очень удобно для разработки.


public static void ClearStore(String store, String host, String port) {
        OraStore orastore = new OraStore(store, host, port);
        KVStore myStore = orastore.getStore();
        System.out.println("Store Opened");

        System.out.println("Cleaning Store ...");

        Iterator<Key> keyIter = myStore.storeKeysIterator(Direction.UNORDERED, 0, null, null, null);
        Key key = null;
        List<String> majorPath = null;
        String majorPathStr = null;
        Hashtable<String, String> majorKeyHash = new Hashtable<String, String>();
        Integer count = 0;
        while (keyIter.hasNext()) {
            key = keyIter.next();
                  majorPath = key.getMajorPath();
            majorPathStr = majorPath.toString();
            if (!majorKeyHash.containsKey(majorPathStr)) {
                majorKeyHash.put(majorPathStr, majorPathStr);
                Key newkey = Key.createKey(majorPath);
                myStore.multiDelete(newkey, null, null);
                System.out.println(++count + " " + majorPathStr);
            }

        } //EOF while
        System.out.println("\nKVStore cleaned.");
        myStore.close();
        System.out.println("Store Closed");
    }

На сегодня наверное все.
Если у вас есть какие-либо вопросы по Oracle NoSQL - задавайте в комментах, постараюсь ответить, либо пишите на oracle.nosql@gmail.com.