|
|
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
В базе данных MS SqlServer есть таблица с товарами и таблица с ценами и количеством к этим товарам. В первой таблице ~ 200 тыс. записей, во второй в 3 раза больше (цен на один товар может быть несколько). Обе таблицы постоянно обновляются (но в основном цены и количество). Задача - выводить товары всегда с актуальными ценами и количеством. Варианты 1. Писать товары в кеш и обновлять с помощью SqlDependency только те, что изменились. Зависимость изменений кеша устанавливать на каждый товар. При изменении товара, цены или количества писать ModifiedDate и на это поле 'вешать' SqlDependency. С чем столкнулись: при старте приложения или обновления кеша создается большое количество локов, так как в запросе SqlDependency нельзя использовать NOLOCK, а SqlDependency приходится добавлять на каждый из 200 тыс. товаров. 2. Писать товары в кеш и обновлять с помощью SqlDependency весь кеш. Зависимость изменений кеша устанавливать на любое изменение товара, цен, количества. Минусы - при любом изменени приходится перечитывать весь товарный кеш. Если изменений много, то это т процесс будет длится постоянно. 3. Отказаться от кеша и читать напрямую из базы. По тестам такой вариант сильной тормозит, так пользователей ~ 1000 одновременно. Запрос - обычный Select Good From Goods (NOLOCK) WHERE GoodId=@GoodId. Цены и количество читаются вторым сетом. Тоже обычный Select Какие варианты еще можно использовать? Или может оптимизировать те, которые я указал? И еще один вопрос в догонку. Так как таблица с ценами и количестов постоянно обновляется и перезаписывается возникает проблема с локами. Как правильно организовать схему обновления - чтения данных, чтобы минимизировать локи? Может у кого есть ссылка на пример организации высоконагруженных приложений похожий на ту, что я описал? Заранее всем спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 17:11 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
1. SqlDependency вроде бы дает факт, что в таблице есть изменения, смысл вешать на каждую запись? Если вешать на каждую из 200 тыщ записей, то надо представлять как это работает, брокерские очереди и пр. сервер загнется... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 17:43 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
rudevelop, Тысяча пользователей, которые одновременно исполняют этот запрос? Не смешите людей. У Вас, скорее всего, вообще и тысячи посетителей не наберётся. Впрочем, отвечу. У меня к таблице с миллионом записей и не меньше десятка приджойненых таблиц запрпос (одновременно 1024 запросов) выполняется меньше, чем за секунду. И это - не суперкомпьютер. Тестировал на своём собственном, самом обыкновенном. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 17:43 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
Winnipuh1. SqlDependency вроде бы дает факт, что в таблице есть изменения, смысл вешать на каждую запись? В этом случае придется обновлять кеш на все товары, а хотелось бы только на тот товар, который изменился. ShSergeТысяча пользователей, которые одновременно исполняют этот запрос? Не смешите людей. Откуда такой скепсис? Сайт - это интернет магазин. Все страницы сайта - это страницы с товаром. Каждый пользователь на сайте смотрит либо карточку товара либо каталог с товарами. Соответственно, если посетителей в данный момент несколько тысяч, то запрос выполняется ~ 1000 раз. ShSergeУ меня к таблице с миллионом записей и не меньше десятка приджойненых таблиц запрпос выполняется меньше, чем за секунду. Запрос выполняется тоже меншье чем за секунду, но связка mssql - mvc дает дополнительное время. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 18:01 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
rudevelopВ первой таблице ~ 200 тыс. записей, во второй в 3 раза больше (цен на один товар может быть несколько). Обе таблицы постоянно обновляются (но в основном цены и количество). Объем реально небольшой. Даже маленький, сказал бы. Вот самый минимум требований: 1. Никаких кешей товаров и цен и пересинхронизаций (сиквел зависимости, по таймеру и иже). Только прямые запросы по факту. 2. Смотрите в сторону оптимизации запросов. 3. Пересмотрите планы выполнения основных запросов. 4. Добавьте индексы, в т.ч. реально мощные INCLUDE-индексы. Тут важно учитывать самые частые запросы. Например, вот индекс по двум полям с инклюдом третьего поля: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 5. Еще раз - индексам уделите самое пристальное внимание . 6. Пересмотрите UI и то, как Вы выдаете результаты (пейджинги, фильтры, сложные вычисления средствами сервера приложений, и т.д.). Например, если рассматривать пейджинг грида, не нужно делать второй Count-запрос, это слишком трудозатратно. Достаточно иметь в пейджере текущий индекс и кнопку "Далее". 7. Максимально упростите UI, выкиньте сложные фильтры. Тянуть с SQL сервера данные только те, которые действительно нужны. 8. Анализировать локи, если имеются. Корень зла - тот самый пагубный неоптимальный запрос без индексов. 9. Если бы данных действительно было бы много, без ETL пересчетов не обойтись. Но, это не Ваш случай, уверен. Скорее всего зло кроется в плохо спроектированном UI, в неоптмимальных запросах и в отсутствии индексов. ShSergerudevelop, Тысяча пользователей, которые одновременно исполняют этот запрос? Не смешите людей. Вас, скорее всего, вообще и тысячи посетителей не наберётся. Откуда такая уверенность? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 18:06 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
rudevelopВ базе данных MS SqlServer есть таблица с товарами и таблица с ценами и количеством к этим товарам. В первой таблице ~ 200 тыс. записей, во второй в 3 раза больше (цен на один товар может быть несколько). Обе таблицы постоянно обновляются (но в основном цены и количество). ... 3. Отказаться от кеша и читать напрямую из базы. По тестам такой вариант сильной тормозит, так пользователей ~ 1000 одновременно. Запрос - обычный Select Good From Goods (NOLOCK) WHERE GoodId=@GoodId. Цены и количество читаются вторым сетом. Тоже обычный Select Данных не много При наличии индекса подобный запрос вообще на лету должен отдавать данные Как и советовали - думайте в сторону оптимизации запросов, проводите профайлинг, стройте индексы под запросы Кешировать то что ~"постоянно обновляется" не вижу особого смысла Также немного оффтоповый вопрос - зачем количество обновлять каждый раз? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 18:34 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
SanSYS Также немного оффтоповый вопрос - зачем количество обновлять каждый раз? Сайт - это интернет магазин. Товар продается, количество меняется. Обновлять нужно, чтобы купить товар можно было не более чем N штук. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 18:40 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
МСУ...Откуда такая уверенность? Обычное дело. Меня, в своё время, интересовал вопрос про сканирование акцизных марок на алкогольную продукцию. Позже тема закрылась. Ну и представь себе, что все покупатели одновременно просканировали свои марки. Ерунда! Даже на обыкновенном компьютере прокатит. Я уже не говорю про супер-пупер-навороченный сервер. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 18:43 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
rudevelopSanSYS Также немного оффтоповый вопрос - зачем количество обновлять каждый раз? Сайт - это интернет магазин. Товар продается, количество меняется. Обновлять нужно, чтобы купить товар можно было не более чем N штук. Хм.. так ли это нужно? Может кол-во стоит всегда "подсчитывать"? Если подсчет окажется быстрее обновления, то получится минус одна первопричина предположительных тормозов ("постоянно обновляются ... в основном цены и количество") ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 18:51 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
И кстати, цены обновлять не совсем правильно Нужно, если можно выразиться, вести прям лог цен, где последняя по дате цена будет актуальной, имхо А то получится - придет манагер, скажет, что была продажа моника за $500, а он стоит $510, придется лезть в бекапы, чтобы сверится ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 18:59 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
rudevelopSanSYS Также немного оффтоповый вопрос - зачем количество обновлять каждый раз? Сайт - это интернет магазин. Товар продается, количество меняется. Обновлять нужно, чтобы купить товар можно было не более чем N штук. Не вижу никаких преткновений найти цену товара из референсной таблички ( по индексированному полю GoodId ) и произвести изменение. Откуда тут тормоза и, тем более, блокировки? ShSergeМеня, в своё время, интересовал вопрос про сканирование ... Не уходите от вопроса. ShSergeМСУ...Откуда такая уверенность? Обычное дело. "Аргумент" не засчитывается. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 19:00 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
SanSYSИ кстати, цены обновлять не совсем правильно Нужно, если можно выразиться, вести прям лог цен, где последняя по дате цена будет актуальной, имхо А то получится - придет манагер, скажет, что была продажа моника за $500, а он стоит $510, придется лезть в бекапы, чтобы сверится Чушь не мелите. Как это цены обновлять не правильно? Присядьте, сегодня двойка. Цены - обычная референсная сущность товаров. Всегда можно поднять любую цену за конкретную дату + кто оценивал, как оценивал, какие скидки были на тот момент, и пр. У автора всё правильно сделано. Продажа и Покупка - вообще отдельные сущности (сущность, в разрезе типа операции). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 19:05 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
МСУЦены - обычная референсная сущность товаров. Всегда можно поднять любую цену за конкретную дату + кто оценивал, как оценивал, какие скидки были на тот момент, и пр. Именно так все и верно, я имел ввиду, если непосредственно в таблице товаров есть поле цена хранящее значение (а не ссылку), то ее обновлять неверно, не боле ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 21:28 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
Цена товара переносится в заказ в момент его оформления (смотрим Order Details). Дальше цена обновляется при необходимости (смотрим Order Details). Как-бы классика жанра (смотрим Northwind database). SanSYSМСУЦены - обычная референсная сущность товаров. Всегда можно поднять любую цену за конкретную дату + кто оценивал, как оценивал, какие скидки были на тот момент, и пр. Именно так все и верно, я имел ввиду, если непосредственно в таблице товаров есть поле цена хранящее значение (а не ссылку), то ее обновлять неверно, не боле ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 21:39 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
Оптимизация запросов Кеш неизменяемых частоиспользуемых данных Декомпозиция сущностей БД (в частности про цены), при чем ничего не удалять/обновлять, т.к. речь идет о финансах Рекомендую ASP.NET MVC оптимизация & mssql оптимизация производительности т.к. тема избита и на форумах конкретных решений не получишь, т.к. к каждой систему подход уникален ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 21:42 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
Relic HunterЦена товара переносится в заказ в момент его оформления (смотрим Order Details). Дальше цена обновляется при необходимости (смотрим Order Details). Как-бы классика жанра (смотрим Northwind database). SanSYSпропущено... Именно так все и верно, я имел ввиду, если непосредственно в таблице товаров есть поле цена хранящее значение (а не ссылку), то ее обновлять неверно, не боле Не совсем верно, в Order Details нужно также хранить ссылку на цену, как писали выше в отношении товаров ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 21:45 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
SanSYSИменно так все и верно, я имел ввиду, если непосредственно в таблице товаров есть поле цена хранящее значение (а не ссылку), то ее обновлять неверно, не боле Можно и так, но тогда цены нужно протаскивать по всем документам, что не есть гуд. И не понятно будет, почему за одну и ту же дату/время одному клиенту отпустили товар по одной цене, другому - по другой (нужно будет и кучу признаков протаскивать). А дело всё было в скидках, к примеру. Либо в определенной ценовой политике (например, некоторые магазины имеют n-уровневую систему цен, например, в том же юлмарте (не примите за рекламу) 3 цены у товара - справа вверху). Стандартная практика. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 21:46 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
Relic HunterЦена товара переносится в заказ в момент его оформления Для прозрачной торговли и самых простых интернет магазинов - прокатит. Для более сложного ценообразования и постоянной динамикой - увы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 21:49 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
GulagНе совсем верно, в Order Details нужно также хранить ссылку на цену, как писали выше в отношении товаровOrder Details содержит ссылку на продукт ProductID и цену, по которой он был отгружен. Сама цена Procuts->UnitPrice может менятся. Поэтому приходится денормализовывать. Классика. Order Details - это финальный документ, который не может быть изменен через ссылку на значение ни при каких условиях. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 21:51 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
Relic Hunter, о какой "классике" Вы говорите? :) Это простейшая учебная база данных и никакого отношения с жизненными реалиями она не имеет. Тем более Northwind, которая является очень устаревшей, которая шла еще в поставке с 2000 скулем. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 21:55 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
МСУЭто простейшая учебная база данных и никакого отношения с жизненными реалиями она не имеет.Почему не имеющая? Вы думаете на заправке хранят все цены на бензин, которые могут менятся сто раз в день? Кому это надо? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 21:59 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
Relic HunterПочему не имеющая? Вы думаете на заправке хранят все цены на бензин, которые могут менятся сто раз в день? Кому это надо? 1. Да, представьте себе - цены на топливо / акции меняются чаще всего остального. В точку. 2. Когда я выше приводил примеры с n-уровневым ценообразованием, скидками, бонусами и т.д. - я со стенкой дискутировал? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 22:06 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
Relic HunterКому это надо? Бизнесу. Аналитики составляют красивые графики, правительство мониторит динамику, оппозиция ругает правительство за такую динамику. Ух, кипит целая жизнь с этими ценами :) Вы можете дернуть сервис http://www.cbr.ru/dailyinfowebserv/dailyinfo.asmx за любую древнюю дату и удивиться, даже курсы валют хранят длительное время. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 22:10 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
Relic Hunter, большие дяди в большом бизнесе больше всего любят красивыве графики с умными цифрами, финансовые отчеты за периоды. Как будете строить статистику в разрезе цен, по сотням миллионов отпущенных накладных? Проще убить себя из револьвера ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 22:14 |
|
||
|
Как правильно реализовать высоконагруженное веб-приложение?
|
|||
|---|---|---|---|
|
#18+
МСУRelic HunterКому это надо? Бизнесу. Аналитики составляют красивые графики, правительство мониторит динамику, оппозиция ругает правительство за такую динамику. Ух, кипит целая жизнь с этими ценами :) Вы можете дернуть сервис http://www.cbr.ru/dailyinfowebserv/dailyinfo.asmx за любую древнюю дату и удивиться, даже курсы валют хранят длительное время.Вот, начинаем приходить к минимальному пониманию)) Интернет-магазину оно нафик не сдалось. А для аналитики грузите ежедневные снимки в DWH. Будут им и графики и диаграммы Гауса. Просто не нужно смешивать (большинство так и делает) OLTP и DWH в одном флаконе и наделять магазин не свойственными ему функциями. От этого страдает и OLTP и DWH в конечном итоге. Нет? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.03.2012, 22:39 |
|
||
|
|

start [/forum/topic.php?fid=18&msg=37705606&tid=1359813]: |
0ms |
get settings: |
4ms |
get forum list: |
10ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
170ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
57ms |
get tp. blocked users: |
1ms |
| others: | 188ms |
| total: | 447ms |

| 0 / 0 |
