Pull to refresh

Comments 60

Вот вы обмолвились, что для этих целей подошел бы nosql. Но как же проблема с автоинкрементами? Ведь тут все на красивом id завязано. Хотел в последнем проекте использовать монго, но в связи с невозможностью грамотно генерировать иды, необходимые в приложении, пришлось отказаться
Имел дело с монго и кочем
В коче можно сделать через view+reduce. Собственно и сделал, но как только дошло до тестов дело… Оказалось, что он в 10 раз медленнее того же мускула. А в теории все эти статичные запросы выглядели так сладко
В монго такой финт уже не сделаешь
Есть два варианта. Первый — не брать за основу айди. Использовать, например, хеш от микровремени или еще чего-то

Второй вариант — в той же Монго хранить поле «lastId», которое вручную инкрементировать

Но на самом деле я не особый сторонник моды NoSQL и вполне радуюсь старенькой MySQL
1 — сделал парсер на ноде, все валит в один момент.
2 — тот же монго достаточно скоро потребует шариться, а безопасность атомарных операций там никто не гарантирует
В голове вертятся только гибриды
Автоинкремент в монго можно сделать так: links.freecr.ru/!bvc
Но можно еще подумать над сокращением ObjectId, которое выглядит так:

47cc67093475061e3d95369d

Но как его сокращать, оставляя уникальным — я хз. Мне в проекте это требовалось и я не допёр, но вместо этого я использовал собственную реализацию автоинкремента в монго.
Используем Redis и Keyspace в обоих случаях атомарный инкремент присутствует.
Redis выглядит заметно лучше, но все-равно советы сводятся к применению уникального идентификатора, то есть того же самого guid`a.
Можно, смотрите: links.freecr.ru/!bvc
Спасибо, очень полезно. Смотрю на такие вещи после питон+твистед очень положительно.
свои коллбэки обьявляя с err, можно в случае ошибок вложенного вызова просто вызывать callback с полученным err.

Использовать throw некорректно в асинхронной модели.
Ну, тут зависит от политики сервиса. Если проверять наличие, то это поиск в хранилище, что увеличивает время создания ссылки и уменьшает размер хранилища. А если не проверять, то ссылка создается быстро, но увеличивается хранилище ссылок.

Популярные укорачиватели такой проверки не делают.
пардрон, браузер тупит:
goo.gl, сабмитил 5 раз, результат habrahabr.ru/new/ -> goo.gl/QcLw
tinyurl.com, сабмитил 5 раз, результат habrahabr.ru/new/ -> tinyurl.com/4sbk7u
byst.ro, сабмитил 5 раз, результат habrahabr.ru/new/ -> byst.ro/3bwh

Уверен, что если еще проверить — большинство будет отдавать один урл… его проще 1 раз закешировать, чем каждый раз писать в базу.
я думал об этом, но. часто бывает, что человек хочет собрать статистику по переходам на урл. например, я в топике выкладываю ссылку и хочу узнать, сколько раз по ней перешли. но, возможно, имеет смысл брать уже готовые, да
Agree — cl.ly на каждый писк создает новую ссылку и персональную статистику по каждой.
а у меня goo.gl создаёт каждый раз новую ссылку
Да, действительно :-/

Я задавался этим вопросом несколько месяцев назад и политика создания урла была другая. Клянусь (с) =)
Немного не понял, а проверки на валидность url не предусмотрено?
Прикольно получается когда пустую форму отпрвляешь.
Я вот недавно тоже сел за ковыряние ноды, и, не поверите, тоже в голову пришло сделать сокращалку урлов :)
Вот мой вариант: sudn.tk. Исходники покажу по запросу, выкладывать их стыдно.
Там проверки тоже примитивные… yandex.ru и yandex.ru/ посчитает за разные урлы.

Да, делал на ExpressJS, в качестве хранилища редис, шаблонизатор ejs.
вы предлагаете перебирать всю базу, парсить её этим методом и сравнивать потом объекты?
Нет, сохранять хеш в базе. По нему же можно генерировать короткий ID.
Зачем? Храните сразу md5-хеши объектов.
UFO just landed and posted this here
Думаю что если сервис будет популярен, то будут частые обращения и любой ФС тут станет нехорошо.
Представьте себе 1к обращений в единицу времени. Это надо прочитать 1000 файлов, получается. Параллельно.
А параллельное чтение большого количества файлов — это либо дорого, либо практически нереально.
Да и наверное память и цпц нынче дешевле дискового пространства.

Я конечно могу ошибаться, ибо не сильно много понимаю в ФС и файловых операциях :)
А кстати да — как можно читать кучу файлов параллельно? Ну то есть тут, как я понимаю всё упирается в скорость чтения головки с хдд и в «раскиданность» файлов по ФС?
При достаточном количестве памяти ОС Linux будет держать кеш файлов в ОП и обращения будут сверх быстрыми. Есть только один подводный камень — fileatime, то есть последнее обращение к файлу. Но при монтировании файловых систем можно поставить noatime и избавиться от этого.
Как дело обстоит в Windows и для NTFS, не знаю.
UFO just landed and posted this here
Дело в опыте. Первые лет 5 всегда делаешь всё через MySQL. Уже потом начинаешь задумываться.
ещё два подводных камня:
1) ограничение на суммарное количество файлов в файловой системе (вернее, inodes);
2) резкое снижение производительности при большом числе файлов в одном каталоге (но это легко решаемо).
а зачем? по-моему бред и вот почему: сегодня я использую фс, завтра, когда потребности проекта возрастут, буду писать велосипед того, как бы это все красиво заоптимизировать, а послезавтра, когда захочется переехать в облако пойму, что где-то в проектировании системы был прокол. почему бы сразу не использовать бд, которая как раз для этого и создана? не обязательно реляционную, для такого проекта сгодится простенькая key-value бд вроде редис. а чтобы начать работать с ней, нужно меньше времени, чем потом бороться с граблями файловой системы. скажите я не прав?
смысл? если я захочу расширить приложение — я смогу это с легкостью сделать. работа с базой тоже будет безумно быстрой в этом приложении.
тем более, я уже сказал, что можно было бы использовать НоуСКЛ, но целью было именно научится работать с MySQL
Забавно использовать для серверной части MooTools, а для клиентской — jQuery.
Хотя классы там удобные — это факт, а как с этим в jQuery, я не знаю. И как у jq с node.js
jQuery прекрасно работает в приложениях node.js с использованием jsdom.
для операций с DOM jquery — лучший. Но на сервере он — не очень. Имхо
Иногда полезен, при операциях с деревом, и для идентичности кода.
А по-моему, и mootools для этого нисколько не хуже. Странно, что вы решили серверную часть писать с использованием mootools, а на клиенте — jquery.
я не могу отдать предпочтение определенному фреймворку. наверное, ДОМ мне нравится больше в JQuery. Хотя многие вещи мне больше нравятся в MooTools. Они разные на самом деле
jQuery больше для дизайнеров, как мне кажется,
в то время как mootools больше для разработчиков
Спасибо за статью, красивый код и доступное описание.

Небольшое дополнения: String.sqlEscape можно было не реализовывать, ведь есть conn.escapeSync(). Потери производительности будут минимальны, но зато точно не забудете заэкранировать что-нибудь, а вы явно забыли \n, \r и т.д. Впрочем, для INSERT уже можно использовать prepared statements.
поприветствуем автора mysql-libmysqlclient)
спасибо, conn.escapeSync() — это то, что нужно.
ждем подробных мануалов, что и как использовать)
Да, похоже прежде всего нужно допилить Dox для генерации постраничной документации, а то в едином списке в api.html трудно ориентироваться.
Поддерживать документацию вручную для одного разработчика довольно хлопотное занятие. Но пример с INSERT и экранированием в срочном порядке добавлю в examples.js, моё упущение.
ок. Оказывается не работает нажатие на «enter» после того как вставил урл.
Сервис не развивается, прибыль не приносит и вообще не работает. В общей сложности было сокращенно около 20000 ссылок за первые дни. Нагрузка — близка к нулю, отработал прекрасно.
Почему дальше не разивали? не видели смысла или другими проектами заняты?
Не видел смысла, есть куча других проектов. Сокращалок — много, сомневаюсь, что смогу дать что-то особенное.
Хотя, если кто-то станет успешным с кодом, описанным в статье — я буду рад.
if (err) throw err;

А что будет, если таки произойдет ошибка? Не упадет ли весь сервер?
Может правильнее дальше передавать:
if (err) fn(err);
?
Sign up to leave a comment.

Articles