суббота, 11 января 2014 г.

Redisson - распределенные и масштабируемые структуры данных Java на основе сервера Redis

Опубликовал первый релиз проекта Redisson. Проект позволяет использвать знакомые всем структуры данных Java (Set, List, Map, Queue, AtomicLong, Lock, CountDownLatch), а также использовть функционал publish/subscribe в распределенном виде с поддержкой масштабирования. Все это достигается благодаря использованию весьма популярного сервера Redis, для которого Redisson является лишь клиентом.

Вам даже не придется знать команды Redis-а, да и возможности вызова команд Redis напрямую нет, т.к. цель проекта предоставить удобный api с использованием уже известных Java-интерфейсов. Для выполнения вызовов на сервере Redis используется пропаченный Redis-клиент - lettuce.

Представленный api по своей стуктуре в чем-то схож с Hazelcast api. Проект Hazelcast может хранить данные только в памяти, что не всегда удобно и влияет на надежность системы. Сервер Redis, в свою очередь, предоставляет три способа хранения данных:
   1. только в памяти
   2. переодическое сохранение на диск (snapshotting) - используется по-умолчанию
   3. лог транзакций, т.е. синхронная запись каждого изменения в лог (append-only file)
Таким образом, благодаря возможностям сервера Redis, мы получаем распределенные java структуры данных с возможностью хранения состояния не только в памяти.

Доступ к хранилищу Redis реализован практически для любого языка программирования, благодаря большому количеству реализованных клиентов. Соотвественно данные созданные в Redisson будут доступны для любого Redis-клиента.

Изначально проект задумывался как простая попытка реализовать Map на Java через Redis-команды. Однако дальнейшее изучение команд Redis, (в Redis есть поддержка транзакций, hashes, lists, sets) навело на мысль о реализации более сложных структур, таких как Lock и CountDownLatch.

В проекте более 70 unit-тестов, для запуска которых (по-умолчанию они отключены) нужно запустить локально Redis-сервер и запустить maven-сборку с параметром -DskipTest=false
Примеры использования:
Распределенный Map:
        Config config = new Config();
        config.setConnectionPoolSize(10);
        config.addAddress("some.redis-server.com:8291");
        Redisson redisson = Redisson.create(config);

        ConcurrentMap<String, SomeObject> map = redisson.getMap("anyMap");
        map.put("123", new SomeObject());
        map.putIfAbsent("323", new SomeObject());
        map.remove("123");

        ...

        redisson.shutdown();

Распределенный Lock:
        Redisson redisson = Redisson.create();

        Lock lock = redisson.getLock("anyLock");
        lock.lock();
        lock.unlock();

        // или

        redisson.getLock("anyLock").lock();

        ...

        redisson.getLock("anyLock").unlock();

        ...

        redisson.shutdown();