Веб-разработка

индекс
236,88

Обновились Redis 1.2.1 и PHP клиент Rediska 0.3.0

RediskaRedis — это очень быстрая key-value база данных. Может использоваться как memcached, но отличие от последней в том, что Redis сохраняет свои данные на диск, то есть может быть использован для хранения данных (что мы успешно и делаем). Основные отличии от других собратьев — более сложные структуры данных (списки, коллекции) и атомарные операции с ними. Читайте более подробный обзор Redis на Хабре.


Что нового в Redis 1.2.1

  • Sorted sets — упорядоченные коллекции («сеты»). Для каждого элемента хранится индекс (score) по которому «сет» и сортируется.
  • MSET и MSETNX — установка нескольких значений одной командой.
  • SRANDMEMBER — возвращает случайный элемент из «сета».
  • RPOPLPUSH — возвращает последний элмент из списка и вставляет в начало другого.
  • Новые атрирбуты для комманды SORT
  • Append Only File — новый метод сохранения данных на диск.
  • Новый binary safe протокол
  • Новая политика хранения integer значений приводящая к приличной экономии памяти (30% для базы с большим количеством integer значений).
  • Поддержка Solaris.
  • Исправления ошибок и оптимизация производительности.
Такой внушительный список изменений не может не радовать! Читайте полный список на официальном сайте.

Что нового в Rediska 0.3.0

Подробнее о Редиске вы можете прочитать на официальном сайте или в обзоре на Хабре.

Примеры работы на дисерт


Создаем ключ на 2 минуты и сохраняем значение, если пусто:

<?php
// инциализация ключа
require_once 'Rediska/Key.php';
$key = new Rediska_Key('keyName', 60 * 2);

// старый способ
$value = $key->getValue();
if ($value === null) {
    $value = $exampleObject->getNewValue();
    $key->setValue($value);
}

// новый способ
$value = $key->getOrSetValue($exampleObject)->getNewValue();
?>

Работаем со списком:

<?php
// инициализация списка
require_once 'Rediska/Key/List.php';
$list = new Rediska_Key_List('list');

// добавляем новые элементы
$list[] = 'first element';
$list[] = 'second element';

// получаем элемент
echo $list[1]; #=> 'second element';

// Заменяем элемент
$list[0] = 'new first element';

// Получаем количество элментов
echo count($list); #=> 2

// Проверяем установлен ли элемент с указанным индексом
echo isset($list[0]); #=> true

// Итерация списка
foreach($list as $element) {
    echo $element;
}
?>

Работа с «пайплайнами» и выполнение команд на указанном сервере:

<?php
// инициализация
$options = array(
    'namespace' => 'MyApplication_',
	'servers' => array(
        'exapmleAlias' => array('host' => '127.0.0.1'),
	    array('host' => '127.0.0.1', 'port' => 6380)
	)
);
require_once 'Rediska.php';
$rediska = new Rediska($options);

// создать ключ на сервере "exampleAlias"
$rediska->on('exampleAlias')->set('a', 'b');

// выполяем серию команд в "пайплайне"
$result = $rediska->pipeline()->set('a', 1)
                                           ->increment('a', 10)
                                           ->rename('a', 'b')
                                           ->get('a')
                                           ->execute(); // выполнить команды и вернуть ответы
?>
Более подробную информацию и примеры читайте в документации.

Rediska — открытый проект: вы можете поучаствовать в разработке или стать автором интеграции с любимым фреймворком. Контакты авторов вы найдете на сайте проекта.
+36
25 января 2010, 15:56
48

комментарии (28)

+1
vadimdne #
достойная замена memcached, спасибо
+1
eugyn #
Нормальные бенчмарки в сравнении с оттюненным memcached увидеть.
Тогда и можно о достойной замене говорить.

Пока таких не видел.
+3
iobit #
Memcached хранит в памяти только ключ -> значение.
Смысл же Redis хранить ключ -> (значение1; значение2;…; значениеN). В основном, конечно.

Что вы тут предлагаете сравнивать? Сколько каждый тратит на выборку из памяти? Наверное, одинаково, если память одинаковая.

По-моему, делать бенчмарк довольно глупо в том смысле, что вы будете сравнивать молоток с циркулярной пилой. Это немного разные инструменты по своей природе. Хотя циркулярной пилой можно попробовать забивать гвозди, а молотком попробовать пилить доски.

Кстати, и наверное количество плюсов на вашей комментарии, естественно незаслуженное, как раз отражает реальность того, что люди не видят дальше своего носа. Вот он хвалит мемкеш, а я его знаю. Плюс ему. Это так, философское :)
+1
eugyn #
Можно было бы тупо послать матчасть учить, да ладно не буду :-)

«Memcached хранит в памяти только ключ -> значение.
Смысл же Redis хранить ключ -> (значение1; значение2;…; значениеN). В основном, конечно.»
Memcached предназначен для кеширования, а редис для персистент хранения. Они вообще то этим отличаются. В основном :-)
И это принципиально разные продукты и использовать их нужно каждый для своих задач.

«Что вы тут предлагаете сравнивать? Сколько каждый тратит на выборку из памяти? Наверное, одинаково, если память одинаковая. „

Здесь не сдержусь — матчасть подучите. В части конкурентного доступа из разных тредов, что и когда лочится, как обеспечивается атомарность операций и вообще кто и чего делает. Где ботленек у кого. Что делает мемкешед я знаю, что делает редис — нет. Вот только редис в любом случае делает больше…

“По-моему, делать бенчмарк довольно глупо в том смысле, что вы будете сравнивать молоток с циркулярной пилой. Это немного разные инструменты по своей природе. Хотя циркулярной пилой можно попробовать забивать гвозди, а молотком попробовать пилить доски.»

Если бы вы были хотя бы немного внимательны, то наверняка заметили бы одну деталь. Мой пост был ответом на утверждение:
«достойная замена memcached, спасибо»
Под заменой заменой я понимаю продукт который умеет все, что умеет заменяемый как минимум не хуже и дополнительные возможности. В данном случае это не так. Нет данных по производительности и отсутствует LRU, который вообще то в редисе как бы и не к чему :-)
Вот только если редис вместо memcached использовать, то LRU руками городить нужно, а это я вам скажу дело не очень благодарное. Но нужное, особенно в свете известной проблемы редиса со свапом.
Если бы вы адресовали утверждение
«Это немного разные инструменты по своей природе. Хотя циркулярной пилой можно попробовать забивать гвозди, а молотком попробовать пилить доски.»
первому посту, это было бы абсолютно логично, а так, если выражаться политкорректно — это глупость.

«Кстати, и наверное количество плюсов на вашей комментарии, естественно незаслуженное, как раз отражает реальность того, что люди не видят дальше своего носа. Вот он хвалит мемкеш, а я его знаю. Плюс ему. Это так, философское :) „
Философ из вас тоже не очень. Найти в моем посте то что мне нравится или не нравится. Воображение у вас однако :-)
Мне к примеру в мемкешед тоже кое что не нравится. Могли бы к примеру при set'е cas отдавать. Причем реализовать это не так уж и сложно. Все примочки с тегированием нафиг бы были не нужны. Вот только не делают почему то :-(

Ну а про плюсы и нравится
У кого чего болит
:-)
0
iobit #
Ну с таким объяснением просто не остается никаких сомнений, что ваша изначальная мысль — было далекоидущим вперед ярким лучшем истины и знания.

Что касается все-таки скорости, то мне просто здесь здравый смысл подсказывает, что скорость у редиса такая же, точнее приблизительно такая же. Вот просто здравый смысл, какой он есть, так и подсказывает.
+1
gnomeby #
Есть ли возможность группировать ключи, а затем очищать всю группу?
0
Shumkov #
Подобный функционал в планах.
–1
LexL #
Можно привести пример, как в редиске звучик аналог «select * from table»?
0
bladeofsteel #
Зависит от типа «table» — свои команды для списков, сетов и упорядоченных сетов.
0
oe24 #
Редиска, Кохана!..
:)
0
pgrishin #
Append Only File нормально работает?
У него принцип — после снапшопа накапливать бинлоги, потом полный снапшот и по кругу, или апдейтит снапшоп на основе бинлогов параллельным тредом?
Как выглядит %id во время создания/апдейта снапшота?

0
Shumkov #
Мы пока используем старый вариант («снапшоты») и Append Only File еще не тестировали.

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

Плюсы этой схемы — при падении редиса при обычной схеме вы теряли данные которые были добавлены в промежуток снапшота. В данном случае вы не теряете данные.
Минусы — размер бин лога растет, и сейчас у редиса нету встроенных средств ротации, для этого используется комманда BGREWRITEAOF.

Мне кажется что был бы очень полезен гибридный вариант и автоматическая ротация лога с настройками в конфиге.
0
pgrishin #
имел ввиду если размер базы 10 гиг, то при подсасывании бинлогов объемом 20 мегабайт в базу, на диск будет запись 10 гигов или 20 мбайт?
0
Shumkov #
Затрудняюсь вам ответить. Советую читать тут: code.google.com/p/redis/wiki/AppendOnlyFileHowto
0
rubyrabbit #
Таки хотелось бы узнать, в каких реальных проектах используется Redis, как при этом выглядит реальный код, и как лучше проектировать для такого типа БД (а то все привыкли к реляционным)?

Спасибо и успехов.
0
aleks_raiden #
написано на сайте.
Код выглядит в зависимости от используемого класса/языка/библиотеки/как напишите.
0
rubyrabbit #
Ну я же не об этом спросил.
Победные заявления на сайте и реальный опыт хабровчан — разные вещи.
А вот меня и интересует реальный код на любой платформе. Пример из жизни.
Чем логика взаимодействия отличается от релационных БД? Каковы неочевидные особенности?
+1
Shumkov #
Вы можете посмотреть пример разработки упрощенного Твитера на сайте Редиса.
0
rubyrabbit #
Спасибо.

Вот такой бы пример разобрать по-русски, в сравнении с традиционной «мускульной» логикой. И указать, где же те весомые плюсы, что должны оправдать изучение новой технологии и миграцию на неё.
0
iobit #
На самом деле, код выглядит как и любой другой код для работы с коллекциями, более точнее сетами. Т.е. get и всякие добавления sadd, srem и так далее.

В каких реальных проектах? Ну например, есть задача хранить результаты игроков, чтобы потом составлять таблицу лидеров, плюс нужно еще делать таблицу лидеров среди твоих друзей. Т.к. играть могут где-то 50 000 — 100 000 тысяч пользователей, хранить и обновлять результаты в БД нецелесообразно. Проще сделать это в памяти. В этой версии Redis есть такая штука как sorted set — сет куда ты добавляешь значение и некоторый int, по которому все значения сортируется. Для этой задачи это именно то, что нужно — у нас есть key (название_игра/таблица_лидеров) куда мы кладем значения или делаем инкеремет когда нужно (имя игрока — сколько очков заработал). Это автоматом сортируется и когда нужно выбрать 100 первых — это всего лишь одна команда для redis. Удобно? По-моему, да.

Ну и кешировато можно, конечно. Это как раз то, для Memcached и используют, кстати.

0
boom #
переписал часть своего сервиса под редис — не могу нарадоваться :) Долго не мог привыкнуть к нерелеационному мышлению :) но в итоге теперь думаю нафиг этот монстр МуСКуЛ надо вообще!?

Пример «SELECT * FROM table»:
+1
boom #
упс, рано
function getAllItems() {
$items = array();

$dbconn = redis_pool::getConn();

$iids = $dbconn->get_members('items.set');

foreach($iids as $iid) {
$item = $dbconn->get('items.'.$iid);
if (!empty($item)) {
$items[] = $item;
}
}

return $items;
}
где в ключе «items.ID» сериализированный масив полей айтема.
0
rubyrabbit #
В чём выгода перед, допустим, PDO+SQLite?
Объём кода и логика приведённого кода будут такими же.
Redis быстрее? Логичнее? Вкуснее? :-)
0
boom #
не совсем понятен вопрос.
PDO+SQLite в класическом исполнении медленее ровно настолько, насколько медленнее обращение к диску чем к памяти.
если же PDO+SQLite (in MEMORY only) тогда надо придумывать механизмы сохранения данных на диск, дабы не потерять данные при краше.
0
rubyrabbit #
Тогда я уже ничего не понимаю: в Redis есть магия кеширования, недоступная в SQLite?
0
catharsis #
Подскажите, а есть ли у редиса memcached-совместимый интерфейс, или обязательно придется переделать софт, чтобы попробовать redis?
0
Shumkov #
Нет, придется переделывать.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.