пятница, 12 апреля 2013 г.

Пост 21. Large Object в Oracle NoSQL Database (LOB).

Доброго времени суток!
В Oracle NoSQL DB версии 2 появилась поддержка Large Object.

Когда то совсем давно я писал, что Oracle NoSQL – хорошая платформа для хранения больших файлов: видео и аудио, например. Но вот как то получилось так, что я не рассказал как это делать.
Во-первых, давайте договоримся о том какой объект считать большим более 1 Мб (так рекомендует Oracle). LOB объект хранится как набор chunk-ов (сами chunk могут быть разного размера).
Во-вторых, давайте посмотрим как записывать LOB в базу. Давайте запишем некоторый файл.
По традиции создадим метод:

    public static void putLob(String sKey, String pathToFile, KVStore myStore)
            throws FileNotFoundException, IOException {
        final Key myKey = ParseKey.ParseKey(sKey);
        File lobFile = new File(pathToFile);
        FileInputStream fis = new FileInputStream(lobFile);
        Version version = myStore.putLOB(myKey, fis, Durability.COMMIT_WRITE_NO_SYNC, 5, TimeUnit.SECONDS);
    }

Прим.: префикс ключа LOB должен заканчиваться на .lob (например: test/image/1.lob).
Прим2.: файлы для тестов удобно генерить командой dd
Например, dd if=/dev/zero of=big.file bs=100M count=20 - сгенерит 2 Гб файл.

Чтение происходит по chunk (порциям). В ходе чтения может поменяться сервер чтения chunk.
Давайте возьмем программу из документации, которая читает lob файл и выводит колличество байт:

    public static int SelectLOB(String sKey, KVStore myStore) throws IOException {
        data = null;
        int byteCount = 0;
        Key myKey = ParseKey.ParseKey(sKey);
        try {
            InputStreamVersion istreamVersion =
                    myStore.getLOB(myKey, Consistency.NONE_REQUIRED, 5, TimeUnit.SECONDS);
            InputStream stream = istreamVersion.getInputStream();
            while (stream.read() != -1) {
                byteCount++;
            }
        } 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 {
        }

        return byteCount;
    }


Запускаем чтение, при этом у нас открыта консоль мониторинга (dstat -tdn 1) всех трех машин из шарда.
Смотрим и видим:


Чтение началось с одной машины, а продолжилось с другой. Т.е. при чтении несколькими агентами данных NoSQL страхует нас от "перекоса" в пользу какого-либо из шардов.

Любите технологии, пытливого ума вам, ну а если будут вопросы по Oracle NoSQL - welcome!

Комментариев нет:

Отправить комментарий