6 ms·
Honest question, and not meant to be inflammatory at all. I'm asking because I'm starting a project where an actor model may be a good fit. Why would one choos
by ryeguy 11y ago
Honest question, and not meant to be inflammatory at all. I'm asking because I'm starting a project where an actor model may be a good fit.
Why would one choose erlang/elixir over akka[0]? Akka seems to implement a lot of common patterns for you. It has actor persistance, cross-node failover, advanced mailbox and routing logic, and is basically a superset of OTP.
The JVM is generally more efficient, has better tooling (ide support), has better libraries, and so on.
The only point I can give to erlang is the pre-emptive scheduling, which is useful for consistently low latency.
[0] http://doc.akka.io/docs/akka/2.4.0-RC3/java.html http://doc.akka.io/docs/akka/2.4.0-RC3/java.html
- m0th87 11y agoPer-actor GC is pretty important, as it allows Erlang to guarantee soft real-time / low latencies. This is simply impossible in the JVM unless you go with Azul's GC, which then sacrifices throughput.
- go1979 11y agoThanks. Another point is that in Erlang/Elixir, if you have many actors, you will have less garbage per actor. Which means faster GC overall. The best known example for Erlang/Beam "http throughput" is WhatsApp's 3 million+ concurrent connections per host. I don't think you get anywhere close in Akka. Maybe max out at 50K per server? Is even that possible? Also, I'm not aware of good examples that use Akka with Java. Everyone I know using Akka seems to also be using Scala (not sure if it is just some kind of self-selection). I really can't stand Scala's syntax. I tried two or three times but I find it too easy to encounter Perl like unreadable code. Just my opinion though.
- rattray 11y agoThere's also Quasar for Java, Clojure, or Kotlin code
- MCRed 11y agoThe problem is the JVM. There's a reason erlang has its own virtual machine. Without virtual machine support, doing concurrency is really just faking it, and will result in significant bugs later on that are essentially impossible to debug.
- 15155 11y agoI take a neutral stance on this: the JVM isn't as amenable to the exact kind of concurrency that Erlang provides (green-threads with local GC backed by immutable data), but that isn't a fair assessment of concurrency. Erlang (et. al. green thread models) has a method of concurrency that works well for situations you're using Erlang for. It's not the most efficient or most technically advanced mechanism for handling concurrency. That being said- > Without virtual machine support, doing concurrency is really just faking it This is patently false, because it implies that: - A VM is necessary for "real" concurrency - (by deduction) Anything not utilizing an erlang-identical model is "faking it." > will result in significant bugs later on that are essentially impossible to debug I'm going to need to see an anecdote or citation for this. Personally-speaking, I have a much easier time (quickly) understanding the execution of event-loop-backed cooperative multitasking than high-level, arbitrarily-preempted threads. Also - I cannot see any reason why Quasar for the JVM would be any easier or harder to debug (from a theoretical, not tooling or practical standpoint) than Erlang actors. The nuances differentiating the two models aren't great enough to merit bugs that you might see in one place or the other. Unbound, CPU-heavy tasks will cause problems for both systems.
- BenoitP 11y agoThe quasar library comes with bytecode manipulation to implement lightweight threads. It saves the program counter and local stack, and pushes it back when resuming. The space cost of context switching is reduced to its minimum. Now this is still on the regular JVM, which will probably have difficulties JITting code that resides in those green-threads (but still better performance than erlang). Also, the entire application is subject to the regular hiccups: gc requires global safepoints, which are reached by making each thread wait when it reaches a local safepoint; on top of the stop-the-world gc operations themselves. But things are improving: RedHat is developing Shenandoah, a GC that has STW pauses under 10ms. The only thing left is making concurrent the scanning of garbage roots(those reside in the registers and stacks). Their goal for version 2 is to get completely rid of pauses.
- nailer 11y agoI can't speak for Akka, but right now Elixir is growing hugely: it feels like node in 2011. There aren't a lot of experts but it's the first time a distributed systems language has actually cared about syntax and a lot of people are really excited about that. You go to any major city and there will be a standing-room-only Elixir meetup.
- roryokane 11y agoThere’s no such meetup anywhere near New York, sadly. The only NYC Elixir meetup is http://www.meetup.com/NYC-Elixir-Language-Meetup/ http://www.meetup.com/NYC-Elixir-Language-Meetup/, which only had three meetings and hasn’t met for two months.
- perishabledave 11y agoRobert Virding has a great talk on BEAM (the Erlang VM). He talks specifically about how BEAM handles concurrency. I think it would answer a lot of your questions. A few of his points that would directly apply to your question: 1. BEAM processes are lightweight which means smaller memory footprint and cheaper context switching between processes. 2. As others have mentioned, garbage collection. Processes don't share memory, so data passed between processes are copied. Virding says that this is a tradeoff, but worth the benefits of keeping garbage collection simple and fast. 3. Since processes are VM processes and not OS processes, BEAM can count the number of function calls each process makes. If a process is long running and starving other processes, BEAM can put that process back on the run queue to give other processes necessary time. These are the ones I can remember from off the top of my head. I recommend giving the talk a listen. https://www.youtube.com/watch?v=_Pwlvy3zz9M&feature=youtu.be https://www.youtube.com/watch?v=_Pwlvy3zz9M&feature=youtu.be
- ssmoot 11y agoAkka doesn't spawn additional OS processes. It's thread based. (ForkJoinPool? Though maybe that's changed.)
- perishabledave 11y agoAh yea sorry, wasn't implying that it was only stating what BEAM did. I think Akka uses a thread pool so you'd be right.
- 15155 11y ago> Why would one choose erlang/elixir over akka - BEAM has green-thread-local GC. - As you mentioned, preemptive scheduling is implemented at the VM-level and is relatively elegant. - Faster startup times (meh) - Dynamic typing (subjective) > JVM is generally more efficient Depends on the scenario (and JVM implementation) - tracing, STW GC isn't always the best option. > has better tooling (ide support) Yes. > has better libraries Bit subjective, but there are certainly MORE JVM-compatible libraries. --- Personally not a fan of Akka simply due to the underlying languages commonly used with it (Scala, Akka) As a Haskell-user: if forced to choose between Scala and Elixir, I would choose Elixir.
- rozap 11y agoJVM threads are relatively heavyweight. The JVM would fall over trying to run as many threads per machine as BEAM will happily run. And you still have the stop the world GC in akka. Obviously that's not the be-all-end-all measure of a VM, but in the context of actors it's pretty damn important. Akka is essentially an actor library bolted onto a VM that really doesn't like what it tries to do. Some people make it work, but there's a lot of friction from the GC that gives rise to some really undesirable performance characteristics.
- justthistime_ 11y ago> Akka is essentially an actor library bolted onto a VM that really doesn't like what it tries to do. Given that it already beats the shit out of Erlang, I can only wonder what would happen if the Hotspot guys added a little bit of additional support ... :-)
- vladimirralev 11y agoI use both Akka and Erlang/BEAM is heavy production. There is a huge difference in multiple aspects. 1. GC and context switching internals. This becomes obvious quickly under load. While you can tune Akka in some ways and Akka will generally kick Erlang's ass in terms of performance, the response times and the number of usable concurrent entities are in favor of Erlang. 2. Libraries - what libraries are you going to use in Akka? JDBC/JPA? java.net? HTTP clients to pass REST requests around to modern integration endpoints? Most if not all are blocking and will bring Akka to it's knees when something freezes. Erlang libs are either non-blocking or blocking doesn't matter because it will handle millions of processes with little overhead. 3. Production ops - deploying and rolling back code in Erlang has tons of gotchas, but you can mostly change code and DB schemas on the fly in production, selectively or even run parts of the production load on your laptop to debug it. And you can deploy changes in small increments many times a day without affecting uptime. 4. Best part is failure recovery. In Akka, the node is a single OS process and single JVM. If you leak a file handle or some resource or lock and a thread blocks nothing will recover you until your OS process dies. Erlang is capable of killing processes everywhere, there is no internal global state. Even if you leak something like a file handle in a process, it will be cleaned up when the process terminates like a real OS process. Even if you leak something in ets/mnesia(the global storage), you can go ahead and clean it up from your erlang shell and production doesn't have to stop. If you leak something in Java and you haven't exposed specific interface to clean it, you will have to kill the JVM.