Pull to refresh

Comments 40

UFO just landed and posted this here
исправьте: нативный клиент на любымом Вам языке
UFO just landed and posted this here
а вам важен фикс или благодарность?
Тут не все так однозначно, публичность может не благодарность иметь своей целью: иногда пишу авторам в личку замечания по орфографии, пунктуации, переводу — исправляют не все, даже когда ошибки очевидные. Всем, кто исправляет — спасибо.
UFO just landed and posted this here
Одна из причин популярности Redis — простота использования
Тут, судя по вашему описанию, до простоты API Redis очень далеко
если Вы поклонник Перла, то клиент Перла позволяет работать с пcевдо SQL, типа писать запросы:
SELECT * FROM t0 WHERE k0=124
А почему псевдо? Вы, наверное, имеете в виду, что это — не полностью реализованный SQL.
это SQL реализованный не по стандарту SQL'92, а адаптироанный применительно к key/value хранилищам, чтоб программистам было легче создавать свое творчество.
Примеры:
update t0 set k1 = 2, k2 = 3 where k0=1
insert into t0 values (4294967295)
insert into t0 values (1, 'I am a new tuple')

select * from t0 where k0=4294967295
Здесь нет обращения к конкретной таблице, так как нет понятия таблиц в принципе. Запрос идет в конкретный неймспейс t0 (в данном случае =0 ), В данном случае важна цифра 0, и с таким же успехом можно написать
select * from n0 where k0=4294967295 — результат будет одним и тем же.
то же самое относится и к ключам, важен номер а не имя:
select * from n0 where k0=4294967295
select * from n0 where m0=4294967295
дадут один и тот же результат.
и еще нельзя написатьконкретные поля: SELECT field1,field3 FROM t0 WHERE k0 = 0
можно выбрать все поля звездочкой.
Ох плохая это идея.

Скажу как разработчик в свое время (2000-2002) довольно перспективной и очень необычной базы данных, основанной на связных множествах.

И одна из задач менеджмента была именно реализация под-множества возможностей SQL99. Типа чтоб кастомерам было легче переходить.

В результате это была имхо наиболее ошибочное решение, которое и привело к фейлу. Ошибка в том, что кастомеры искусившись SQL-языком стали писать почти обычные запросы, не воспользовавшись всей мощью entety-relations системы.

В общем мне кажется что если бд действительно необычна и дает какие-то существенные приемущества по сравнению с обычной SQL-бд, то не стоит давать возможность писать SQL-like запросы.
не смог найти клиент Перла, пожалуйста, покажите его.
Мне кажется, чтобы заинтересовать кого-то, нужно хотя бы привести сравнение производительности с существующими системами. А также показать примеры красивого использования, опять же, проводя какую-то параллель с тем же Redis.
А когда люди заинтересуются движком, то ли с точки зрения производительности, то ли с точки зрения возможностей, — тогда уже описывать протокол.
сравнение производительности memcache & rdis можно найти в интернете
Я делапл замеры на 100 000 последовательных get/set memcache/redis результат, 16/19 сек
с tarantool замеры не делал, но маилрушники его сравнивали с мемкешом и у меня нет причин их замерам не верить.
А что с Tokyocabinet/Kyotocabinet?
я работаю над этим вопросом ;)
есть положительные результаты
и вот в процессе сравнения с аналогами рождаются такие вот посты
как видно из замеров — чуть-чуть обгоняем мемкеш
5 копеек: абзац про редис это, извините, не имеет отношение к реальности. не хочется холиварить но и видов данных там достаточно — там не только списки, но и аналогичные вашей структуре ассоциативные массивы и много другого полезного, не говоря уж о базовых вариациях «ключ-значение». клиенты под него есть на всем что шевелится :) и многое другое
по сравнению с тарантулом фокус немного другой, так что каждому инструменту своя область, но чем тарантул лучше редиса если честно не видно (производительность думается сравнимая — нового уж давно никто ничего не выдвигал...).
имхо!
и я про тоже но другими словами, что у редиса есть мгного клиентов, по этому он и популярен. У Тарантула их нет, по этому популярность этой БД в тени.
Тарантул — имеет копию данных на диске (уже очень давно), и она не ломается, если сервер или машина падает.
Если Вы цените Ваши данные — думаю это важно.
То же самое с репликацией — в Tarantool она уже довольно давно.
Протокол в Tarantool бинарный, в Редисе текстовый — соотв. бинарный быстрее.
Хранимые процедуры в Tarantool пишутся один раз, компилируются один раз, выполняются много раз, в Redis'е только недавно появился eval, то есть каждый раз компилируется.
редис тоже имеет копию данных, репликация есть, протокол там *фактически* бинарный — оверхед порядка десятков байт (несеръезный), никакого ескейпинга данных не нужно. эвал в редисе компилируется не каждый раз (скомпиленные куски хранятся в кеше и дергать их можно по хешу не посылая весь скрипт — вообще эта часть активно развивается)
Хотелось бы bind-инг к популярным языкам программирования и ссылку на sourceforge с исходниками и собранными бинариками для популярных платформ. Тогда проще будет использовать.
согласен,
ссылкой выше клиент на руби.
Больше портов на другие языки нет из-за сравнительной молодости проекта.

Сишный клиент, входящий в состав дистрибутива как таковым не является. Маилрушники обещают его выпустить, но про сроки ничего не известно. стал разбираться с протоколом, чтоб сделать bind-инг к РНР — написал эту статью…
Клиенты в процессе, скачать можно с tarantool.org или github.com/mailru/tarantool.

Советую использовать ветку 'master-stable'
Я почитал код, и у меня возник вопрос:
Почему у вас LEB128 реализован в обратную сторону?
а какой код прочитали? уже столько воды утекло
Актуальный мастер на гитхабе
void
write_varint32(struct tbuf *b, u32 value)
{
    tbuf_ensure(b, 5);
    if (value >= (1 << 7)) {
        if (value >= (1 << 14)) {
            if (value >= (1 << 21)) {
                if (value >= (1 << 28))
                    append_byte(b, (u8)(value >> 28) | 0x80);
                append_byte(b, (u8)(value >> 21) | 0x80);
            }
            append_byte(b, (u8)((value >> 14) | 0x80));
        }
        append_byte(b, (u8)((value >> 7) | 0x80));
    }
    append_byte(b, (u8)((value) & 0x7F));
}
 


В обратную сторону:
u32
read_varint32(struct tbuf *buf)
{
    u8 *= buf->data;
    int size = buf->size;
 
    if (size < 1) {
        tnt_raise(IllegalParams, :"packet too short (expected 1 byte)");
    }
    if (!(b[0] & 0x80)) {
        buf->data += 1;
        buf->capacity -= 1;
        buf->size -= 1;
        return (b[0] & 0x7f);
    }
 
    if (size < 2)
        tnt_raise(IllegalParams, :"packet too short (expected 2 bytes)");
    if (!(b[1] & 0x80)) {
        buf->data += 2;
        buf->capacity -= 2;
        buf->size -= 2;
        return (b[0] & 0x7f) << 7 | (b[1] & 0x7f);
    }
    if (size < 3)
        tnt_raise(IllegalParams, :"packet too short (expected 3 bytes)");
    if (!(b[2] & 0x80)) {
        buf->data += 3;
        buf->capacity -= 3;
        buf->size -= 3;
        return (b[0] & 0x7f) << 14 | (b[1] & 0x7f) << 7 | (b[2] & 0x7f);
    }
 
    if (size < 4)
        tnt_raise(IllegalParams, :"packet too short (expected 4 bytes)");
    if (!(b[3] & 0x80)) {
        buf->data += 4;
        buf->capacity -= 4;
        buf->size -= 4;
        return (b[0] & 0x7f) << 21 | (b[1] & 0x7f) << 14 |
            (b[2] & 0x7f) << 7 | (b[3] & 0x7f);
    }
 
    if (size < 5)
        tnt_raise(IllegalParams, :"packet too short (expected 5 bytes)");
    if (!(b[4] & 0x80)) {
        buf->data += 5;
        buf->capacity -= 5;
        buf->size -= 5;
        return (b[0] & 0x7f) << 28 | (b[1] & 0x7f) << 21 |
            (b[2] & 0x7f) << 14 | (b[3] & 0x7f) << 7 | (b[4] & 0x7f);
    }
 
    tnt_raise(IllegalParams, :"incorrect BER format");
    return 0;
}
 
Не смог уснуть, не разобравшись.
Да, кажется, что наличие слов «Little Endian» в названии протокола указывает на то, что первым в поток лезет старший фрагмент. Но если вчитаться в спецификацию DWARF, то на страницах 70 и 71 можно найти такой текст:
It is ‘‘little endian’’ only in the sense that it avoids using space to represent the
‘‘big’’ end of an unsigned integer, when the big end is all zeroes or sign extension bits).

DW_FORM_udata (unsigned LEB128) numbers are encoded as follows: start at the low order
end of an unsigned integer and chop it into 7-bit chunks. Place each chunk into the low order 7
bits of a byte. Typically, several of the high order bytes will be zero; discard them. Emit the
remaining bytes in a stream, starting with the low order byte; set the high order bit on each byte
except the last emitted byte. The high bit of zero on the last byte indicates to the decoder that it
has encountered the last byte.


Отсюда следует, что в статье Википедии, на которую вы ссылаетесь в документации для ознакомления с LEB128, примеры кода правильные, а вот у вас порядок октетов в бинарном потоке не тот.
спасибо — буду проверять
Sign up to leave a comment.

Articles

Change theme settings