Стас Выщепан @gandjustas
Умею оптимизировать программы
Information
- Rating
- 269-th
- Location
- Москва, Москва и Московская обл., Россия
- Date of birth
- Registered
- Activity
Specialization
Software Architect, Delivery Manager
Lead
C#
.NET Core
Entity Framework
ASP.Net
Database
High-loaded systems
Designing application architecture
Git
PostgreSQL
Docker
1) Скорость записей упирается в диски. Хотя я даже на обычном SQL Server делал 10к записей в секунду пачками по 5к в транзакции. Уровень надежности не ниже записи в любую nosql базу.
2) Рекомендации не пересчитывают на каждое событие ибо это очень дорогая операция, которая далеко не в скорость записи упирается. А влияние одного события на рекомендации ничтожное. Я делал системы рекомендаций и прекрасно знаю как они работают.
3) В принципе существуют системы для онлайн пересчета аналитики по событиям, им необязательно писать каждое событие на диск.
4) По поводу ebay не знаю, возможно при их объемах и нагрузке Cassandra помогает. Но далеко не каждый проект вырастает до масштабов ebay, а nosql на старте проекта только мешает. Из за отсутствия гарантий приходится или сильно больше кода писать, или мириться с багами.
5) Использование NoSQL, там где прекрасно справится РСУБД, очень напоминает предварительную оптимизацию, которая, как известно, зло. Причем, как ни странно, NoSQL требует больше ресурсов (много памяти и несколько серверов), по сравнению с какойнить бесплатной РСУБД.
Я знаю что есть типовые сценарии, для которых NoSQL работает лучше РСУБД. Но я бы не брался 100% утверждать на старте проекта, что именно такой сценарий будет в приложении
А как будет?
Для этого уже давно есть материализованные\индексированные представления. В SQL Server появились updateable columnstore индексы. А для больших объемов также давно есть OLAP системы.
Представил, а в чем проблема? Рекомендации ведь не будут на каждый клик пересчитываться, иначе мощностей никаких не хватит. А писать клики в permanent inconsistent (eventual consistent) базу или в обычную с ACID гарантиями — разницы нет, а можно вообще сохранять на локальном диске веб-сервера, а потом прогонять через механизм расчета рекомендаций.
По сути нет ни одного сценария, где eventual consistent было бы выгоднее, чем strong consistent.
Почему утрирован? Нормальный вполне пример, подобные системы в кинотеатрах и на вокзалах стоят.
Для чтения мастер не нужен, а для записи нужен. У multimaster в общем случае возникают проблемы с consistency, когда параллельно две транзакции в разные мастеры пишут по одним и тем же ключам.
Считать можно вообще что угодно. Но смысла в этом обычно нет. Strong consistency это гарантия для приложения, eventual consistency это просто слова, которые ничего не дают приложению.
На примере той же продажи билетов. Если есть eventual consistency в 10 секунд, то как это поможет не продать более одного билета на одно место?
Если eventual consistency имеет такое маленькое значение, что в реальности наблюдатель никогда не увидит кластер в неконсистентном состоянии, то в чем разница со strong consistency? Да и стоить это будет одинаково.
Банальная ситуация — сервис по продаже билетов в кино, на одну ноду приходит команда, которая бронирует билет и тут рвется связь. Вторая нода не знает что билет забронирован, тут приложение обращается ко второй ноде и пытается забронировать тот же билет.
Тут два варианта:
1) если билет таки удастся забронировать, то после восстановления связи будет две брони на одно место.
2) не писать пока нет связи с мастером, то ест сервис в одной из частей не доступен.
Даже если система ждет ответа е от всех нод, а от подмножества, то сеть может поделиться по границе подмножества. Короче честный partition tolerance без strong consistency сделать нельзя.
Это приводит к неутешительному выводу: для честного partition tolerance нужно иметь мастер-ноду, куда будет приходить вся запись, а также синхронный коммит, чтобы в случае падения мастера можно было переключиться на другу ноду (сделать её мастером). Понятно что падение мастера синхронно отследить не удастся, поэтому любая реальная система может быть только CP.
Кстати если почитать обсуждения cap теоремы, то для устранения этого «бага» понятие consistency поменяли, и оно больше похоже на atomicity в ACID.
Но не все так плохо. Если consistency и partition tolerance это бинарные понятия. Они или есть или нет. То availability это непрерывная величина между 0 и 1, причем существует она не сама по себе, а еще и зависит от инфраструктуры. Предположим что мы смогли инфраструктурно добиться доступности серверов бд в 99,99% и время на продвижение нового мастера менее 1 секунды. Это значит что приложение может просто повторять попытки записи в базу в течение и для пользователя система будет доступна на те же 99,99%.причем это легко делается на sql server.
1) Если частота записей больше, чем время, которое необходимо до получения консистентного состояния в кластере, то eventually consistent превращается в permanently inconsistent.
2) eventually consistent не дает абсолютно никаких гарантий, в отличие от strong consistency.
1) Сложность написания. То есть количество времени для получения конкретного результата. Самый незначимый вид сложности, хотя дающий максимальный эмоциональный эффект.
2) Сложность чтения. То есть сколько времени нужно потратить чтобы восстановить мысль автора по коду. Так как код читается гораздо больше чем пишется, то это самый значимый вид сложности.
3) Сложность понимания как оно работает. То есть сколько времени нужно потратить до того чтобы понять как код работает. Эта сложность вызывает больше всего холиваров.
Так вот язык C и Java имеют среднюю сложность написания и понимания и низкую сложность чтения.
А большинство ФЯ снижают сложность написания и повышают сложность понимания и чтения.
Это неверно в общем случае. Запрос в базе оптимизируется в первую очередь на чтение. Это значит что имея правильный индекс база данных не будет считывать всю таблицу, а только ту часть индекса, который поможет вернуть значение.
Далее если у тебя запрос получился сложным и реально требует много вычислений на процессоре, то почти всегда выгоднее его выполнять в базе, ибо прокачать весь объем данных между базой и приложением получится долго.
Только в двух случаях такое «варьирование нагрузки» помогает:
1) Логика невыразима в терминах TSQL, например рекурсии или moving average
2) База очень маленькая (до 1ГБ), тогда выгоднее всосать все в память приложения и использовать навигационный доступ между объектами.
А нельзя было написать функцию (inline TVF) в sql и дергать её из контекста с материализацией?
О чем статья вообще?
не читайте до обеда советских газет
Пример будет интересен, только пожалуйста без экзотики.
:) Откуда такая уверенность?
Запустил LoadTest, 500 запросов в секунду, ошибок нет. Так что нет проблем у EF и ASP.NET (в том числе MVC и WebAPI), по крайней мере тех, о которых вы думаете.
Ты думаешь что для такого кейса не запилили бы стабильную реализацию?
Естественно работает без ошибок.