Спасибо за статью! Материал годный, но хотелось бы больше примеров из практики, особенно интересны метастабильные состояния.
Этот паттерн обычно используют взамен классической стратегии простых повторов (Retry) запроса в случае неуспеха, ставшей антипаттерном.
Мне кажется тут авторы подборки антипаттернов либо не знакомы со всеми паттернами либо лукавят. А как же retry with exponential backoff?
В 99.9% случаем он работает прекрасно. В моей практике был только один случай когда circuit breaker мог бы быть лучше exponential backoff (но это не точно). И проблема даже не в самом exponential backoff, а в его классической реализации - полностью аннулировать накопившийся backoff на первый успешный ответ (что в результате может убивать систему периодически, волнами). Если бы backoff откатывался плавно, то проблем бы не было.
Circuit breaker хорош там где ответы не "подвисают", а где клиент не понимает ответа и отсылает новый запрос немедленно.
рассинхронизирования баз данных (основная vs. kafka) если kafka лежит
медленные воркеры все также блокируют все очередь (или одну partition)
Подход с transactional sandbox или BD+CDC вполне стандартный подход в данном случае.
Альтернативой может быть какой-то pub/sub, но тут надо дробить входящие сообщения. Скорее всего несколько уровней очередей - первая принять большой документ, вторая раздробить его, и дальше уже workers которые будут скачивать изображения и обновлять базу. Да и это довольно рискованная смена архитектуры по сравнение с тем, что было до обновления.
Инкрементальное улучшение существующей архитектуры описанное в статье вполне логичное решение. Этот ход купил достаточно времени при малейших затратах, ну а дальше можно подумать о более радикальных изменениях
Возможно, что Вам следует подумать о KV-storage и хранить данные в формате который не стирает данные которые не может распознать (тот-же Protobuf или даже JSON).
А еще лучше просто использовать Document-storage.
Похоже, что Вы используете неправильный инструмент.
Ваш тест на скорость ниочем. В первую очередь время инициализации/деинициализации и время выполнения полезной работы — это разные вещи.
Ну и как всегда цена разработки и поддержки против цены оборудования.
Я не большой сторонник Go но это хороший язык который выполняет свою задачу. Есть свои проблемы, но у какого языка их нет? Ну и, конечно, всегда нужно применять нужные инструменты вовремя и с умом.
Имеет сложное математическое определение, которое можно заменить на: Функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом.
Мне кажется, что это определение вводит в заблуждение. Это скорее всего применимо к полиморфизму и ducktyping. Да и про функции в определении принципа нет упоминания.
Речь идет о типах: подтипы базовых типов не должны изменять свойства(как корректность) программы.
Например, если есть тип «драйвер базы данных», то подтип «драйвер базы данных с резервным копированием» отвечает принципу, а подтип «драйвер базы данных который всегда отбрасывает данные с невалидными полями» может и не подходить. Тут все зависит от рамок «корректности».
poxvuibr, на самом деле все зависит от расположении в памяти и размеров всех узлов где кэшируются данные. Ну и, естественно от расстояния между указателями.
Конечно, нет гарантий, что данные еще в кэше первого, второго или третьего уровня, или данные еще в памяти (а не сброшены на диск) или вообще исчезли потому, что это поток сообщений из сети.
grossws, я не зацикливался на привязке Java/LinkedList, а постарался абстрагироваться и представить какие еще бывают случаи применения данного алгоритма.
Мне кажется, что если стоит такая строгая задача (Java/LinkedList), то почему бы не изменить условия и не использовать другую структуру данных с помощью которой алгоритм реализуется проще. Я понимаю, что есть спортивный интерес, а кто этот код потом поддерживать будет?
У вас объекты, составляющие linked list валяются в разных кусках tlab'ов, а какой локальности речь?!
Главное чтоб cache line тэги не конфликтовали, а там пусть лежат где угодно.
В том, что данные на которые смотрит медленный указатель могут буть еще в кэше.
Если Вы посмотрите дальше связанного списка, то теоретически подобные решения могут быть использованы при работе с потоками.
Локальностью данных. Если данные не локальные или не помещаются в кэш первого уровня.
Хотя если честно все подобные задачи имеют академический характер в 80% случаях.
Если необходимо реализовать timsort на листочке на собеседовании в офисе — я согласен с fzn7 — ничего это задание не показывает.
Если это «домашнее задание» то почему бы и нет — покажет, что человек может в комфортной обстановке.
Так же в офисе могут попросить реализовать алгоритм на доске — вполне хорошее упражнение. Так как тут есть диалог между у частниками, даже если человек затрудняется реализовать алгоритм, видно как он мыслит (что в основном и должно быть целью собеседования).
А Вы, khim, можете тут вот реализовать все операции RB-tree или Radix-tree не заглядывая в wikipedia(или другие источники информации).
Это как же так? Вы хотите сказать, что подавляющее количество серверов использует Win или OSX?
К тому же Android использует ext4 в 90% случаев. Если еще сюда добавить сетевое оборудование и т.д. — думаю что *nix в большинстве =).
Википедия позволяет быть ближе к реальности.
Ваш пример не имеет никакого отношения к ригистру.
В основном регистронезависимые имена в файловый системах — это потеря производительность. Ведь если регистр учитывается, то можно просто сравнить байты, а если нет — сначала раскодировать символ(например Ć в unicode U+0106), потом сменить регистр(на ć), и только потом начинать сравнение. К слову, перекодировка нетривиальная задача. Причем это надо сделать 2 раза — для искомого и для всех «зарегистрированных» вариантов(существующих файлов, директорий, и т.д.) на пути. Кроме того тут присутствует не только чтение из памяти, но и запись в нее.
В итого это большой расход памяти, нагрузка на кэш процессора и на шину данных памяти. Если Вы посмотрите сколько сравнений приходится делать FS для того чтоб открыть file.txt, то сразу станет понятно что к чему.
Ну и есть, конечно, эстетический аспект. Я бы возмутился, если бы ко мне обращался человек как к NiAmStEr.
А как же платы от SolidRun или ODROID? Есть поддержка Arch Linux и Yocto(даже есть сборки OpenElec если кому надо для домашнего кинотеатра). Большего для любителей и профессионалов(для прототипирования) и не надо ИМХО. Мощное железо до $200.
У меня мой NAS поднят на CuBox-i(4 ядра) с Arch Linux, один диск(512Go WD AV) подключен через eSATA, установлена samba, rTorrent+ruTorrent. Шум 0dB, потребляемая мощность около 15Вт в активном состоянии, в пассивном не знаю так как нет прибора замерить, но на вскидку не должно превышать 5Вт. Если немного покопаться, то можно установить KODI, чтоб подключить к телевизору. В основном была загвоздка с дровами для GPU и так как у меня валялась бесхозная rPI и было слегка лениво красноглазить, то я решил ее задействовать и установил OpenElec который довольно стабилен.
Насчет стоимости я точно сказать не могу, так как покупались все части в разное время и что-то подорожало, что-то подешевело. На данный момент cubox-i подорожал — 160 евро(покупал за 140 евро 2-3 года назад), сравнительно недавно покупал кейс для диска Icy Box IB-290 — 23 евро, диск достался в аренду от провайдера(до этого был WD 2To 5-летней выдержки который до сих пор жив, но решил заменить на тот, что дал провайдер так как он тише) но на рынке он стоит около 80 евро. Итого 260 евро — стоимость начального ноутбука. По опыту могу сказать, что должно быть достаточно самого простого cubox-i который стоит 85 евро, что выльется в 175 евро в целом.
По поводу скорости передачи — в локальной сети по samba скачивание файла около 35Mops(WiFi 5G). Про максимальну скорость скачивания торрента сейчас точно не могу сказать, так как провайдер начал резать закачку торрентов после смены контракта(упал до 5Mops для всех торрентов), раньше из России было до 16Mops. Касательно одновременного скачивания и передачи точно сказать не могу — сейчас в командировке, но если кого интересует — могу по приезду провести тесты.
Сам пробовал pomodoro с разными интервалами, но как-то не прижился. Часто бывают задачи интервал которых превышает 1 час.
Также возникают проблемы с прерыванием на самом интересном — не так просто прерваться в некоторых кульминационных моментах. Получается, что интервалы могут плыть, что я так понимаю убивает всю идею pomodoro. Также приходится тратить время на изменение всего графика после таких ситуаций.
Хочу также заметить, что чаще всего почта и т.д. — не проблема для меня. Соц сетями на работе я вообще не пользуюсь. А почту просматриваю когда дохожу до какого-то логической точки, когда перерыв не разбивает текущую мысль.
Я пытаюсь использовать такой принцип — взвожу часы на время X, которое по моему прогнозу мне понадобится выполнить задачи (T0,..,Tn). Стараюсь чтоб время X не превышало 2 часа и не меньше 45 минут. Если я справляюсь раньше или позже — я отмечаю прогресс(что помогает также оценивать точность прогноза) и отдыхаю в среднем 10 минут.
Спасибо за статью! Материал годный, но хотелось бы больше примеров из практики, особенно интересны метастабильные состояния.
Мне кажется тут авторы подборки антипаттернов либо не знакомы со всеми паттернами либо лукавят. А как же retry with exponential backoff?
В 99.9% случаем он работает прекрасно. В моей практике был только один случай когда circuit breaker мог бы быть лучше exponential backoff (но это не точно). И проблема даже не в самом exponential backoff, а в его классической реализации - полностью аннулировать накопившийся backoff на первый успешный ответ (что в результате может убивать систему периодически, волнами). Если бы backoff откатывался плавно, то проблем бы не было.
Circuit breaker хорош там где ответы не "подвисают", а где клиент не понимает ответа и отсылает новый запрос немедленно.
Опечатка: DB (Data Base) + CDC (Change data capture). Например Posgres + Debezium
Тут есть 2 проблемы:
рассинхронизирования баз данных (основная vs. kafka) если kafka лежит
медленные воркеры все также блокируют все очередь (или одну partition)
Подход с transactional sandbox или BD+CDC вполне стандартный подход в данном случае.
Альтернативой может быть какой-то pub/sub, но тут надо дробить входящие сообщения. Скорее всего несколько уровней очередей - первая принять большой документ, вторая раздробить его, и дальше уже workers которые будут скачивать изображения и обновлять базу. Да и это довольно рискованная смена архитектуры по сравнение с тем, что было до обновления.
Инкрементальное улучшение существующей архитектуры описанное в статье вполне логичное решение. Этот ход купил достаточно времени при малейших затратах, ну а дальше можно подумать о более радикальных изменениях
Возможно, что Вам следует подумать о KV-storage и хранить данные в формате который не стирает данные которые не может распознать (тот-же Protobuf или даже JSON).
А еще лучше просто использовать Document-storage.
Похоже, что Вы используете неправильный инструмент.
Ну и как всегда цена разработки и поддержки против цены оборудования.
Я не большой сторонник Go но это хороший язык который выполняет свою задачу. Есть свои проблемы, но у какого языка их нет? Ну и, конечно, всегда нужно применять нужные инструменты вовремя и с умом.
Спасибо
Мне кажется, что это определение вводит в заблуждение. Это скорее всего применимо к полиморфизму и ducktyping. Да и про функции в определении принципа нет упоминания.
Речь идет о типах: подтипы базовых типов не должны изменять свойства(как корректность) программы.
Например, если есть тип «драйвер базы данных», то подтип «драйвер базы данных с резервным копированием» отвечает принципу, а подтип «драйвер базы данных который всегда отбрасывает данные с невалидными полями» может и не подходить. Тут все зависит от рамок «корректности».
Конечно, нет гарантий, что данные еще в кэше первого, второго или третьего уровня, или данные еще в памяти (а не сброшены на диск) или вообще исчезли потому, что это поток сообщений из сети.
grossws, я не зацикливался на привязке Java/LinkedList, а постарался абстрагироваться и представить какие еще бывают случаи применения данного алгоритма.
Мне кажется, что если стоит такая строгая задача (Java/LinkedList), то почему бы не изменить условия и не использовать другую структуру данных с помощью которой алгоритм реализуется проще. Я понимаю, что есть спортивный интерес, а кто этот код потом поддерживать будет?
Главное чтоб cache line тэги не конфликтовали, а там пусть лежат где угодно.
Если Вы посмотрите дальше связанного списка, то теоретически подобные решения могут быть использованы при работе с потоками.
Хотя если честно все подобные задачи имеют академический характер в 80% случаях.
Если это «домашнее задание» то почему бы и нет — покажет, что человек может в комфортной обстановке.
Так же в офисе могут попросить реализовать алгоритм на доске — вполне хорошее упражнение. Так как тут есть диалог между у частниками, даже если человек затрудняется реализовать алгоритм, видно как он мыслит (что в основном и должно быть целью собеседования).
А Вы, khim, можете тут вот реализовать все операции RB-tree или Radix-tree не заглядывая в wikipedia(или другие источники информации).
Отличное объяснение от автора красно-черных деревьев Р. Седжвика на портале Принстонского университета.
Для полноты статьи добавьте алгоритм удаления ячейки. Это самая захватывающая часть.
К тому же Android использует ext4 в 90% случаев. Если еще сюда добавить сетевое оборудование и т.д. — думаю что *nix в большинстве =).
Википедия позволяет быть ближе к реальности.
В основном регистронезависимые имена в файловый системах — это потеря производительность. Ведь если регистр учитывается, то можно просто сравнить байты, а если нет — сначала раскодировать символ(например Ć в unicode U+0106), потом сменить регистр(на ć), и только потом начинать сравнение. К слову, перекодировка нетривиальная задача. Причем это надо сделать 2 раза — для искомого и для всех «зарегистрированных» вариантов(существующих файлов, директорий, и т.д.) на пути. Кроме того тут присутствует не только чтение из памяти, но и запись в нее.
В итого это большой расход памяти, нагрузка на кэш процессора и на шину данных памяти. Если Вы посмотрите сколько сравнений приходится делать FS для того чтоб открыть file.txt, то сразу станет понятно что к чему.
Ну и есть, конечно, эстетический аспект. Я бы возмутился, если бы ко мне обращался человек как к NiAmStEr.
Насчет стоимости я точно сказать не могу, так как покупались все части в разное время и что-то подорожало, что-то подешевело. На данный момент cubox-i подорожал — 160 евро(покупал за 140 евро 2-3 года назад), сравнительно недавно покупал кейс для диска Icy Box IB-290 — 23 евро, диск достался в аренду от провайдера(до этого был WD 2To 5-летней выдержки который до сих пор жив, но решил заменить на тот, что дал провайдер так как он тише) но на рынке он стоит около 80 евро. Итого 260 евро — стоимость начального ноутбука. По опыту могу сказать, что должно быть достаточно самого простого cubox-i который стоит 85 евро, что выльется в 175 евро в целом.
По поводу скорости передачи — в локальной сети по samba скачивание файла около 35Mops(WiFi 5G). Про максимальну скорость скачивания торрента сейчас точно не могу сказать, так как провайдер начал резать закачку торрентов после смены контракта(упал до 5Mops для всех торрентов), раньше из России было до 16Mops. Касательно одновременного скачивания и передачи точно сказать не могу — сейчас в командировке, но если кого интересует — могу по приезду провести тесты.
Также возникают проблемы с прерыванием на самом интересном — не так просто прерваться в некоторых кульминационных моментах. Получается, что интервалы могут плыть, что я так понимаю убивает всю идею pomodoro. Также приходится тратить время на изменение всего графика после таких ситуаций.
Хочу также заметить, что чаще всего почта и т.д. — не проблема для меня. Соц сетями на работе я вообще не пользуюсь. А почту просматриваю когда дохожу до какого-то логической точки, когда перерыв не разбивает текущую мысль.
Я пытаюсь использовать такой принцип — взвожу часы на время X, которое по моему прогнозу мне понадобится выполнить задачи (T0,..,Tn). Стараюсь чтоб время X не превышало 2 часа и не меньше 45 минут. Если я справляюсь раньше или позже — я отмечаю прогресс(что помогает также оценивать точность прогноза) и отдыхаю в среднем 10 минут.