Моей ситуацией является то, что я в настоящее время храню иерархию в базе данных SQL, которая быстро приближается к 15000 узлам (5000 ребер). Эта иерархия определяет мою модель безопасности, основанную на позиции пользователей в дереве, предоставляя доступ к элементам ниже. Поэтому, когда пользователь запрашивает список всех защищенных элементов, я использую CTE, чтобы перезаписать его в db (и сгладить все элементы), который начинает показывать свой возраст (медленный).Как эффективно хранить и считывать иерархию из кеша
Иерархия не меняется часто, поэтому я попытался переместить ее в ОЗУ (redis). Имея в виду, у меня есть много подсистем, которые нуждаются в этом для вызовов безопасности, а пользовательский интерфейс - для создания дерева для операций CRUD.
Первая попытка
Моя первая попытка сохранить отношения как ключевой пары значений (это, как его хранится в базе данных)
E / \ F G /\ /\ H I J K mapped to: E - [F, G] F - [H, I] G - [J, K]
Так что, когда я хочу, E и все его decedents, я рекурсивно получаю его ребенка и его ребенка с помощью ключей, и это позволяет мне начинать с любого узла, чтобы двигаться вниз. Это решение дало хороший прирост скорости, но с 15 000 узлов, это было примерно 5000 попыток кэша для восстановления моего дерева в коде (худший сценарий ... начиная с E. производительность основывается на местоположении стартовых узлов, в результате чего суперпользователи видят наихудшая производительность). Это было все еще довольно быстро, но, казалось, болтливо. Мне нравится, что я могу удалить узел в любое время, вытащив его из списка ключей, не перестраивая весь мой кеш. Это также быстро освещалось, чтобы визуально создавать дерево по требованию в пользовательском интерфейсе.
Вторая попытка
Моя другая идея заключается в принять Иерархию из базы данных, построить дерево и хранить, что в оперативной памяти (Redis), а затем вытащить все вещи из памяти (это было около 2 MB по размеру, сериализован). Это дало мне один вызов (не как chatty) в redis, чтобы вытащить все дерево, найти родительский узел пользователя и спуститься, чтобы получить все дочерние элементы. Эти вызовы часты, и передача вниз по 2 МБ на сетевом уровне казалась большой. Это также означает, что я не могу легко добавить/удалить и элемент, не сбрасывая дерево и не редактируя его и не отталкивая его обратно. Также по запросу деревья, построенные по HTTP, означали, что каждый запрос должен был сбрасывать 2 МБ, чтобы получать прямые дети (очень мало, используя первое решение).
Итак, какое решение, по вашему мнению, является лучшим подходом (в долгосрочной перспективе оно продолжает расти). Оба вызывающе ускоряются и берут нагрузку на базу данных. Или их лучший способ добиться этого, о котором я не думал?
Thanks
Как вы решили эту проблему? – vishal