пятница, 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