Необходимо прочитать n больших объектов (в сумме ~4 млрд. свойств) в бэкенде, как это сделать на сайте с Node.js самым оперативным способом?
Обновление 1. Изменил вопрос, теперь интересует загрузка объекта только в бекенд. Обновление 2. Добавил инфу о сути задачи, выложил примерный объект, изменил объект на несколько объектов и еще небольшие изменения. Обновление 3. Заменил слово "загрузить" на "прочитать" для верного понимания меня и некрупные изменения. Жирным выделил вопрос, на который еще не ответили.
Или массив. В объекте есть ссылки на 10 переменных (не циклические). Без учета вложенных объектов/массивов конечные элементы объекта/массива - это строки и числа (хотя это не принципиально). Вложенность свойств - десятиуровневая или одноуровневая, пока не определился. Свойства - варианты разложения 10 предметов по 9 ячейкам. Более подробно и пример объекта вы можете посмотреть в комментариях к вопросу. Так как размер объекта, с которым может работать JS ограничен в том числе мощностью железа, на котором он работает, то вместо одного объекта будет несколько объектов приемлемого размера, но суть вопроса от этого остается той же.
Бонусные вопросы. Базы данных, например, Mongo DB оперативнее в плане загрузки объектов, чем чтение из JSON-файла или нет? Чтение объекта быстрее в Node.js, чем в фронтендском JS, если мощности железа одинаковые? Вариант в JS-файлы вставить просто содержимое JSON-файла (в котором будет только те большие объекты) и подключить их как модуль в Node.js вместо чтения из БД или JSON-файла? Будет ли этот вариант чтения объектов быстрее, ведь не будет происходить парсирование (я правильно понимаю, что при чтении из БД происходит парсирование?)?
Каким способом объект/массив читается самым быстрым способом?
sim3x, Опишу задачу описанием игровой механики. Постараюсь максимально коротко. В самом конце представил объект аналогичный моему.
Пишется AI для компьютера-противника в игре, в игре пользователь играет против компьютера.
Есть поле состоящее из 9-ти ячеек и у каждого игрока (пользователя и компьютера) есть по 5 предметов. Они поочередно кладут предметы и происходит некоторая игровая механика (основа которой - только что расположенные предметы с большой, чем у соседей стоимостью, переводят соседние предметы в собственность противника) , в результате которой определяется победитель. Потенциальных вариантов итоговой раскладки предметов, исходя из которой определяется победитель и которые используются AI для выбора своего очередного хода примерно 4-5 млрд. Отсюда и такой большой объект. Для понимания моей ситуации этого достаточно, но если интересует пример объекта аналогичного моему с некоторыми пояснениями он представлен ниже.
В свойствах будут записываться потенциальная раскладка, где на каждом уровне вложенности будет потенциальная раскладка на очередном ходу вплоть до 9-го последнего. Для удобства напишу тут свойства кириллицей и подробнее. Подразумевается, что первым ходит пользователь. Потенциальные раскладки показываются свойством:значением, где свойство отражает очередной ход, а в значении показана раскладка и счет на момент после хода, а также процент выигрышных подвариантов.
varianty = {
"2 ход. 2 игрок 1-м предметом ходит на ячейку 2": {
"Раскладка": "0b5g-------------- schet=0:0",
"Процент выигрышных подвариантов": 75,
//дальше свойства этого вложенного объекта представляют собой раскладки на последующих потенциальных ходах
"3 ход. 1 игрок 2-м предметом ходит на ячейку 3": {
"Раскладка": "0b5g1b------------ schet=0:0",
"Процент выигрышных подвариантов": 73,
"4 ход. 2 игрок 2-м предметом ходит на ячейку 4": {
"Раскладка": "0g5g1b6g---------- schet=1:0",
<.....>
"9 ход. 1 игрок 5-м предметом ходит на ячейку 9": {
"Раскладка": "0g5g1b6g2b7g3g8g4b schet=2:0"
},
<.....>
},
...
},
"3 ход. 1 игрок 2-м предметом ходит на ячейку 4": ...
...
"3 ход. 1 игрок 2-м предметом ходит на ячейку 9": ...
},
"2 ход. 2 игрок 1-м предметом ходит на ячейку 3": "0b--5g------------ schet=0",
...
"2 ход. 2 игрок 1-м предметом ходит на ячейку 9": "0b--------------5g schet=0",
"2 ход. 2 игрок 2-м предметом ходит на ячейку 2": "0b6g-------------- schet=0",
...
"2 ход. 2 игрок 5-м предметом ходит на ячейку 9": "0b--------------9g schet=0",
}
В принципе можно оставить данные только 9-го уровня вложенности, необходимо будет только добавить инфу о порядке добавления предметов и иметь объект с одноуровневой вложенностью, но это не суть, все равно мы имеем дело с овербольшим объектом и суть вопроса в этом.
Допустим свойства не содержат никакой структуры и оверхеда на формат данных, ключи, вложенность и т.д..
И допустим они состоят из одного символа т.е. 1 байт.
Итого 4ккк байт = 4гб данных.
Так что никак при текущей постановке вопроса/задачи.
А в чем проблема 4гб данных? (По моим подсчетам для моего случая минимум 16 гб.) Если они будут храниться на сервере, там производится некоторые манипуляции с объектом и потом результат в виде пары однозначных чисел будет возвращаться к клиенту?
И не подскажите, этот большой объект весь (то есть 16 гб) необходимо загружать в оперативку для работы с ним или JS умеет работать с ним частями или он вообще может работать с данными с жесткого диска?
в вопросе это не указано, и вопрос выглядит как "как отдать клиенту овердофига данных да побыстрее".
И не подскажите, этот большой объект весь (то есть 16 гб) необходимо загружать в оперативку для работы с ним или JS умеет работать с ним частями или он вообще может работать с данными с жесткого диска?
смотря что за данные и что с ними всё-таки надо сделать, опять же в вопросе ничего про это нет.
Логично что надо скорее всего базу какую-то(вообще любую в целом) использовать и хранить данные там, и естественно не в оперативке. Но опять же зависит от того как их обрабатывать чтобы получить "пару однозначных чисел".
А в чем проблема 4гб данных?
В формулировке вопроса что это надо отдать пользователю в браузер как-будто.
бери Кассандру и храни данные там в виде: первичный ключ: [ключ: значение, ], где ключ - это путь до свойства в json, в роли первичного ключа может быть идентификатор объекта к которому относятся дальнейшие свойства. Кассандра это простыми словами двумерное key-value хранилище
Если вам надо передать с клиента на сервер 16 гб, то вы что-то делаете не так. Если вам надо выгружать в оперативку 16 гб, то вы тоже делаете что-то не так
Михаил, видимо опять не совсем ясно написал, под загрузкой объекта в бэкенд я имел ввиду не загрузку с клиента, а просто чтобы Node.js прочитала данные в виде объекта с бд или еще откуда-либо. Потом проводится определенные вычисления и клиенту отправляется пару цифр. По каким конкретно критериям загружается оперативка при загрузке такого большого количества данных мне не совсем ясно, но понял что если делать частями или потоково - то железо справляется. Сейчас примерно 1,6 гб данных обработались упрощенно (если я правильно посчитал) за 185 секунд. Я делаю не сайт, а игру, такие вычисления надо будет делать только один раз на конкретный набор игровых предметов, потом можно будет только читать данные. Пока такая медленная скорость меня устраивает, если все сработает, но в будущем хотелось бы побыстрее, но я понимаю что тут может быть зависимость от моей техники программирования, от выбора устройства ИИ, от выбора железа и языка программирования.
Вам писали, что у вас проблемы с архитектурой. Берите БД, читайте текстовый документ по кускам или что-то подобное. Держать в оперативке 16ГБ данных - это самоубийство. У меня на компе 8гб, на серваке - 512мб. А вы хотите сразу 16 данных в память залить. Не надо так
вопрос на уровне бреда. порывался заминусовать минут 5.
нода не рекомендуется никому для тяжелых вычислений, описанный в вопросе кейс пахнет дампом из какой-то бд, туда ему и дорога, jsonb (postgres) mongo elastic да что угодно, главное потоком этот файл читать и в бд разложить.... пытаться заюзать JSON.parse какой-то трешак....
Ну я еще изучаю программирование, поэтому в вопросе может быть ерунда, я не спорю, но этот сайт вроде как создан помогать изучающим и заминусовать тут в отличии от Хабра нельзя, только "пожаловаться". Изменил немного вопрос, можете ознакомиться.
Я не все понял из того, что вы написали. Как я понял читать JSON-файл по вашему не стоит, можете объяснить почему? Чтение потоком - это например это?
Js для такой структуры данных не подойдёт, js-объект - это ассоциативный массив, а не структура, жрать памяти будет больше в разы, можно попробовать загрузить данные в один объект ключ-значение, где ключ и значение - это строки, значение нужно парсить чтобы получить parent, либо использовать БД, подойдёт любая, нужно будет создать индекс по parent node, для анализа ситуации не более 10 запросов по 4 млрд. записей - партиции в помощь