8 ms·
Using Rust to Scale Elixir for 11M Concurrent Users (2019)
- bobnamob 6y ago[2019]
- hugodutka 6y agoThe perfect Hacker News title has finally been crafted.
- ibraheemdev 6y agoRust, Elixir, Million, Concurrent ... all that's missing is Decentralized Web :)
- drsozesakamoto 6y agoWhat about blockchain ?
- dwaltrip 6y agoAnd “scale”!
- iExploder 6y agoscalable paradigm disrupting shift on blockchain in rust
- callamdelaney 6y agoIs it web scale?
- swat535 6y agoBetter alternative: Rust leverages the power of FP in Elixir to Scale 11M Users.
- teraflop 6y agoAs was pointed out last time it was posted: https://news.ycombinator.com/item?id=19947458 https://news.ycombinator.com/item?id=19947458
- ignoramous 6y agoA glitch in the Matrix?
- sdwolfz 6y agoA glitch in the Matrex: https://github.com/versilov/matrex https://github.com/versilov/matrex (sorry I couldn't resist)
- brightball 6y agoThe combination of Elixir and Rust has been really fascinating to watch. They compliment each other so well.
- StreamBright 6y agoYou might be thinking complement. And yes those do complement each other perfectly. The other scaling article how and why they switched from Go to Rust is pretty mind blowing too.
- mkl 6y agoThis one? https://blog.discord.com/why-discord-is-switching-from-go-to-rust-a190bbca2b1f https://blog.discord.com/why-discord-is-switching-from-go-to... Discussed extensively last year: https://news.ycombinator.com/item?id=22238335 https://news.ycombinator.com/item?id=22238335
- StreamBright 6y agoYep that one.
- ntonozzi 6y agoIt'd be interesting to see it compared to https://doc.rust-lang.org/std/collections/struct.BTreeSet.html https://doc.rust-lang.org/std/collections/struct.BTreeSet.ht.... Their skiplist description is a little funny — typically a skiplist has one element per leaf node, and you should never need to move items between buckets. Also skiplists have logarithmic layers in the number of elements, so inserting and searching are always bounded by O(log n).
- jhgg 6y agoWe needed to support arbitrary index access into the sorted set - which is why stdlib btree map doesn't work.
- c0deb0t 6y agoFor binary trees, indexing can be done by saving the subtree size of each node and doing a sort of binary search. Not sure if this is fast for B-trees that have more than 2 children nodes, though.
- Lichtso 6y agoDo you mean OSTs? https://en.wikipedia.org/wiki/Order_statistic_tree https://en.wikipedia.org/wiki/Order_statistic_tree
- ntonozzi 6y agoOh, that makes sense. I like the solution you arrived at!
- infradig 6y agoI've been using a bucketized version of skiplist for years now, I thought I invented it! Using most recently in https://github.com/infradig/trealla https://github.com/infradig/trealla (a Prolog interpreter).
- didibus 6y ago> There’s a fantastic Elixir project called Rustler. It provides nice support on the Elixir and Rust side for making a safe NIF that is well behaved and using the guarantees of Rust is guaranteed not to crash the VM or leak memory Hum, can someone talk more about these NIF and what special thing Rustler brings? What's different from just any kind of native interop, like say Java JNI ?
- bluejekyll 6y agoI can’t speak to the Rustler, but the JNI bindings for Rust are quite good. There are a lot of areas where you can still shoot yourself in the foot, lots of unsafe. But there are patterns they encourage that are very safe, like associating lifetimes to Java objects that are instantiated in the Rust code appropriately. It also has good interfaces for working with arrays and avoid some of the foot guns in traditional C JNI libraries. It’s not quite possible to have no unsafe code in JNI with Rust (in my experience) but it is very easy to isolate to very small areas of your code.
- aloukissas 6y agoThe little that I know about NIFs is that if they crash, they bring down the entire BEAM, so it's pretty risky if not done properly. But I've seen that Rust complements Elixir (via NIFs) very well.
- vvanders 6y agoMy brief understanding of NIFs is they're similar to unsafe in Rust where a bunch of VM guarantees are only held so long as the NIF is well-behaved. I believe there was also some limits on how long a NIF could execute before starving the Erlang scheduler[1]. [1] http://erlang.org/doc/man/erl_nif.html http://erlang.org/doc/man/erl_nif.html
- latch 6y agoNIFs run without most (all?) of the safety features the erlang VM provides, such as memory safety and scheduling. If the NIF crashes, the entire app (aka, VM) crashes. This is anathema to some...i dunno..philosophies? expectations? of Erlang/Elixir. NIFs written in Rust (via Rustler) should never be able to crash the VM. Unlike NIFs written in C. Rustler brings other quality of life improvements, like easier interop (decoding/encoding values to and from) and managing the cleanup of objects that live in Rust but are referenced by Elixir.
- jjice 6y agoThe most interesting thing about Discord is their ability to scale. Their product really works well in my experience, and their scale is no joke.
- ketzo 6y agoI've been using Discord on a near-daily basis for 9 years, in servers from 10 to 25,000 people, and I think I can count on two hands the number of actual breakages I have had with the product. It's honestly pretty nuts.
- johnisgood 6y agoI have been using for 2-3 years, and it had loads of breakages for me. I cannot count on two hands, need more. Europe.
- ggregoire 6y ago> I've been using Discord on a near-daily basis for 9 years Wikipedia says Discord was released 5 years ago. Am I missing something?
- ketzo 6y agoHm — maybe that’s in reference to it coming out of beta or something? I can tell you I made my first Discord server in 2015.
- Deukhoofd 6y agoI've seen it go down quite a lot. https://discordstatus.com/ https://discordstatus.com/ shows at least 5 breakages in the last week.
- 0xcoffee 6y agoI agree, I always found it strange that an app aimed for gaming really has better performance than slack/teams and their massive budgets behind them. But I never saw a company that uses discord for communication.
- transfire 6y agoI was wondering if Crystal could be used thus way too. Found this https://github.com/splattael/erl_nif.cr https://github.com/splattael/erl_nif.cr
- callamdelaney 6y agoI believe you can use almost anything as an erlang / elixir nif
- elcritch 6y agoYou can also write Elixir/BEAM NIF extensions in Nim and Zig as well using Nimler or Zigler, resp [1,2]. Also I’ve found writing native extensions for the BEAM is simpler than many other dynamic languages since it relies on immutable data. It’s roughly the same as just a function to deserialize/serialize data with some extra references to GC’ed data. Especially with dirty “NIF”s (they allow the functions to run for as long as they want without messing up the BEAM scheduler). 1: https://github.com/wltsmrz/nimler https://github.com/wltsmrz/nimler 2: https://github.com/ityonemo/zigler https://github.com/ityonemo/zigler
- secondcoming 6y agoStop raining on the rust parade!
- AlchemistCamp 6y agoIn the case of BEAM NIFs, I find Rust's compiler guarantees especially compelling. That's because a crashing NIF can take down the whole Erlang VM. If fault-tolerance is what brought you to Erlang/Elixir and OTP to begin with, as it is for many, having the server crash could be a major issue.
- elcritch 6y agoTrue, Rust has the strongest guarantees. Nim offers similar guarantees overall (checked arrays etc) and Nimler has exception checking enabled so the compilers checks if you have any possible checkable exceptions. Personally, I use Nim since it’s easier to use on embedded Linux devices by precompiling to C. Rust has some odd dependencies on the target’s C linker but doesn’t check the standard $CC or $LD variables. Zig is interesting but it offers the least memory protection.
- StreamBright 6y agoOld article: May 17, 2019. Title should reflect that.
- kilotaras 6y agoArticles SortedSet[0] is basically a pseudo-BTree with fixed depth = 2 and fixed max_size of leafs. This gives O(log n) search and O(sqrt n) inserts [1]. It would mean that insertion at beginning is worst case scenario (split + need to move all buckets), but timing of insert is actually dominated by adding size of the buckets to calculate final index. Spending a little bit of time on research, finding https://en.wikipedia.org/wiki/Order_statistic_tree https://en.wikipedia.org/wiki/Order_statistic_tree and just using G++ implementation would probably yield better result and less code to support. G++ has __gnu_pbds which add O(log n) "find_by_order" and "order_of_key" to trees, e.g. [2]. [0] https://github.com/discord/sorted_set_nif/blob/master/native/sorted_set_nif https://github.com/discord/sorted_set_nif/blob/master/native... [1] Technically O(n/max_size + max_size) but we can assume that max_size is selected to be ~sqrt n [2] https://www.ideone.com/8mzxGR https://www.ideone.com/8mzxGR
- cultofmetatron 6y agoOMG, my startup is trying to solve a similar problem. Albeit not at this scale (YET). Looks like I have a good excuse to delve back into rust
- cultofmetatron 6y agodamn, tried to pull this in as a dependency, doesnt look like it compiles on the most recent erlang versions. good reason to dig into the source this weekend.
- deleted 6y ago[deleted]