In this talk, Dave made the following question (paraphrased by me):
Why aren’t we dominating the serverless space? Elixir is functional, it has multiple processes and is parallel. It has everything serverless needs and wants, and yet Elixir has not risen to be the dominant technology in the area.
I think this is a pertinent question.
In your opinion why do you think Elixir is not dominating serverless architectures?
What main issues do you think Elixir has when trying to go serverless?
Do you believe there is a competing technology easier/more fitting to go serverless than Elixir?
Let me know, I would love to know what everyone thinks !
I’ve not listened to the podcast, but I see two point in terms of elixir and serverless technology:
For orchestration: I guess it’s because of existing knowledge in other languages in teams building those systems. Also the beam doesn’t really have a straight forward story for executing user-code within the vm, so it’s going to need a technology mix anyways.
As the executed runtime: The beam is not the best vm to be started up for a single task and stopped right afterwards.
I guess the beam excels at “self hosted serverless”, when you can deploy your own trusted code to be run.
Aka serverless, but from 90s-00s. There was a reason why we stopped that, and IMHO there is no point in resurrecting that technology.
Ranch pool is number of acceptors not connections. Quote from docs:
First of all, it should not be confused with the maximum number of connections. Acceptor processes are only used for accepting and have nothing else in common with connection processes. Therefore there is nothing to be gained from setting this number too high, in fact it can slow everything else down.
– Ranch Internals docs
So while connection gets accepted by the Ranch, “connection handling” takes place in separate process AFAIK.
Maybe because Elixir doesn’t shine as bright when you take away the OTP, the clustering and long-running processes that pass messages between each other thanks to the BEAM VM?
Elixir & Erlang make sense when you are building distributed, long-running, message-passing system, which is the counter-definition of “serverless” architecture.
Simply put, because the current serverless hosting providers destroy the OS process after it has called one function (okay, most of the time; some of them keep the instance around for a bit) and because the BEAM isn’t starting up particularly quickly. It wasn’t designed to be started and stopped many times just to do one small task. It was designed to be a long-running service.
Contrast that to the average Go, Rust or OCaml compiled binary that starts up in 0.5 - 8.0 milliseconds.
Maybe I’m misunderstanding, but wasn’t Dave Thomas’ point to use Elixir as infrastructure for serverless? In other words, you would still write your small serverless functions in JS, Python, Go etc., but the system running them would be written in Elixir.
I don’t believe BEAM is built with a level of sandboxing required to run untrusted code in mind. Whenever you have a “serverless” architecture, you are allowing programmers to send functions and execute them on a virtual machine somewhere in the cloud, along with other programmers doing the same. I don’t know how technically this is done, but I suspect a strong reliance of OS-level sandboxing and one-off virtual machines, possibly keeping a pool of them already started and allowing instant execution, and then discarding them after the execution. It’s an educated guess but you can probably get to the details here: https://d1.awsstatic.com/whitepapers/Overview-AWS-Lambda-Security.pdf
Now, you could replace all that with BEAM if beam was built to do so. But it’s not. There is a lot of ways to start processes, call functions on current or remote nodes, execute code dynamically. It’s just going to be a nightmare trying to secure that environment and allow execution of untrusted code that needs to be sandboxed. A nightmare to the point of “it ain’t going to happen”, I think.
By using FastCGI which works by creating long-running process that will receive data and then execute provided scripts. Exactly what serverless is trying to avoid.
Because it has it’s use cases - one-shot jobs. For example it is good idea to use FaaS to generate miniatures of uploaded images or to translate data from one format to another, but in general case, FaaS isn’t replacement for “web services’ backends”, it is supporting them in tasks that aren’t their main concern.
I think you both are kind of right and kind of wrong. Current “serverless” implementations are very much like FastCGI. At least Amazon Lambda starts a VM for given function and keeps it on hand, re-using it for the same function. Note the PDF of the AWS Lambda security overview I posted above. It’s the same thing as FastCGI just starts a bunch of VMs: one or more per function.
A nightmare that the BEAM maintainers specifically call out as not happening:
We will not accept patches that add mechanisms that allows a node to restrict what other connected nodes can do, for the following reasons:
“Almost secure” is not any better than “definitely not secure”. You still cannot allow untrusted nodes to connect. (To reach the level of complete security is very hard for a protocol that was not designed for that in the beginning.)
We don’t want code bloat and code that makes the Erlang distribution slower even for applications that don’t use the new features.
If you still want to improve the security, please write an EEP first. It would probably be more fruitful to design an entire new protocol (independent of the current Erlang distribution), designed with security in mind from the ground up.
I think that’s not even all that would be needed. This is about node-to-node security. Currently compromising one node in cluster means compromising all nodes. But for replacing OS-level sandboxing with BEAM one would have to have isolation between processes on the same node. That is not going to happen either.
The only reason the paying customers are even concerned with FastCGI is because of perceived UI responsiveness - they really don’t care about technical details whether processes are recreated or recycled.
Since cowboy 2.0 each request gets a separate process. In cowboy 1.0 it used to be a process per connection. But I don’t remember genservers ever being used there, all processes were started via :proc_lib to avoid genserver’s overhead.
I haven’t listened to the interview but the way you phrased the question got me thinking.
It is entirely possible that there is a disconnect in terms of perspective. When I think of serverless architecture I get my head immediately into designing/building it.
I see serverless as a way to delegate the responsibility of ops to the provider and paying for the privilege. But ultimately I’m still thinking of building the whole damn thing.
But from a business perspective the best code is the code you don’t have to write - because there is nothing for you to maintain.
Dave may be talking about a business model where customers don’t get to write their own cloud functions but instead they rent ready made cloud functions/capabilities/components.
For example, we tend to look at payment platforms as an API to a service - which they are - but we also need to acknowledge that there is an awful lot of code that we benefit from which we don’t have to write.
In that kind of world “capability (API) providers” could base their platforms fairly efficiently on the BEAM/OTP with plenty of optimization opportunities - while their paying customers simply build the browser or native clients to consume these capabilities, aggregating them with capabilities from other providers into their own unique user facing service.
It’s surprisingly, that nobody mentioned the real benefit of serverless here. IMHO its deployment. you just deploy a function and it maps to an endpoint. Therefore the BEAM could actually dominate, by starting process with a bit of business logic in it, hold state, emit events, and stop again. So I think it could grow into somekind of Platform for Modular Applications. Just provide a simple declarative way to deploy Modules into a running BEAM cluster, and its even better then what we know as Serverless today.
Our Elixir interpeter compiles to a gen_statem process. In the AWS version your Resource is the ARN (Amazon Resource Name) of your lambda function. In the Elixir interpeter a Resource is just handled by the handle_resource callback of your process. This of course can be an RPC type call to other nodes, or anything really.
We’re actually using it to orchestrate microservices, using a GUI editor to create the state machines.