Изучаю ноду. Восхитительный инструмент! И вот решил в целях самообразования сделать чат )) Не угорайте, его пишут все программисты )) Примерный функционал:
1. Регистрация, авторизация пользователей.
2. Общий чат, создание комнат, приватный чат.
3. Конечно роли: юзер, модератор и администратор.
4. Отдельная админпанель чата со статистикой.
5. Ну и всякие плюшки.
Хочется еще хранить историю сообщений, хотя бы последние 500 сообщений. И возник резонный вопрос: какую БД использовать? Писал на PHP и кроме MySQL ни с чем не работал. Сейчас установил Mongo на комп, ковыряюсь, читаю маны. Удобно, но мне кажется, не совсем она подходит для этого. Собственно смущает только как она справится с объемом данных. Она же хранит все в JSON? Так? Вот и прошу совета. Есть ли удобный инструмент для Node.js, чтобы работать с MySQL?
Собственно смущает только как она справится с объемом данных.
И вот решил в целях самообразования сделать чат
Что-то Вы темните )
А по сабжу - в целях самообразования возьмите монгу. Узнаете что это такое и как это работает. Для поставленной задачи она вполне подходит (как и все остальные СУБД, в принципе)
Alexander Litvinenko: "Чат в первую очередь сидит в кеше, как и по большей части все в ноде, потому больший потенциал показывает монга."
что? ) Что в ноде сидит по большей части в кеше? Причем здесь нода вообще до кеша? Вообще кеш для чата сомнительное мероприятие. Может все таки оперативная память? Ну тогда почти любая СУБД умеет "сидеть в кеше" и монго это делает не лучше всех.
А почему я посоветовал монго - просто запустить, просто работать, основная цель ТС - самообразование и нет смысла брать мускуль, так как ТС и так с ним работал до этого, а монго - немного другой подход, который поможет расширить знания.
Alexander Litvinenko: я конечно начинающий в node.js, но что там тех запросов? Ввел сообщение ->нажал Отправить->Сервер сохранил в БД и разослал всем подключенным. Или может хранить в памяти, а по достижении какого-то пика, например 500 сообщений, писать в БД? Вы бы как сделали?
Алексей Ярков:
зашёл навый юзер -> запросил 10 последних сообшщений -> запрос.
полистал историю чата -> запрос.
немного, но зачем усложнять, если с кешем код сделать еще и проще?
В бд можно писать асинхронно, разослали обновления, и тамже setimmediate обновление в бд
Alexander Litvinenko: само собой асинхронно! В этом же и прелесть ноды. Это я так, для примера. А никаких запросов истории я не планирую. Зашел юзер->Записали данные о нем в БД->отдали из памяти последние 500 сообщений ему на вывод->и дальше работаем. Как-то так я думаю. А не подскажете, есть ли возможность делать запросы в монго с параметом LIMIT, как в мускуле?
Alexander Litvinenko: Вы видимо собираетесь делать чат, в котором сообщения никто не пишет? Зашел пользователь полезли в кеш взяли 500 последних сообщений, а уже давно другие пользователи написал новые 500 сообщений. Все таки заход пользоателя происходит куда реже, чем написание сообщений. В итоге кеш Ваш будет постоянно инвалидироваться и вместо обычного запроса в базу по ключу (id комнаты) Вы будете лезть в кеш, смотреть, что там ничего нет, лезть в базу, выбирать оттуда все нужное, класть в кеш, отдавать пользователю + еще при написании осуществлять инвалидацию. Для чата в общем случае я вижу необходимость хранить только данные зарегистрированных пользователей, существующих комнат и последних сообщений (и то я бы лучше хранил их просто в памяти, не страшно, если при рестарте потеряются). Из всего этого кешировать имеет смысл только список комнат и то аккуратно, так как выдавать все миллион комнат из кеша ничуть не лучше, чем выдавать миллион комнат из базы (все таки кеш применяется не там где много, а там где тяжелые запросы). Поэтому комнаты надо будет кешировать постранично, а тут опять проблема инвалидации, так как может добавиться новая комната, к примеру. Если комнаты сортируются по количеству пользователей, то могут измениться места и т.п. Т.е. кеш в чате вообще ни к месту в принципе. Даже если будет 1000 комнат - их проще выбирать из базы, так как проблем этот запрос много не создаст, а с кешированием\инвалидацией намаетесь. А 1000 комнат это уже приличное значение для чата. Алексей Ярков да, можно. db.users.find().limit(3);
Алексей Ярков: имеется ввиду что вы отправляете запрос на сохранение и забываете о нем. Неважно когда он сохранит изменения в базе, главное что в кеше у вас актуальная информация.
Алексей Ярков: обратил внимание еще на вид запросов в ответах, это запросы с нативными драйверами монги, но само собой так не пишут часто, чаще используют mongoose или аналоги.
Alexander Litvinenko: "а про прочее, сами осмыслите что написали, похоже сами недавно разобрались, теперь блесчете умениями. "
Ну не сказать, что недавно, но разобрался, что и Вам советую. Проблема в том, что Вы уже второй раз рассказываете то, о чем не имеете представления (по крайней мере второй раз я Вас вижу за этим занятием). Сначала пытались рассказать, что основное применение java это фронтэнд, теперь рассказываете, что "Чат в первую очередь сидит в кеше, как и по большей части все в ноде". А ведь Вы судя по профилю преподаете людям навыки веб разработки за 5000 гривен насколько я понял.
Объясняю на пальцах. У вас 10 пользователей. Заходит первый пользователь. Получает 500 сообщений из базы, кладет их в кеш. пишет сообщение. Кеш инвалидировался. Заходит второй пользователь, делает запрос в базу, кладет результат в кеш. Пишет первому пользователю "Привет". Кеш снова инвалидировался. И так до бесконечности. Нормальная ситуация для чата - общаться. А каждое новое сообщение инвалидирует кеш. Т.е. созданым кешом практически никто не успеет воспользоваться и Вы постоянно будете делать лишние телодвижения.
Далее. Если перестать быть занудой, то можно притвориться, что Вы говорите о некой структуре в памяти процесса, в которую при создании процесса будут загружаться все данные из базы, а далее в базу будет идти только инсерт + данные в процессе будут изменяться на лету (тогда можно даже понять что Вы имели ввиду, когда говорили про то, что кеш в ноде реализуется базовыми средствами). Ок, действительно здесь это выглядит идеальной схемой. Но если Вы преподаете людям, то научитесь использовать верные термины, чтобы потом не появлялись программисты, которые будут говорить, что "нода по большей части сидит в кеше". Это называется не кеш, а оперативная память. Кешом можно назвать сами данные, которые Вы будете хранить в этой структуре, но это не меняет того факта, что предложение "нода по большей части сидит в кеше" попахивает непониманием сути и является лишь попыткой повторить где-то выхваченные, но до конца не понятые знания.
Alexander Litvinenko: "обратил внимание еще на вид запросов в ответах, это запросы с нативными драйверами монги, но само собой так не пишут часто, чаще используют mongoose или аналоги."
ну если Вас спросят как выбрать всех пользователей с возрастом более 20 лет из базы, то Вы наверняка напишите что-то типа SELECT * FROM user WHERE age > 20, а не User.object.filter(age_gt=20). Так почему Вы предлагаете мне писать ответ используя ODM? Я написал как этот запрос выглядит через cli монги. А ТС сам разберется как ему этот запрос использовать - переложить на ODM или пулять напрямую в монгу.
kazmiruk: с чего вдруг кешу инвалидироватса? добавляетса новая запись в масив, не более. Вот редактирование инвалидирует, и то невижу в этом проблемы, если конечно вы не сохранили туда имя пользователя вместо ид или что-то подобное, ведущее к масовым изменениям данных. И не путайте, кеш - это кеш, и неважно как он реализован.
Alexander Litvinenko: Да, кеш, это кеш. Но нода никак не сидит на кеше, так как термин кеш != термину оперативная память ) Поэтому тут 2 варианта - или Вы изначально неправильно употребили слово кеш, а сейчас отмазываетесь, или не понимаете вообще предметную область. Хотя ок, пусть будет по Вашем. В целом, чем больше людей Вы научите таким премудростям - тем более выгодно я буду смотреться на их фоне для работодателя.
kazmiruk: у HDD, например, встроенная оперативная память почему-то зовется кешем, и люди поопытнее нас с вами ее так почему-то назвали. Варианта как вы сказали два, Вы изначально неправильно употребили слово кеш, а сейчас отмазываетесь, или не понимаете вообще предметную область.
Alexander Litvinenko: если начать философствовать, то можно, конечно, сказать, что оперативная память это своего рода кеш. Но люди поопытнее нас с Вами все таки так ее не называют ) Т.е. если я захочу назвать оперативную память сосиской, то написав "чат и нода сидят по большей части на сосисках" вряд ли смогу называться профессионалом, пусть даже и приложив определенные усилия меня смогут понять окружающие.
ребят, всем спасибо! Разжевали все от и до ))) Остановлюсь на монго и заюзаю mongoose (погуглил, почитал, понравилось), а то собрался свой велосипед городить.
Alexander Litvinenko: нет не называют ) кеш - это некий буфер, который использует некие быстрые устройства чтения\записи. Ваш пример с HDD - там используют буфер для записи, куда пишутся данные, а затем, при накоплении эти данные сбрасываются уже на диск. Но никто не называет это оперативной памятью (если я неправ, то покажите ссылку, я честно попытался нагуглить, думал может отстал от жизни, но фраза "оперативная память жесткого диска" мне ничего не дала). Второе - данные процессов (чата, ноды и т.п.) живут все таки не в кеше, а в оперативной памяти. Да, если заняться философствованием, то можно сказать, что оперативная память это тоже своего рода кеш. Но тем не менее Вы мало того, что считаете себя специалистом, так еще и преподаете людям, поэтому нужно говорить правильно, а не как захочется. Ну и третье - от вопроса ТС мы уже давно ушли.
Если есть желание сразу привыкать к хорошему, я бы порекомендовал попробовать реализовать чат в кластере из нескольких процессов ноды.
Как фронт базу использовать redis как бэк база - монго - она лучше всего подходит для несвязанных данных (когда данные 1 запроса с клиента можно разместить в 1 документе монги), реляционки лучше себя показывают на сложных связях, которых у несложного чата нет.
Насчет редиса - смотрим publish/subscribe - для новых сообщений - по subscribe анные рассылаются ругим юзерам в комнате и дампятся в бэк базу
так же смотрим выборку по множеству ключей - для комнат
Не совсем понял зачем мне redis (не сталкивался, может поэтому). А вот кластеры тема интересная. Нашел статью: https://nodejs.org/api/cluster.html. Не подскажете как чат объединить с кластером воедино?
Алексей Ярков: нода - однопоточная среда, что бы использовать все ядра процессора используют кластеризацию на дочерних процессах.
Модуль cluster основаный на модуле child_process позволяет делать удобную кластеризацию для серверов, все процессы кластера будут слушать общие порты, а обработка запросов будет распределяться между ними. В офф доке есть примеры с http сервером, но сервер может быть любой (cluster патчит библиотеку net на базе которой работают любые сокеты в node)
Соответственно работать просто, из мастера запускаем воркеров, из воркеров слушаем нужный порт
А редис нужен для общения между процессами (прокидывание событий, хранение объектов, которые используются во всех воркерах и т.д.)