Демка куска пашэ-СУБД движка. Сложно, но мы обсудим. Ссылка. Прототип. Можно тыкать.
|
||
---|---|---|
Очередной какой-то там пашэпроект.
http://fintank.ru:9090/ Что это. По ссылке - тестовая морда в самописный B+-Tree (с дикимичи фичами). Зачем писать своё B+-Tree Незнаю, чё-то все их пишут в мире, наверное это круто. Да ещё вещь не простая, каждый раз что-то своё получается под свои задачи. Как понять. Зайдя по ссылке видим корень дерева. Сверху написано level 5. Значит дерево высотой 6 (самый нижний листовой уровень - level = 0). Почему такое высокое - оно тестовое с размером страницы 512 байт, чтобы блоки почаще делились и проявлялись всякие краевые эффекты. В это дерево напихано 1М элементов. Элемент - это key=value, но их только половина от ляма. Остальная половина элементов - это другие упоротые вещи, о них речь далее. В корне мы видим, что у нас там лежат два разделяющих (всё наше пространство) ключа. По текущей ссылке это: пустая строка и cgLQ. Почему там два - ну так сложилось, обычно больше. Каждый ключ ссылается на блок уровнем ниже (level 4). Если вы хотите найти что-то, что в порядке сортировки строк идёт после cgLQ - жмите на эту ссылку, если до - жмите на предыдущую. Вот скажем я жму на предыдущую (которая "пустая строка). Прихожу в этот блок: http://fintank.ru:9090/?block_id=451 Там навалены разделяющие ключи, которые все до cgLQ. Ну и так далее. Жмём на Bz: http://fintank.ru:9090/?block_id=104958 Жмём на CwvNtFkJk: http://fintank.ru:9090/?block_id=59010 Жмём на CzpDbTlmooFIljFDWNKzGy: http://fintank.ru:9090/?block_id=66489 Жмём на Czz: http://fintank.ru:9090/?block_id=131180 Оппа, пришли на level 0. Это листовой блок, он хранит сами полезные данные, а не информацию роутинга. В данном листовом блоке мы видим несколько ключей: Czz CzzKYs CzzZhYTyER <-- обсудите тот факт, что только у этого ключа тип key=value (KV). D Остальные ключи оказались не просто key=value, а массивами (листами). Например ключ Czz - хранит массив из 2 элементов: @@ocYDrqX @@UOV Это пример "дикой фичи" данного B+-Tree: key=[array]. Есть там ещё key=[set] и ещё key=[map], например. Зачем? - спросит очередной формоклёп с горы. "Разве нельзя было просто сериализовать как-нибудь что угодно, включая список, в строку и сохранить в любое key=value" - спросит он? Можно. Но так любая псина умеет. А чё ты будешь делать, если тебе надо вставить в конец списка? Достанешь ключ, десериализуешь, засериализуешь и пересетишь? Ясно. Сам так живи, мы не хотим. Нам надо так: список длинной 6 млрд элементов и мы вставляем в его середину, да так, чтобы это было за время вставки маленького key=value и чтобы индексы всех 3-млрд-после-середины элементов автоматом сдвинулись на 1 (или N, сколько мы там вставляем). Т.е. список может занимать много блоков данного B+-Tree. И мы не хотим трогать все эти блоки. Я не знаю сколько блоков займёт 6 млрд строчек. И я хочу потрогать максимум 2-3 блока, чтобы выполнить вышеозвученное требование. И хочу вообще на диск не ходить, если уже потрогал эти блоки и снова надо в середину вставить. Короче нужен не какой-то детский уровень, а чтобы сам товарищ Сталин руку пожал. Посмотрим на ключ D в данном листовом блоке. В нём лежит 15 элементов. Но это только кусок, точнее начало. Мы не зря в этот блок пришли. В нём кончается C-пространство и начинается D-пространство, скажем, например. Сколько элементов лежит в списке D я не знаю. Дохрена. Мы видим голову. Выйдем на уровень выше. Кнопки выше нет, юзайте назад в браузере или смотрите выше наш путь в этот листовой блок. А на уровне выше мы видим разделитель D:15. Он показывает на блок, в котором список D продолжается с элемента 15. Можно туда сходить, там всего 3 элемента и в блоке свободно 90% памяти. "Чё так не плотно" - спросит читатель. Ну уплотнялка тут решила не работать или выключена, не помню. Всё потому, что когда в список D в этом B+-Tree инсертились ключи, то они втыкались в рандомные смещения: ну типо 4, 1, 3, 2, 4, 1, 0, 3, 2.... Инсерт в позицию 0 предполагает что старый 0 становится 1. Чё-то я щас смотрю на этот D, у него только голова плотная, остальное надроблено по 1 элементу-на-блок. Короче ладно, это потом пофиксим. Можно посмотреть на этот блок: http://fintank.ru:9090/?block_id=59010 Видно что тут индексы у D шагают на сотни. Если я хочу элемент списка >= 709,то ясно по какому маршруту идти. Вся структура, ясно дело, относительная, на новом уровне надо всё суммировать к 709. Относительная она потому, что... долго объяснять... короче чтобы разные куски маршрутов были максимально независимы. Так мы добиваемся того, что при сдвиге всех элементов в 6-млрд-элементном списке можно пошевелить только какой-то верхний уровень, не думая больше ни о чём. В общем, подумайте и поймёте. Очевидное решение довольно. А вот тут: http://fintank.ru:9090/?block_id=104958 есть D:963. В общем, можно сказать что в D лежит больше 963 элемента точно. Больше чем D:963 + D:590 ну и т.п. - сходите по той ветке, суммируя максимальные индексы разделителей, узнаете. Там оказывается ещё список DA валяется. А тут лежит последний ключ дерева: http://fintank.ru:9090/?block_id=114364 Он называется zzzo и он оказался тоже списком из 1 элемента. Нахрен нужны списки обычному человеку и подобный простой доступ к его рандомным кускам и диапазонам? Например, чатики любых размеров хранить. Большой чатик из 10 млрд сообщений просто жрёт блоки, а доступ к любой месаге по порядковому номеру моментален. Чатик из 1 сообщения занимает как 1 жалкое key=value - удобно, дёшево, молодёжно. Можно дать юзеру создать сто миллиардов топиков в день и никто не умрёт. А в структурах типа key=[set] можно хранить инфу из кнопки лайков. Пихаешь туда id юзеров, оно гарантирует их уникальность и может быстро сказать количество элементов в сете - можно нарисовать циферку лайков. Массивы, сеты (множества), мапы (словари) и прочая дичь, рубить которую на куски умеет B+-Tree - это очень мощно, потому что блоки - вещь децентрализуемая, компактная, сжимаемая и очень сильно крупнологарифмическая, что в целом приводит к существенной бесплатности происходящего. Бенчмарки: в среднем инсерт сюда стоил 7 микросек, селект стоил в среднем 0.7 микросек. Блоки нарублены плохо, во многих 90% пустого пространства. Стоит включить мёржилку, чтобы при инсертах она смотрела на соседей и объединяла их. Это сожрёт сколько-то тактов, но селекты будут ещё быстрее, блоков-то будет меньше раз в 10. Если делать размер блока не наркоманский, а нормальный, где-нибудь в 65 Кб, то уровней будет не 5, а естественно штуки 2-3. Чтокакбе намекает нам на то, что это надо протестить. Вообще у всяких Дональдов-Кнутов описаны B*-Tree (звёздочка) и там есть какие-то соотношения про 2/3 и мёржинг, но в реальности нужно думать. Могу бухнуть с экспертами в этой области. А, да, я ещё статистику считаю конечно же: скажем, если с вероятностью 0.9 втыкали в конец блока (кто-то льёт в конец списка или инсертит возрастающие ключи), то при делении блока левый сын получит 90% старых ключей, а всё свободное место и 10% старых ключей достанется перспективному правому сыну. Левые обычно социалисты. Хорошо примерчик получился про "перспективый", конечно. Мемно! Ну и вот. Я незнаю чё в этот раз так наделилось странно. А вспомнил, мёржилка не работала вообще и был полный рандом во вставке. Да, конечно тестировали на совпадение данных в этом B+-Tree с референсным хранилищем - всё совпадает, обижаешь. Нормальные люди ещё умеют сжимать ключи, скажем сохранять только общие префиксы. Миллиард литературы есть по теме, конечно. Досвидания. |
||
Модератор:
![]()
Нравится:
Не нравится:
|
||
30.08.2020, 03:26 |
|
Демка куска пашэ-СУБД движка. Сложно, но мы обсудим. Ссылка. Прототип. Можно тыкать.
|
||
---|---|---|
Можно потрогать и потестить.
|
||
Модератор:
![]()
Нравится:
Не нравится:
|
||
09.09.2020, 19:42 |
|
Демка куска пашэ-СУБД движка. Сложно, но мы обсудим. Ссылка. Прототип. Можно тыкать.
|
||
---|---|---|
афтар, реализован ли поиск ключей по диапазону и по маске? можно ли делать составной ключ, например timestamp + key и искать пачку keys с учетом даты ? или стоит афтору принять новичок
|
||
Модератор:
![]()
Нравится:
Не нравится:
|
||
12.09.2020, 16:00 |
|
Демка куска пашэ-СУБД движка. Сложно, но мы обсудим. Ссылка. Прототип. Можно тыкать.
|
||
---|---|---|
Дырокол 12.09.2020, 16:00 афтар, реализован ли поиск ключей по диапазону и по маске? можно ли делать составной ключ, например timestamp + key и искать пачку keys с учетом даты ? или стоит афтору принять новичок |
||
Модератор:
![]()
Нравится:
Не нравится:
|
||
12.09.2020, 16:14 |
|
Демка куска пашэ-СУБД движка. Сложно, но мы обсудим. Ссылка. Прототип. Можно тыкать.
|
||
---|---|---|
FSR 12.09.2020, 16:14 Дырокол 12.09.2020, 16:00 афтар, реализован ли поиск ключей по диапазону и по маске? можно ли делать составной ключ, например timestamp + key и искать пачку keys с учетом даты ? или стоит афтору принять новичок нет - в том смысле что для того, чтоб эти фичи приемлемо работали, необходимо, чтоб дерево строилось с учетом этих фич и хранило доп инфу для поиска. например B+tree имеет плюс в названии потому что листы одного уровня знают друг о друге не через родителей, а непосредственно. для того чтобы убыстрить скан по диапазону подряд идущих ключей. |
||
Модератор:
![]()
Нравится:
Не нравится:
|
||
12.09.2020, 16:24 |
|
Демка куска пашэ-СУБД движка. Сложно, но мы обсудим. Ссылка. Прототип. Можно тыкать.
|
||
---|---|---|
Дырокол 12.09.2020, 16:24 FSR 12.09.2020, 16:14 Дырокол 12.09.2020, 16:00 ... нет - в том смысле что для того, чтоб эти фичи приемлемо работали, необходимо, чтоб дерево строилось с учетом этих фич и хранило доп инфу для поиска. например B+tree имеет плюс в названии потому что листы одного уровня знают друг о друге не через родителей, а непосредственно. для того чтобы убыстрить скан по диапазону подряд идущих ключей. Пример: составной ключ: (timestamp : int32, value : int32). Для дерева он будет выглядеть как 8-байтный ключ, где первые 4 занимает timestamp, вторые value. Дереву похрен на слово "составной". Юзер дерева (движок СУБД, для которого это дерево всего-лишь реализация индекса) при желании получить всё строки WHERE: timestamp = 0x11223344 AND value >= 0x55 AND value <= 0xFFFFFFFF просто ставит 8-байтный ключ в значение 0x1122334455000000 и бежит пока он не станет равен 0x11223344FFFFFFFF. (endian-ness в этом базаре не учитывается и хер с ней) |
||
Модератор:
Изменено: 12.09.2020, 16:29 - FSR
![]()
Нравится:
Не нравится:
|
||
12.09.2020, 16:28 |
|
Демка куска пашэ-СУБД движка. Сложно, но мы обсудим. Ссылка. Прототип. Можно тыкать.
|
||
---|---|---|
FSR 12.09.2020, 16:28 Дырокол 12.09.2020, 16:24 FSR 12.09.2020, 16:14 ... нет - в том смысле что для того, чтоб эти фичи приемлемо работали, необходимо, чтоб дерево строилось с учетом этих фич и хранило доп инфу для поиска. например B+tree имеет плюс в названии потому что листы одного уровня знают друг о друге не через родителей, а непосредственно. для того чтобы убыстрить скан по диапазону подряд идущих ключей. Пример: составной ключ: (timestamp : int32, value : int32). Для дерева он будет выглядеть как 8-байтный ключ, где первые 4 занимает timestamp, вторые value. Дереву похрен на слово "составной". Юзер дерева (движок СУБД, для которого это дерево всего-лишь реализация индекса) при желании получить всё строки WHERE: timestamp = 0x11223344 AND value >= 0x55 AND value <= 0xFFFFFFFF просто ставит 8-байтный ключ в значение 0x1122334455000000 и бежит пока он не станет равен 0x11223344FFFFFFFF. (endian-ness в этом базаре не учитывается и хер с ней) |
||
Модератор:
![]()
Нравится:
Не нравится:
|
||
12.09.2020, 16:34 |
|
Демка куска пашэ-СУБД движка. Сложно, но мы обсудим. Ссылка. Прототип. Можно тыкать.
|
||
---|---|---|
поэтому у всяких кассандр есть столбцы, а есть суперстолбцы. по сути - по второй индекс по части ключа
|
||
Модератор:
Изменено: 12.09.2020, 16:35 - Дырокол
![]()
Нравится:
Не нравится:
|
||
12.09.2020, 16:35 |
|
Демка куска пашэ-СУБД движка. Сложно, но мы обсудим. Ссылка. Прототип. Можно тыкать.
|
||
---|---|---|
Дырокол 12.09.2020, 16:34 FSR 12.09.2020, 16:28 Дырокол 12.09.2020, 16:24 ... Пример: составной ключ: (timestamp : int32, value : int32). Для дерева он будет выглядеть как 8-байтный ключ, где первые 4 занимает timestamp, вторые value. Дереву похрен на слово "составной". Юзер дерева (движок СУБД, для которого это дерево всего-лишь реализация индекса) при желании получить всё строки WHERE: timestamp = 0x11223344 AND value >= 0x55 AND value <= 0xFFFFFFFF просто ставит 8-байтный ключ в значение 0x1122334455000000 и бежит пока он не станет равен 0x11223344FFFFFFFF. (endian-ness в этом базаре не учитывается и хер с ней) 0x1122334411000000 идёт до 0x1122334411000001 Элементы составного ключа являются просто разрядами в неком "числе верхнего уровня", где разряды могут быть разных типов. Например в составном ключе с типами (int, double, string, string, time) важно только, что при их сравнении старшим разрядом будет int и только если они одинаковы мы переходим к сравнению double и т.п. В дереве это может лежать как непонятно что вида 0x137DF137F183745DF1848A20CA1081C2A, главное что пользователь этого дерева знает что это и как это сравнивается с другим подобным. |
||
Модератор:
![]()
Нравится:
Не нравится:
|
||
12.09.2020, 16:37 |
|
Демка куска пашэ-СУБД движка. Сложно, но мы обсудим. Ссылка. Прототип. Можно тыкать.
|
||
---|---|---|
FSR 12.09.2020, 16:37 Ну они упорядочены как составной ключ. по сути они упорядочены по ведущим байтам (допустим у тебя ведущие 4). а остальные - фуллскан. смотри, я вот о чём: храним дату рождения и фио в одном ключе. дата впереди, фио позади. когда ты хочешь найти путиных за декабрь прошлого года, действительно, ты быстро берешь пул декабря и в нем быстро выходишь на фио с ПУ до ПФ. ну а теперь запрос - просто взять всех ПУТИНЫХ. и тут же тебя настигает фулскан |
||
Модератор:
![]()
Нравится:
Не нравится:
|
||
12.09.2020, 16:45 |
|
Демка куска пашэ-СУБД движка. Сложно, но мы обсудим. Ссылка. Прототип. Можно тыкать.
|
||
---|---|---|
чтобы запрос на только по ФИО был эффективен, нужно иметь сортировку по фио (по сути второй индекс). также надо иметь механизм быстро двигаться по диапазону последовательно без родителей, если запрос предполагает выбирать подрядидущие листья. ну и т.д. и т. п.
|
||
Модератор:
![]()
Нравится:
Не нравится:
|
||
12.09.2020, 16:48 |
|
Демка куска пашэ-СУБД движка. Сложно, но мы обсудим. Ссылка. Прототип. Можно тыкать.
|
||
---|---|---|
Дырокол 12.09.2020, 16:45 FSR 12.09.2020, 16:37 Ну они упорядочены как составной ключ. по сути они упорядочены по ведущим байтам (допустим у тебя ведущие 4). а остальные - фуллскан. смотри, я вот о чём: храним дату рождения и фио в одном ключе. дата впереди, фио позади. когда ты хочешь найти путиных за декабрь прошлого года, действительно, ты быстро берешь пул декабря и в нем быстро выходишь на фио с ПУ до ПФ. ну а теперь запрос - просто взять всех ПУТИНЫХ. и тут же тебя настигает фулскан |
||
Модератор:
![]()
Нравится:
Не нравится:
|
||
12.09.2020, 16:50 |
|
Демка куска пашэ-СУБД движка. Сложно, но мы обсудим. Ссылка. Прототип. Можно тыкать.
|
||
---|---|---|
Дырокол 12.09.2020, 16:48 чтобы запрос на только по ФИО был эффективен, нужно иметь сортировку по фио (по сути второй индекс). также надо иметь механизм быстро двигаться по диапазону последовательно без родителей, если запрос предполагает выбирать подрядидущие листья. ну и т.д. и т. п. |
||
Модератор:
![]()
Нравится:
Не нравится:
|
||
12.09.2020, 16:52 |
|
Демка куска пашэ-СУБД движка. Сложно, но мы обсудим. Ссылка. Прототип. Можно тыкать.
|
||
---|---|---|
FSR 12.09.2020, 16:50 Дырокол 12.09.2020, 16:45 FSR 12.09.2020, 16:37 ... по сути они упорядочены по ведущим байтам (допустим у тебя ведущие 4). а остальные - фуллскан. смотри, я вот о чём: храним дату рождения и фио в одном ключе. дата впереди, фио позади. когда ты хочешь найти путиных за декабрь прошлого года, действительно, ты быстро берешь пул декабря и в нем быстро выходишь на фио с ПУ до ПФ. ну а теперь запрос - просто взять всех ПУТИНЫХ. и тут же тебя настигает фулскан |
||
Модератор:
![]()
Нравится:
Не нравится:
|
||
12.09.2020, 16:55 |
|
Демка куска пашэ-СУБД движка. Сложно, но мы обсудим. Ссылка. Прототип. Можно тыкать.
|
||
---|---|---|
Дырокол 12.09.2020, 16:55
не понял как просто описание еще одного своего правила сравнения избавляет от фуллскана, когда у тебя запросы по разным частям составного ключа обычного B+-Tree Топик про один индекс. |
||
Модератор:
Тема была перенесена из форума 'Общение'.
![]()
Нравится:
Не нравится:
|
||
12.09.2020, 16:56 |
|
get settings: | 1ms |
get forum list: | 1ms |
check forum access: | 0ms |
check topic access: | 0ms |
get msg page: | 1ms |
>>> redirection >>>: | 102ms |
get settings: | 1ms |
get forum list: | 1ms |
check forum access: | 0ms |
check topic access: | 0ms |
get topic data: | 1ms |
get forum data: | 0ms |
get page posts: | 23ms |
track hit: | 3ms |
get tp. blocked users: | 0ms |
get online users: | 1ms |
check new: | 2ms |
others: | 14ms |
total: | 151ms |