LINUX.ORG.RU

Сообщения hellonik

 

Вот есть такая timeseries-хранилка - kdb+. А чё в ней такого волшебного?

Чё там такого внутри этой kdb+, что оно не пишется за несколько месяцев расслабленно по вечерам на крестах и за что там надо платить тыщи баксов-на-ядро?

Слышал что трейдинговые трейдеры в этой штуке timeseries хранят и страшно прутца от её скорости и размера бинарника меньше мегабайта, но пока не понял чего там внутри такого революционного, что какие-нибудь крестописцы, сидя в офисе Тинькова, не осиливают это повторить, скажем.

Ну и, скажем, чем их кликхаус не устроил как колоночная хранилка этих их биржевых котировок, если вставлять в КХ пачками по 100К строк.

References

https://en.wikipedia.org/wiki/Kdb%2B

 

hellonik
()

Как реализовать лайки в кастомной СУБД?

Есть кастомная СУБД, типа на redis, которая умеет хранить key=SET. SET - это хранилка уникального набора строк. По ключу key я могу в этот SET добавлять/удалять строки с результатом «успех/фейл», получать текущее число строк в этом SET и т.п. То есть, эта СУБД условно представляет собой C++-структуру map<string, set<string>>.

Юзер uid нажал лайк на посте/комменте/фотке obj_id - тогда я втыкаю в SET с именем likes_{obj_id} новую строку obj_id:

DB.insert("likes_" + obj_id, uid);

Мы можем достать из ключа likes_{obj_id} список лайкеров данного поста, просто увидеть число лайков, взяв size() этого SET и просто не дать юзеру лайкнуть что-то дважды, SET ведь не жрёт одну строку дважды.

Например, у меня есть чатик (группа в телеграме), а при заходе в чатик надо показать сразу 50 последних сообщений. Если сам чатик хранитсяв структуре данных типа key=LIST, то достать любой подинтервал сообщений чатика очень быстро по диску/памяти, но вот нарисовать у каждого сообщения сердечко с числом лайков этого сообщения - это уже нужно перебирать ключи likes_{obj_id}, где obj_id - конкретная сообщенечка. Когда 10К юзеров поставят утюг на F5 в этом чатике, серверу станет больно.

Чтобы сервер так не болел, в каждой сообщенечке есть бинарный header, где в каком-то месте есть 4-байтный счётчик лайков, а в СУБД реализован такой транзакционный прикол:

// Найти в key2 SET, вставить в него str и если это удалось
// то найти в key1 строку, и трактуя 4 байта по offset как uint32 заинкрементить этот uint32 на 1.
increment_uint32(key1, offset, key2, str);

Аналогично есть декремент и прочие подобные штуки. То есть, лайк сообщения сразу инкрементит что-то в header этого сообщения, никак не меняя длину объекта-сообщения. Таким образом, доставая сообщение, я сразу получаю и его число лайков.

Ну, в логике «классических» СУБД, типа mysql, можно сказать, что сообщение - это строка в таблице, у строки есть колонка «likes_cnt» и эту колонку в этой строке инкрементят какой-то хранимой процедурой, которая не инкрементит это дважды для данного юзера и данного сообщения. В общем, tuple из типизированных полей он и в африке такой: ему можно менять поля, не меняя его размер и сохраняя offset до каждой колонки константным.

Теперь возникает боль: а лайков-то разных бывает много. Лайк - это только один из видов реакции на сообщение. Во всяких там Slack разных реакций существует 100500 и юзеры ещё и свои умеют добавлять. Тут уже прикол с header внутри сообщения проканает чуть менее, чем никак. Я конечно могу в колонке «likes_cnt» хранить адский бинарный JSON вида {«likes»:10, «dislikes»:80, «cry»:4, «fuck»:1}, перезаписывая полностью на какое-то изменение, но это какая-то боль и профнепригодность. Посоветуйте каких-нибудь дата-структурных идей, имея то допущение, что в нашей кастомной СУБД мы можем реализовать что взбредёт в голову, подобно вон тому «условному инкременту любых байт по любому оффсету» и даже страшнее.

 

hellonik
()

RSS подписка на новые темы