Комментарии 7
Tarantool должен работать быстро. У нас есть грубая оценка — мы должны выдавать 1 Mrps на чтение и запись.
Не очень понятно, на каком оборудовании этот Mrps должен быть достигнут и каков размер данных для request?
Если этот Mrps отдается из кеша, то непонятно, при чем тут Memory ALLocators.
А помимо железа и размера спейсов есть еще море нюансов. Индекс — hash или tree (или rtree)? Индексируемое поле — число, строка, скаляр? Сколько полей в индексе? А сколько индексов? Запросы из lua или по сети (или по сети дергаем lua хранимку)? Записи делаем по одной или большими транзакциями? Сравнение строк бинарное или utf8 case insensitive? И это то, что первое пришло в голову.
Если интересны реальные цифры, то на моем почти десятилетнем десктопе все самое простое из вышеперечисленного в lua выдает около 0.5Mrps на запись и 1Mrps на чтение.
С ноутбуком вообще непонятно про 1 Mrps на чтение. Миллион взятий в секунду из локального кэша? Ну как-то так и должно быть, хоть на derby, хоть на bboltdb.
Миллион операций по записи в секунду — это впечатляет, но все равно непонятно, при чем тут память. Надо стремиться к "Zero memory allocations in hot paths", иначе с "миллионом" будут проблемы, как не выделяй.
Кроме того, миллион реальных операций записи в секунду это может быть около гигабайта в секунду. Терабайтный диск заполнится за 20 минут. Круто, что.
Конечно, если есть возможность избежать аллокации — нужно её избежать. Но это всё же можно сделать не всегда. И тут приходит на помощь аллокатор в высоким быстродействием.
Спасибо за статью! Было интересно почитать. Оставлю несколько предложений и вопросов:
1) В коде с примером работы Region в 10 строчке должно быть &fiber()->gc, AnotherItem)
(пропущена скобка).
А ещё функция region_alloc_object_xc
не представлена в списке сразу после заголовка "Region" (там есть только region_alloc
).
2) В описании LSRegion при упоминании LSM-дерева, мне кажется, уместно прикрепить ссылку на статью (только, может быть, стоит упомянуть, что она довольно убойная).
3) В разделе про OBuf, наверное, стоит добавить: "Когда Tarantool отвечает НА запрос по сети" .
4) В разделе про Small alloc слово задублировалось: "и такой БЛОК БЛОК будет результатом".
Не очень понятно, почему Small alloc с мемпулами используется именно для кортежей? Разве под них не нужно выделить один кусок памяти размером с сам этот кортеж?
5) В разделе про Matras тоже слово задублировалось: "в любой момент МОЖНО текущее состояние всех данных в одном Matras МОЖНО моментально".
Думаю, опечатка: "ИПРИ перезаписи какого-нибудь элемента...".
В этом ^^^ же разделе говориться про несколько потоков: "свободно использовать, например, в другом ПОТОКЕ без всяких мьютексов". Приведите, пожалуйста, пример потока, о котором идёт речь. Спрашиваю, потому что у Тарантула ведь один транзакционный поток.
Объясните, пожалуйста, когда может быть полезна ситуация "Для писателя элементы для него уже будут лежать в другом месте, а для читателя — в старом.". Разве это не означает, что у читателя будут старые данные?
Спасибо, поправил опечатки! Кроме:
не стал описывать
region_alloc_object_xc
, на самом деле там есть с десяток различных врапперов, это один из них, упоминать их не хочется чтобы незахламлять суть.ссылку на статью про винил не стал добавлять, потому что в этой статье хочется говорить про общие подходы, а не про частные решения.
А что касается вопросов:
Small alloc и кортержи - не понял вопроса. Кортеж - это единица хранения данных, что-то типа одного ряда таблицы. Хранится в памяти он одним кусоком. Кортежи переменного размера, поэтому для них нужен аллоктор общего назначения. Подошел бы malloc, но вместо него мы используем свой small_alloc.
В Тарантуле действительно один транзакционный поток, но есть еще несколько вспомогательных потоков. В частности recovery checkpoint (он же snapshot на диске) пишется из треда. Еще один пример relay поток реплики. Когда приходит пустая реплика и присоединяется к кластеру, для неё создается персональный поток, а чтобы заполнить реплику текущими данными - в этот поток также передается read view всех данных.
Про читателя и старые данные - все верно, это и нужно. Читатель дожен получить консистентный неизменный read view на какой-то момент времени, писатель будет создавать новое состояние базы данных, а читатель - получается будет работать с неизменным старым.
Работа с памятью в Tarantool: Small — Specialized Memory ALLocators