Как стать автором
Обновить
32
@Pyrusread⁠-⁠only

Пользователь

Отправить сообщение

Привет! Как раз написали об опыте с JetStream:

https://habr.com/ru/post/700058/

Я бы сказал, что во-вторых, программист откладывает проблему управлением памятью на неопределенный срок. И во многих проектах (большинстве) этот срок никогда не наступает. :)
В статье описан результат работы почти двух месяцев неполной занятости. Это итеративный процесс: замер, исправление, деплой, повторный замер. Пока ждем деплоя и результатов замера, занимаемся другими задачами.
Возможно, с ArrayPool-ом правильнее, но сложнее:
1) Поверх ArrayPool все равно придется писать реализацию List и HashSet.
2) Добавляется ручное управление временем жизни: массивы, полученные из ArrayPool-а, надо возвращать обратно.
Я слышал, что кто-то именно так и делал. Можно подписаться на событие сборщика мусора, которое он кидает незадолго до сборки: https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/notifications. По этому событию сервер посылает сообщение балансировщику нагрузки, и тот временно перестает распределять запросы на этот сервер. Но это экзотика, редко используется.
Спасибо! Рады, что статья оказалась полезной. Про режимы мы написали в другом комментарии.
Мы сравнивали режимы работы сборщика мусора GCLatencyMode.Interactive и GCLatencyMode.SustainedLowLatency. На замерах разница в поведении вызывалась многими факторами, например количеством запросов, объемом памяти, уже используемым приложением. На фоне этих различий влияние режима не заметно.
Если же обратиться к документации (https://docs.microsoft.com/en-us/dotnet/api/system.runtime.gclatencymode?view=netframework-4.8), то отличие SustainedLowLatency в том, что он старается не выполнять блокирующую сборку 2-го поколения. Наши замеры показывают, что в веб-сервисах Pyrus происходят только фоновые сборки мусора, а следовательно, режим SustainedLowLatency не должен дать никаких изменений.
Вот так у нас практика сходится с теорией.
По поводу публикации «кусочных» коллекций — мы над этим думаем. Если есть интерес, то почему бы и нет.
Уф, давно это было. Если получится поднять логи, вспомнить, опубликуем отдельным постом.
Они не предоставляют сервис во всех странах, где нам нужно хранить персональные данные (например, в России). Кроме того, есть риск зависимости от одного облачного поставщика.

Когда мы используем какие-то сервисы от Amazon/Azure/Google/Yandex/Mail.ru, то всегда смотрим, что сможем найти аналогичные по приемлемым ценам от других облачных провайдеров. В случае DynamoDB это была бы слишком сильная привязка к Amazon.
Не совсем так. В статье идет речь о том, что если во время выполнения длительного запроса документы уже отфильтрованные по индексу меняют свои значения, то они могут не попасть в конечную выборку, хотя формально все время удовлетворяли условиям отбора (и до, и после изменений).

А именно, допустим у вас есть коллекция документов с атрибутами (Name, Country, City) и индекс по полям (Country, City). Вы выполняете запрос people.find({country: «France»}), который использует индекс и выдает 1000 документов. Если вы в параллельной транзакции меняете одну запись таким образом, что она и до, и после изменений подпадает под условия поиска (поле Country равно ‘France’ и не изменяется), но ее позиция в индексе сдвигается (поле City изменяется):

(Anna, France, Paris) —> (Anna, France, Bordeaux)

то возможна ситуация (race condition), когда в результатах запроса вы эту запись не увидите. То есть вы получите 999 документов вместо 1000.

Обратите внимание, и старый, и новый документ удовлетворяли условиям поиска, но запрос не вернул ни один из них!

Это классический пример phantom read, и совсем неинтуитивное поведение. В других БД при высоком уровне изоляции (Serializable) или в системах MVCC такое поведение невозможно.

Вот человек пишет, что воспроизвел это на Wired Tiger 3.2:

medium.com/@alex_65399/ah-we-were-able-to-replicate-it-on-wired-tiger-3-2-5fb18cc5bc45

Монга родилась как cAP. Тут «неожиданно» выясняется — оказывается acid ( C) в монге не совсем acid. В монге не совсем acid не потому что разработчики монги не знают что такое acid, или не могут его правильно реализовать, а потому что за acid ( C) нужно платить.

Понятно, спасибо.

А раз так, то зачем продукт который cAP, вдруг начинает работать как CaP, или CAp?

Они раскрутили cAP-продукт, но рынок показал, что «С», оказывается, не менее важно. Предполагаю, что руководство Монги говорит разработчикам: «клиенты жалуются на потери данных, надо что-то делать». Разработчики пытаются сделать, чтобы данные терялись чуть реже, не переписывая БД с нуля. Платить за полноценный «С» (разработчики — временем, бизнес — деньгами) никто не хочет.
Неясно, о каком именно продукте вы говорите.

На практике большую часть времени сеть надежна (нет Partition), и тогда практически любая система согласована и доступна (Consistent + Available).

CAP-теорема говорит только о ситуации сетевых сбоев. В присутствии Partition любая БД, которая заявляет ACID-свойства, должна выбирать Consistency (иными словами быть СP, жертвуя A). Однако, в CAP-теореме A понимается слишком жестко — а именно «все ноды доступны 100% времени». В реальной жизни такое требование избыточно. Ноды могут быть недоступны какое-то минимальное время, если пользователи этого не успевают заметить. Это формализуется термином HA (High Availability) и обычно измеряется числом девяток, например «4 девятки» означает «все ноды доступны 99,99% времени».

Короче говоря, HA!=A и CAP-теорема не запрещает CP-систем, которые не A, но HA.

Вот, собственно, рассуждения по теме автора оригинальной CAP-гипотезы (доказали его как теорему другие):

static.googleusercontent.com/media/research.google.com/en//pubs/archive/45855.pdf
У нас все операции критичны к transaction delay. Среднее время ответа application server — 250мс. И мы планомерно снижаем его.
Спасибо за замечание. В одном посте невозможно описать все возможные use cases.
Увы, нет. Автор поста по второй ссылке тоже так думал и перепроверил у знакомого разработчика MongoDB. А тот ответил, что с WiredTiger поведение не изменилось:

Reads may miss matching documents that are updated during the course of the read operation.
When I originally looked at the concurrency documentation, this sentence said it only applied to the older MMAPv1 storage engine. We started looking into upgrading our databases to use the newer WiredTiger engine, and pinged a friendly MongoDB engineer to double-check that we understood the issue and that upgrading would fix it. Sadly, his response was to fix the docs to say that this behavior is expected with WiredTiger as well. Ah well.
Да, но их multi-document transacations пока не поддерживают Sharded Clusters, только Replica Sets. И (по слухам) заметно снижают производительность. Они появились совсем недавно, должно пройти время пока им начнут доверять. Слишком много у народа было проблем из-за их отсутствия:

news.ycombinator.com/item?id=18366385

Или вот чувак описывает, что MongoDB в силу специфического дизайна операции update (она неатомарна и выполняется как delete и insert) иногда не возвращает соответствующие запросу документы, хотя в базе они есть:

blog.meteor.com/mongodb-queries-dont-always-return-all-matching-documents-654b6594a827

А так — MongoDB не стоит на месте, развивается.
Я читаю документацию здесь:

https://developer.android.com/guide/components/loaders
Loaders have been deprecated as of Android P (API 28). The recommended option for dealing with loading data while handling the Activity and Fragment lifecycles is to use a combination of ViewModels and LiveData.

Можно, конечно, продолжать использовать через SupportLibrary. Но поставщик платформы явно рекомендует использовать другие механизмы. Опыт подсказывает, что если не следовать таким рекомендациям, то поведение приложения с каждой новой версией API будет становиться менее предсказуемым.
Перед нами стояла задача показать в одной галерее файлы разных типов: и картинки, и видео, и документы. Проблема не в RecycleView, а в компоненте WebView, который не умеет показывать офисные файлы.
Спасибо за ваш комментарий.

Вы пишете, что механизмов асинхронной работы еще больше. Это делает восприятие еще более сложным. Loader, кстати, будет deprecated, начиная со следующей версии API (28). Непонятно, почему AsyncTask до сих пор не deprecated, ведь он явно входит в противоречие с идеей пересоздания всех компонентов интерфейса при повороте. Любая ссылка, запомненная в объекте AsyncTask, будет нерабочей после окончания асинхронной задачи, если пользователь повернул экран во время ее выполнения.

Понятно, что архитекторы Android каждый свой выбор на чем-то основывали. И документация, конечно, опишет, какие компоненты и как использовать, чтобы получить требуемое вам поведение. Мы в большей степени акцентируем внимание на том, что некоторые архитектурные решения Android сомнительны, и в других ОС сделано по другому и в чем-то проще.

В хорошей архитектуре сама структура кода API подсказывает разработчикам как использовать платформу, а документация лишь дополняет ее. В Android же доверять интуиции не стоит, нужно всегда читать документацию. Например, идея, что Service обрабатывает события в том же потоке, а наследник от него IntentService создает отдельный поток, совершенно контринтуитивна.

Про «холодный старт» — в том-то и дело, что Android претендует на то, что в отличие от десктопа, ваше приложение, если написано правильно, вообще не заметит, как его выкидывали из памяти и потом рестартовали. А на самом деле технология не срабатывает, как только приложению нужна инициализация с подогреванием кешей.

Что касается просмотра файлов — в iOS аналог WebView приемлемо показывает документы Word/Excel/PDF. В Excel-документе можно даже переключаться между листами. В Android это не так.

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность