Коли НЕ добре використовувати акторів в акка / ерланг?


58

Я працюю з аккою вже 7-8 місяців щодня. Коли я починав, я працював над додатками і зауважував би, що актори використовуються в основному де-небудь всередині акторської системи для спілкування між більшістю об'єктів. Так що я зробив те саме - закрутив іншого актора на х / у / з.

Мені здається, що це може бути занадто безрозбірливим, додаючи складності там, де це не потрібно - але я не можу знайти жодних дискусій щодо того, де слід використовувати акторів проти простої синхронної або навіть асинхронної логіки через ф'ючерси. Я почав обмірковувати свою позицію після того, як мій колега згадав щось подібне. Нещодавно я зрозумів декілька випадків, коли я розмірковував над завданням, а потім ухилявся від створення іншого актора, тому що міг би досягти такого ж результату безпечно в незмінному виконанні - наприклад, щось на зразок отримання значень конфігурації з db або файлів десь, куди ви звертаєтесь дуже рідко і будете чекати результату - це фактичний випадок використання.

Зокрема, мені здається, що будь-який випадок, коли ви граєте з незмінним станом, актори створюють складність і обмежують пропускну здатність - чисту функцію в об'єкті, наприклад, можна викликати одночасно без ризику з будь-яким рівнем одночасності, але актор може обробляти лише одне повідомлення за один раз. Альтернативне розгляд полягає в тому, що ви будете паркувати нитку, якщо вам потрібно дочекатися результату, якщо ви не почнете використовувати ф'ючерси, але випадки, коли вам не потрібно турбуватися про повідомлення про асинхронізацію чи масштаб, здається, що може бути зайвим зайняти актора.

Тож моє запитання - чи поганий час використовувати акторів? Мені цікаво, як виглядає Ерланг і дуже хотілося б зрозуміти інших людей. Або якщо існують якісь принципи використання акторів.


Яка робота дає можливість щомісяця працювати місяцями з Аккою?
День

3
Хороші. :) Або внесіть зміни самостійно.
JasonG

Я хотів би конкретно дізнатися, які компроміси є між askартистом і просто використанням простого Future.
Макс Хайбер

2
Я закінчив писати книгу про Акку через пару років, і я думаю, ви можете підсумувати це так: Якщо у вас є стан - наприклад лічильник, - читання та запис декількох потоків з / до цього значення в кінцевому підсумку перестане битись один на одного без синхронізації та блокування. Якщо ви помістите цей стан у актора, раптом ви можете бути впевнені, що до нього безпечно звертатися, і ви не відмовляєтесь від написання чи отримання черствих читання. Актори в Ерланг і Акка також припускають, що стан може погіршитися, а актор може викидати помилки, тому у вас є деякі характеристики системи самолікування. Ф'ючерси простіші, якщо вам не потрібно мутувати
JasonG

через багато років я є програмістом erlang / elixir, і я продовжую повертатися до цього з новою розумінням :) Еліксир зовсім інший, оскільки немає об'єктів як альтернатива процесам, тому процеси завжди будуються, коли потрібно стан . Це просто відбувається одночасно. Це найкращий евристичний досі.
JasonG

Відповіді:


23

Це питання, яке мене цікавить, і я займався деякими дослідженнями. Для інших точок зору дивіться цю публікацію в блозі Ноеля Уолша або це запитання на стеку Overflow. У мене є кілька думок, які я хотів би запропонувати:

  • Я думаю, що Акка, оскільки він працює з повідомленнями, заохочує "просунути розум". Часто, для паралельності, я б заперечував, що це не те, чого ви хочете. Потягнути набагато безпечніше. Наприклад, одна поширена схема для розподілених систем - це набір працівників, що обробляють інформацію в черзі . Очевидно, що це можливо в Akka, але це не обов'язково здається, що це перший підхід, який люди намагаються . Akka також пропонує довговічні поштові скриньки, але знову ж таки, залежить від того, як ви їх використовуєте - одна загальна черга набагато гнучкіша, ніж на черги працівників для балансування / повторного призначення роботи.
  • Легко ввійти в розум замінити свої заняття акторами. Насправді деякі люди навіть, здається, виступають за це, кажучи, що актори повинні робити лише одне . Згідно з логічним висновком, це збільшує складність коду, як описує Джейсон, адже якщо кожен клас є актором, це багато зайвих повідомлень і блоків прийому / відправки. Це також ускладнює розуміння та тестування коду, оскільки ви втрачаєте формальність інтерфейсів - і я не переконаний, що коментарі є рішенням цього . Також, незважаючи на легендарну ефективність Акки , я підозрюю, що розповсюдження акторів - це не дуже гарна ідея продуктивності - коли ми використовуємо теми Java, ми знаємо, що вони дорогоцінні, і зберігаємо їх відповідно.
  • Це пов’язано з попереднім пунктом, але ще одне роздратування - це втрата інформації про тип, яку виділяють Ноель і Піно, як для багатьох з нас, тому ми використовуємо Scala, а не інші мови, такі як Python. Існують деякі способи цього, але вони або нестандартні , не рекомендуються, ні експериментальні .
  • Нарешті, паралельність, навіть якщо у вас є розум "нехай це впаде" , важко. Альтернативні моделі програмування можуть допомогти, але вони не змушують проблем зникати - вони змінюють їх - ось чому добре про них подумати формально . Ось чому розробник Joe Average досягає готових інструментів, таких як RabbitMQ, Storm, Hadoop, Spark, Kafka або NoSQL. У Akka є кілька попередньо вбудованих інструментів та компонентів, що класно, але він також відчуває себе досить низьким, тому більш готові побудовані загальні елементи розподілених систем допоможуть розробникам та забезпечать, щоб системи були побудовані правильно.

Як і Джейсон, я хочу почути тут прозріння інших людей. Як я можу вирішити деякі вищезазначені проблеми та краще використовувати Akka?


1
Я знайшов цю публікацію про тестування в Akka спот-он timgilbert.wordpress.com/2013/07/07/…
Марк Батлер

"Склад над успадкуванням" все ще корисний для введення залежності. Наприклад, передайте залежність в якості реквізиту (використовує параметри конструктора). Проблемою тоді було б нагляд - створений актор буде контролюватися десь, крім актора. Маршрутизатор може бути використаний для обертання стратегії нагляду навколо акторів, створених на найвищому рівні, але святих, що зараз досить складно! Я думаю, торт був би кращим рішенням - наприклад, позначте, як створити актора для актора служб ДБ. Тоді просто використовуйте тестовий сервіс-макет / стриб-дб службовий рисунок у текстовому контексті.
JasonG

1
Так, саме - нагляд не працює добре з введенням залежності. Також у мене були випадки, коли мені потрібно було вводити фабрику, а не клас, інакше виникали проблеми із закриттям - я здогадуюсь через обробку ниток Аккою.
Марк Батлер

Я думаю, що це не погана ідея - знак подяки - я б насправді спробував трохи написати про це і поспілкуватись. Ви можете ввести щось, що дає реквізит? Фабрика видів акторів, де споживач може інстанціювати актора. наприклад, метод def (arg) = повернути реквізити (новий ActorWithArgs (arg)) з цієї фабрики (psuedo?), щоб ви могли зробити актора в потрібному контексті. Це здається гарною ідеєю та хорошою ціллю для вирішення тортів і для ді.
JasonG

Я щойно розпочав наступний курс: coursera.org/course/posa Хоча він в першу чергу спрямований на людей, які програмують Android, це також хороший огляд одночасності Java. Тож одне, що мені цікаво, це "Хіба Акка не є просто фантазійною формою циклів подій з деякими дзвіночками (адже ви можете розміщувати петлі подій у різних потоках)?"
Марк Батлер

21

Варто подумати, для чого використовується модель актора: модель актора

  1. модель одночасності
  2. що дозволяє уникнути одночасного доступу до змінного стану
  3. використання асинхронних механізмів зв'язку для забезпечення одночасності.

Це цінно тим, що використання спільного стану з декількох потоків стає дуже важким, особливо коли є зв'язки між різними компонентами спільного стану, які повинні зберігатися синхронізованими. Однак якщо у вас є компоненти домену, у яких:

  • Ви не дозволяєте одночасності, АБО
  • Ви не дозволяєте змінювати стан (як у функціональному програмуванні), АБО
  • Ви повинні покластися на якийсь механізм синхронного зв'язку,

тоді модель актора не дасть великої (якщо є) вигоди.

Сподіваюся, що це допомагає.


Дякую - я думаю, вам справді доведеться оцінити дві речі - стан, що змінюється, і паралельність? Немає проблем вирішити, якщо клас без громадянства АБО не сумісний. Ще одне враження - я думаю, що толерантність до помилок - це ще один момент? Наприклад, якщо у вас є непорушний клієнт Redis, але він може вийти з ладу під час роботи - чи це не буде корисним випадком використання? що перезапуск цього актора може знадобитися? Оскільки - хоча клас може бути суттєво незмінним - це дуже можливо, щоб був пошкоджений стан, зовнішній за незмінного актора, який може спричинити його збій.
JasonG

Я думаю, що актор, який відповідає за спілкування з Redis, отримає виняток і хоча перезапустить.
JasonG

@JasonG На мій погляд, "відмовостійкість" - це не аспект моделі актора взагалі - це щось, що поставляється з реалізацією акторської моделі в Ерланге (а може, і Акка?). Я не можу розмовляти з Redis, хоча, маю визнати, "незмінний клієнт" звучить для мене дивно ... Якщо програмний компонент може вийти з ладу, я не бачу, як це можна вважати незмінним.
Айдан Каллі

Допуск та нагляд за відмовами існують у akka, і він дуже схожий на erlang. Я розумію, що ви говорите про незмінного клієнта, але незмінне означає, що стан коду ніде не змінюється. Якщо я ініціалізую з'єднання під час запуску, можливо, що клієнтський код може бути незмінним за допомогою стратегії перезавантаження, яка використовується з будь-якої несправності, просто реініціалізуючи актора при виникненні проблеми.
JasonG

12

Ваша інтуїція правильна, ІМХО. Використовувати акторів скрізь - це як мати прислівний молоточок і бачити лише цвяхи.

Найкраща практика Ерланга - використовувати процеси / дійових осіб для всіх видів діяльності, які відбуваються одночасно. Тобто, як і в реальному житті. Іноді важко знайти потрібну деталізацію, але більшість випадків ви просто знаєте, переглядаючи модельований домен та використовуючи трохи здорового глузду. Боюся, у мене немає кращого методу, ніж це, але сподіваюся, що це допоможе.


Класна подяка. Мені дуже цікаво подивитися, що відбувається в цій дискусії.
JasonG

0

Для введення / виводу повідомлень:

Нещодавно я познайомився з додатком на основі акки, де модель актора насправді викликала проблеми з одночасністю, а простіша модель була б достатньою для навантаження.

Проблема полягала в тому, що вхідні повідомлення рухалися різними «смугами» (різними контурами акторів), але код передбачав, що повідомлення надійдуть до їх кінцевого пункту в тому ж порядку, в якому вони надійшли. Поки дані надходили з досить великими інтервалами, це спрацьовувало, тому що до пункту призначення буде лише одне конфліктне повідомлення. Коли інтервали скоротилися, вони почали виходити з ладу і викликати дивну поведінку.

Проблему можна було б вирішити правильно з трохи меншими акторами, але це легка помилка при їх надмірному використанні.


Це є основоположним і широко актуальним. Ви можете гарантувати лише замовлення між двома акторами. doc.akka.io/docs/akka/current/scala/general/… Ви не можете гарантувати доставку замовлення в будь-яку систему, де ви вболіваєте / входите . andreasohlund.net/2012/01/18/dont-assume-message-ordering
JasonG

-1

На мою думку, для акторів є два випадки використання. Спільні ресурси, такі як порти тощо, та велика держава. Перший добре висвітлювався дискусією, але велика держава також є вагомою причиною.

Велика структура, що передається під час кожного виклику процедури, може використовувати багато стеків. Цей стан можна поставити в окремий процес, структуру замінити на ідентифікатор процесу, і цей процес запитується на необхідній основі.

Бази даних, такі як mnesia, можна вважати збереженням стану зовні в процесі запиту.


1
Ви можете уточнити? Ви маєте на увазі велику державу в мережі? У межах локального процесу передача посилання на незмінне структуру майже не коштує, і ви не можете передавати змінні структури. Якщо припустити, що ви говорите про велику змінну структуру, яку потрібно скопіювати для надсилання? Таким чином, це в основному те саме - спільний стан. Розмір насправді нічого не змінює. Повідомте мене, якщо я нерозумію.
JasonG

То як вам пройти посилання? Безумовно, спосіб зробити це - ввести структуру в процес і передати процесід. Місцеві дзвінки помістять дані в стек, і кожен рекурсивний дзвінок буде робити це знову (за винятком хвостової рекурсії). Рекурсивна обробка структури може бути здійснена за допомогою списків для передачі стану від одного виклику до іншого, цей стан може потім посилатися на структуру в іншому процесі.
тоні Уоллес
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.