Kapan TIDAK baik menggunakan aktor dalam akka / erlang?

58

Saya telah bekerja dengan akka selama 7-8 bulan sekarang setiap hari. Ketika saya mulai, saya akan mengerjakan aplikasi dan memperhatikan bahwa aktor pada dasarnya akan digunakan di mana saja di dalam sistem aktor untuk berkomunikasi antara sebagian besar objek. Jadi saya melakukan hal yang sama - memutar aktor lain untuk x / y / z.

Tampaknya bagi saya bahwa ini mungkin terlalu sembarangan, menambah kompleksitas di mana itu tidak diperlukan - tapi saya tidak dapat menemukan diskusi tentang di mana aktor vs logika sinkron atau bahkan logika async melalui futures harus digunakan. Saya mulai merenungkan pendirian saya setelah rekan kerja saya menyebutkan sesuatu yang serupa. Saya menyadari beberapa kasus baru-baru ini di mana saya telah merenungkan tugas dan kemudian menghindari membuat aktor lain karena saya bisa mencapai hasil yang sama dengan aman dalam implementasi yang tidak dapat diubah - misalnya sesuatu seperti mendapatkan nilai konfigurasi dari db atau file di suatu tempat di mana Anda mengakses sangat jarang dan akan tunggu hasilnya adalah use case yang sebenarnya.

Secara khusus, menurut saya, kasus apa pun di mana Anda bermain dengan keadaan tidak berubah, aktor menciptakan kompleksitas dan membatasi throughput - fungsi murni dalam objek, misalnya, dapat disebut bersamaan tanpa risiko dengan tingkat konkurensi apa pun, namun seorang aktor hanya dapat memproses satu pesan pada satu waktu. Pertimbangan alternatifnya adalah Anda akan memarkir utas jika Anda harus menunggu hasilnya kecuali jika Anda mulai menggunakan futures tetapi jika Anda tidak perlu khawatir tentang pesan atau skala async, tampaknya mungkin terlalu sulit untuk mempekerjakan seorang aktor.

Jadi pertanyaan saya adalah - apakah ada waktu yang buruk untuk menggunakan aktor? Saya ingin tahu bagaimana erlang terlihat dan benar-benar menyukai wawasan orang lain. Atau jika ada beberapa prinsip seputar penggunaan aktor.

JasonG
sumber
Pekerjaan seperti apa yang memberi kesempatan untuk bekerja dengan Akka setiap hari selama berbulan-bulan?
Den
3
Bagus :) Atau buat perubahan sendiri.
JasonG
Saya ingin tahu secara khusus apa kompromi antara askaktor dan hanya menggunakan dataran Future.
Max Heiber
2
Saya akhirnya menulis buku tentang Akka beberapa tahun kemudian dan saya pikir Anda dapat merangkumnya seperti ini: Jika Anda memiliki beberapa kondisi - misalnya counter - banyak utas membaca dan menulis dari / ke nilai itu akan berakhir menginjak satu sama lain tanpa sinkronisasi dan penguncian. Jika Anda memasukkan status itu ke dalam aktor, tiba-tiba Anda dapat yakin bahwa itu diakses dengan aman dan Anda tidak menjatuhkan tulisan atau membaca basi. Aktor-aktor di erlang dan akka juga menganggap bahwa keadaan bisa menjadi buruk dan aktor dapat melakukan kesalahan sehingga Anda memiliki beberapa karakteristik sistem penyembuhan diri. Futures lebih sederhana jika Anda tidak perlu bermutasi
JasonG
bertahun-tahun kemudian saya seorang programmer erlang / elixir dan saya terus kembali ke sini dengan wawasan baru :) Elixir sangat berbeda karena tidak ada objek sebagai alternatif untuk proses sehingga proses selalu dibangun ketika Anda membutuhkan keadaan . Itu terjadi bersamaan. Ini masih heuristik terbaik.
JasonG

Jawaban:

23

Ini adalah pertanyaan yang saya tertarik dan saya telah melakukan penelitian. Untuk sudut pandang lain, lihat posting blog ini oleh Noel Walsh atau pertanyaan ini tentang Stack Overflow. Saya memiliki beberapa pendapat yang ingin saya tawarkan:

  • Saya pikir Akka, karena berfungsi dengan pesan, mendorong "push mindset". Seringkali, untuk konkurensi, saya berpendapat ini bukan yang Anda inginkan. Tarik jauh lebih aman. Sebagai contoh satu pola umum untuk sistem terdistribusi adalah memiliki seperangkat pekerja yang memproses informasi dalam antrian . Jelas ini mungkin di Akka tetapi tampaknya tidak selalu menjadi pendekatan pertama yang orang coba . Akka juga menawarkan kotak surat yang tahan lama tetapi sekali lagi itu tergantung bagaimana Anda menggunakannya - satu antrian bersama jauh lebih fleksibel daripada antrian per pekerja untuk menyeimbangkan / menetapkan ulang pekerjaan.
  • Sangat mudah untuk masuk ke pola pikir mengganti kelas Anda dengan aktor. Bahkan beberapa orang tampaknya mengadvokasi dengan mengatakan bahwa aktor seharusnya hanya melakukan satu hal . Dibawa ke kesimpulan logis ini meningkatkan kompleksitas kode seperti yang dijelaskan Jason, karena jika setiap kelas adalah aktor, itu banyak pesan tambahan dan menerima / mengirim blokir. Ini juga membuat lebih sulit untuk memahami dan menguji kode karena Anda kehilangan formalitas antarmuka - dan saya tidak yakin bahwa komentar adalah solusi untuk ini . Juga di samping efisiensi Akka yang legendaris , saya curiga bahwa proliferasi aktor bukanlah ide yang bagus untuk kinerja - ketika kita menggunakan utas Java kita tahu mereka berharga dan melestarikannya.
  • Ini terkait dengan poin sebelumnya, tetapi gangguan lain adalah hilangnya informasi jenis yang disoroti Noel dan Pino, karena bagi banyak dari kita itu sebabnya kita menggunakan Scala daripada bahasa lain seperti Python. Ada beberapa cara untuk mengatasi ini tetapi tidak standar , tidak direkomendasikan, atau eksperimental .
  • Akhirnya konkurensi, bahkan jika Anda memiliki pola pikir "let it crash" , sulit. Model pemrograman alternatif dapat membantu tetapi mereka tidak menyelesaikan masalah - mereka mengubahnya - itu sebabnya baik untuk memikirkannya secara formal . Itu juga mengapa pengembang Joe Average meraih alat yang siap pakai seperti database RabbitMQ, Storm, Hadoop, Spark, Kafka, atau NoSQL. Akka memang memiliki beberapa alat dan komponen prebuilt, yang keren, tetapi juga terasa cukup rendah, sehingga elemen umum yang lebih siap dibangun dari sistem terdistribusi akan membantu pengembang dan memastikan sistem dibangun dengan benar.

Seperti Jason, saya ingin mendengar wawasan orang lain di sini. Bagaimana saya bisa mengatasi beberapa masalah di atas dan menggunakan Akka dengan lebih baik?

Mark Butler
sumber
1
Saya menemukan posting ini tentang pengujian di Akka spot-on timgilbert.wordpress.com/2013/07/07/...
Mark Butler
"Komposisi atas warisan" masih berguna untuk injeksi ketergantungan. Misalnya, meneruskan ketergantungan dalam sebagai alat peraga (menggunakan params konstruktor). Masalahnya kemudian akan pengawasan - aktor yang dibuat akan diawasi di tempat lain selain aktor. Router dapat digunakan untuk membungkus strategi pengawasan di sekitar aktor yang dibuat di tingkat atas tetapi suci itu cukup rumit sekarang! Saya kira kue akan menjadi solusi yang lebih baik - memiliki sifat dengan pembuatan aktor untuk aktor layanan db misalnya. Kemudian cukup gunakan ciri layanan test mock / stub db dalam konteks teks.
JasonG
1
Ya, tepatnya - pengawasan tidak bekerja dengan baik dengan injeksi ketergantungan. Saya juga punya contoh di mana saya perlu menyuntikkan pabrik daripada kelas, kalau tidak ada masalah penutupan aneh - saya menduga karena perlakuan Akka terhadap benang.
Mark Butler
Saya pikir itu bukan ide yang buruk - terima kasih tandai - saya mungkin benar-benar mencoba untuk menulis tentang ini sedikit dan bersosialisasi. Anda bisa menyuntikkan sesuatu yang memberikan Alat Peraga mungkin? Sebuah pabrik aktor di mana konsumen dapat membuat instantiate aktor. misalnya metode def (arg) = pengembalian Alat Peraga (ActorWithArgs (arg)) baru dari pabrik (psuedo?) sehingga Anda dapat membuat aktor dalam konteks yang benar. Ini sepertinya ide yang bagus dan target yang bagus untuk solusi kue untuk di juga.
JasonG
Saya baru saja mulai mengikuti kursus ini: coursera.org/course/posa Meskipun ini terutama ditujukan untuk orang-orang yang memprogram Android, ini juga merupakan ikhtisar yang baik dalam konkurensi di Jawa. Jadi satu hal yang saya ingin tanyakan adalah, "Bukankah Akka hanya sebuah bentuk acara loop mewah dengan beberapa lonceng dan peluit (karena Anda dapat menempatkan loop acara pada utas yang berbeda)?"
Mark Butler
21

Layak mempertimbangkan untuk apa model aktor digunakan: model aktor itu

  1. model konkurensi
  2. yang menghindari akses bersamaan ke keadaan bisa berubah
  3. menggunakan mekanisme komunikasi asinkron untuk memberikan konkurensi.

Ini berharga karena menggunakan status bersama dari banyak utas menjadi sangat sulit, terutama ketika ada hubungan di antara berbagai komponen dari status bersama yang harus tetap disinkronkan. Namun, jika Anda memiliki komponen domain di mana:

  • Anda tidak mengizinkan konkurensi, ATAU
  • Anda tidak mengizinkan keadaan bisa berubah (seperti dalam pemrograman fungsional), OR
  • Anda harus mengandalkan beberapa mekanisme komunikasi sinkron,

maka model aktor tidak akan memberikan banyak manfaat (jika ada).

Semoga itu bisa membantu.

Aidan Cully
sumber
Terima kasih - saya kira Anda benar-benar harus mengevaluasi dua hal kemudian - keadaan dan konkurensi yang bisa berubah? Tidak ada masalah untuk dipecahkan jika suatu kelas stateless ATAU tidak bersamaan. Satu pertimbangan lagi - saya pikir toleransi kesalahan adalah hal lain? mis. jika Anda memiliki klien redis yang tidak dapat diubah tetapi bisa gagal saat menjalankan - bukankah itu kasus penggunaan yang baik? bahwa memulai kembali aktor itu mungkin diperlukan? Karena - walaupun kelasnya murni tidak dapat diubah - sangat mungkin terjadi keadaan yang rusak di luar aktor yang tidak dapat berubah yang dapat menyebabkannya gagal.
JasonG
Saya kira aktor yang bertanggung jawab untuk berkomunikasi dengan redis akan mendapatkan pengecualian dan memulai kembali.
JasonG
@JasonG Dalam pikiran saya, "toleransi kesalahan" bukan merupakan aspek dari model aktor pada umumnya - itu adalah sesuatu yang datang dengan implementasi model aktor di Erlang (dan mungkin Akka?). Saya tidak dapat berbicara dengan redis, meskipun saya harus mengakui, "klien yang tidak dapat diubah" terdengar aneh bagi saya ... Jika komponen perangkat lunak dapat gagal, saya tidak melihat bagaimana itu dapat dianggap tidak dapat diubah.
Aidan Cully
Toleransi dan pengawasan kesalahan ada dalam akka dan sangat mirip dengan erlang. Saya mengerti apa yang Anda katakan tentang klien yang tidak dapat diubah tetapi tidak dapat diubah berarti bahwa status kode tidak berubah di mana pun. Jika saya menginisialisasi koneksi pada startup, mungkin kode klien dapat diubah dengan strategi restart yang digunakan pada segala jenis kesalahan, cukup menginisialisasi ulang aktor setelah menemukan masalah.
JasonG
12

Intuisi Anda benar, IMHO. Menggunakan aktor di mana-mana seperti memiliki palu pepatah dan hanya melihat paku.

Praktik terbaik Erlang adalah menggunakan proses / aktor untuk semua kegiatan yang terjadi secara bersamaan. Yaitu, seperti dalam kehidupan nyata. Terkadang sulit untuk menemukan rincian yang tepat, tetapi sebagian besar waktu Anda hanya tahu dengan melihat domain yang dimodelkan dan menggunakan sedikit akal sehat. Saya khawatir saya tidak memiliki metode yang lebih baik dari itu, tetapi saya harap ini membantu.

Vlad Dumitrescu
sumber
Keren Terimakasih. Saya sangat tertarik untuk melihat apa yang terjadi dalam diskusi ini.
JasonG
0

Agar pesan input / output:

Saya baru-baru ini bertemu dengan aplikasi berbasis akka di mana model aktor benar-benar menyebabkan masalah konkurensi, model yang lebih sederhana akan cukup lebih baik di bawah beban.

Masalahnya adalah bahwa pesan yang masuk bergerak dalam 'jalur' yang berbeda (melalui jalur aktor yang berbeda) tetapi kode menganggap pesan akan tiba di tujuan akhir mereka dalam urutan yang sama ketika mereka tiba. Selama data datang dengan interval yang cukup besar, ini akan berhasil karena hanya akan ada satu pesan yang saling bertentangan berlomba ke tujuan. Ketika interval berkurang, mereka mulai keluar dari urutan dan menyebabkan perilaku aneh.

Masalahnya bisa diselesaikan dengan benar dengan aktor yang sedikit kurang, tetapi itu adalah kesalahan yang mudah untuk dilakukan ketika menggunakan mereka secara berlebihan.

DHa
sumber
Ini mendasar dan relevan secara luas. Anda hanya dapat menjamin pemesanan antara dua aktor. doc.akka.io/docs/akka/current/scala/general/… Anda tidak dapat menjamin pengiriman pesanan di sistem mana pun di mana Anda melakukan fan / in. andreasohlund.net/2012/01/18/dont-assume-message-ordering
JasonG
-1

Menurut pendapat saya ada dua kasus penggunaan untuk Aktor. Sumber daya bersama seperti port dan sejenisnya, dan negara besar. Yang pertama telah dibahas dengan baik oleh diskusi sejauh ini, tetapi negara besar juga merupakan alasan yang sah.

Struktur besar yang diteruskan dengan setiap panggilan prosedur dapat menggunakan banyak tumpukan. Keadaan ini dapat dimasukkan ke dalam proses yang terpisah, struktur digantikan oleh id proses, dan proses itu dipertanyakan sesuai kebutuhan.

Database seperti mnesia dapat dianggap sebagai keadaan penyimpanan secara eksternal untuk proses kueri.

tony wallace
sumber
1
Bisakah Anda mengklarifikasi? Apakah maksud Anda kondisi besar di seluruh jaringan? Dalam proses lokal yang meneruskan referensi ke struktur yang tidak dapat diubah hampir tanpa biaya dan Anda tidak dapat melewati struktur yang dapat berubah. Anggap Anda sedang berbicara tentang struktur besar yang bisa berubah yang perlu disalin untuk dikirim? Jadi itu pada dasarnya hal yang sama lagi - keadaan bersama. Ukurannya tidak benar-benar mengubah apa pun. Beri tahu saya jika saya salah paham.
JasonG
Jadi, bagaimana Anda melewati referensi? Tentunya cara untuk melakukan itu adalah dengan meletakkan struktur dalam suatu proses dan melewati processid. Panggilan lokal akan meletakkan data di stack, dan setiap panggilan rekursif akan melakukannya lagi (dengan pengecualian rekursi ekor). Pemrosesan struktur secara rekursif dapat dilakukan dengan menggunakan daftar untuk mentransfer status dari satu panggilan ke panggilan lainnya, keadaan ini kemudian dapat merujuk struktur pada proses lainnya.
tony wallace