9 ms·
Making the Switch from Node.js to Golang
- jhou2 10y agohttps://news.ycombinator.com/item?id=11364550 https://news.ycombinator.com/item?id=11364550 Original thread based on Medium post.
- chadscira 10y agoNo mention of Cluster?? https://nodejs.org/api/cluster.html#cluster_cluster https://nodejs.org/api/cluster.html#cluster_cluster
- chadscira 10y agoNot really understanding the down votes (maybe the double question mark??), but oh well. This is a valid comment considering that the EC2 instance mentioned is a 2 core box, and there is a possibly that the node implementation didn't take advantage of both cores. - Go has multi-core support out of the box - Node.js has to be shown a little love, and has limitations. But this would have been a great use-case for Cluster. If the Node implementation was using all cores, then I wouldn't have asked this question. As it stands I don't really know what we are comparing even with all the graphs. Also we are still missing a little info on how they handled the requests. When you have a endpoint on a node server that is not a simple one, it is best to queue those before handling them (yes a additional queue). This prevents the process from choking because it just opened up NNN requests to S3. Most developers are not working with hundreds of HEAVY requests a minute, but in Node.js this usually has to be handled with care, and does not work out of the box. But if you want to pick up a shinier hammer then Go for it.
- justsumbody 10y agoWhy would I want to use a language that requires bolt-ons just for bare minimum acceptable performance, meanwhile dealing with callback/half-promise soup, no types, etc? Also, I strongly suspect that an app that has been refactored multiple times by people well versed in node.js is probably already doing something to leverage multi-core...
- mrweasel 10y ago>Not really understanding the down votes Personal opinion: Because comments like your original one are annoying as hell. They never fail to show up. Someone post an interesting article one how they solved a particular problem and someone always have to show up with these pointless comments. Not everyone will know about, in this case Cluster, and it's not relevant without an explanation. Article and blog posts about Go seems to attract comments like: You might like Rust/Elm/Elixir and "that problem could have been solved using X/Y/Z package or framework". More often than not it's missing the point, which often is people, with little or no Go experience are managing to solve really complex problems within very short time frames.
- brian-armstrong 10y agoIt helps to use the right tool for the job. Go is really perfect for this use case.
- regularfry 10y agoThe interesting question is why Node isn't. It's supposed to be fast because everything's non-blocking, right? So why is this particular use problematic? What colour are the emperor's clothes, anyway?
- deleted 10y ago[deleted]
- supermatt 10y agoso a poorly written app in tech x performs worse than a better written app in tech y. who would have thought!
- BozeWolf 10y agoAgree! It makes you wonder why they didnt try python 3.5 with async stuff, as most of their stack is based on python. Yes its not multi threaded but if the service was rewritten it might have actually performed better. Otoh: sometimes you need a good excuse to test some other technologies.
- ciokan 10y agoCare to explain why python async would have performed better? I don't see a single way in which python async would be a better alternative for the given job. I'm a python guy myself but, when it comes to async stuff, I find nodejs much better and easier to understand/follow through (even with cb madness yes). For the described job, I would have went with Elixir or Go as well yes.
- Can_Not 10y agoDoesn't really make me wonder. I haven't really seen anything about python's new async stuff that indicates it's on par with node's (reply here if you found anything, I've been looking for this information!). And if python is caught up with node, it would be at very high risk of performing the same and having another random performance gotcha. Golang is one of the natural choices to replace a nodejs application for performance reasons. It's low-level, faster, uses less memory.
- mrweasel 10y agoThat's not the message of the article. The original application wasn't poorly written. In fact it was written by people who know Javascript and refactored multiple times. The new application is written by someone that picked up Go in a few weeks. I don't see it as a criticism Node.js either, it's just that Node wasn't the right tool for the job, in this case. If you pick the correct tools and know the limitations of your tools, then it becomes less important how proficient you are with those tools (not irrelevant of cause).
- partycoder 10y agoIf I was to migrate from node.js I would do it to Elixir or Rust.
- scriptproof 10y agoWhen a request could block the server, for example a request which download or upload a big file, Node it not for you. Any concurrent language would be better. Node is perfect when a lot or requests work together, but each one in a small time or even a long time but step by step. that is my experience and I hope it will help to choose the right tool for the task.
- regularfry 10y agoThat misses the point of the article, and misses what they learnt. The point isn't that a request was blocking the server. That's exactly not what happened. The point was that they couldn't handle the timeout of the non-blocking request they were making because there were so many other non-blocking events being processed before the timeout callback could be handled. They could probably have solved this by scaling out, but I'm not going to fault their diagnosis or response.
- chadscira 10y agoThis could have been solved with a simple addition of another queue. Don't spawn off heavy requests without a throttle / queue, or else you will overload your single core. We normally don't think about this because most requests are just tiny queries / small http requests.
- ericj5 10y agoThis. It sounds like the author used a queue and worker pool with the Go version. There's nothing stopping you from doing the same thing in Node. I think a lot of people forget this sometimes and just spawn off unlimited multiple simultaneous requests in Node apps. Doesnt matter what language you're using, that's never going to turn out well
- mtberatwork 10y ago> They could probably have solved this by scaling out, but I'm not going to fault their diagnosis or response. Just want to add that EC2 instances aren't exactly cheap either when it comes down to it. I'm sure budgets are tight at Digg. Far better to first try to solve the problem with refactoring than throwing more hardware at it.
- jondubois 10y agoEvery single "Why we switched from Node.js to Go" article I've ever read is rooted in misunderstanding of Node.js - This one is no exception. The problem was that the codebase was bloated and probably time to scale up or scale out. I bet that if an experienced Node.js developer rewrote the entire service again in Node, you would also get 2x speedup. I can't believe the CTO of digg bought this but I guess ultimately, it's also about making engineers happy. Eventually Go will also reach a point where it will start lagging and then some smart engineer will conclude that you need to switch to C++! Why can't developers just admit that they don't know how to scale a service?! It's not the language that's the problem, it's you; it's always you!
- skizm 10y agoI'm not a node expert, but here is what seems like the crux of the problem: > Consequently, when any request timeouts happened, the event and its associated callback was put on an already overloaded message queue. While the timeout event might occur at 1 second, the callback wasn’t getting processed until all other messages currently on the queue, and their corresponding callback code, were finished executing (potentially seconds later). Seems pretty specific to node, no? I mean, just looking at what the article says (again, I'm not a Node or Go expert) it seems like this problem was directly alleviated by Go and the speedup wasn't because Go is closer to the metal, but ultimately had a different method of handling many async network calls.
- chadscira 10y agoYep thats what it looks like. So the take away is Go is better at handling massive amounts of open outgoing network calls. In Node.js you want to restrict this to prevent the server from choking. If they did that I bet performance would be very similar.
- wwwigham 10y agoI don't think it was alleviated directly by Go, I think it was alleviated directly by improved parallelism... By the descriptions given, their go implementation uses a worker pool to help split active work across threads, while their Node implementation did not (though in Node you'd shard across processes rather than threads) - or at least it doesn't seem like it did (despite admitting to spending a bunch of time doing processing in JS between s3 requests). Another nit: The article also implies that the height of the flame graph would indicate a performance issue, which I argue is inaccurate: Since the height of a flame graph measures stack depth, I argue it also represents abstraction. So long as most of those stacks are are equal-width, then the abstraction is low overhead (and probably has value to justify it). Generally with a flame graph you want to be making comparisons within the graph, comparing the time spent in each call (so the relative widths); not commenting on its shape in-general (though it does always make for a pretty blog post).
- criddell 10y agoI've just started learning Ruby on Rails but Go I'm thinking about Go more often and am curious about working with it. Are there Rails-like frameworks for Go? Why I try to Google that, I find lots of stories about people switching from Rails to Go, but not a lot of frameworks discussions.
- commentzorro 10y agoThere are a couple vaguely Rails like frameworks but Go definitely doesn't lend itself to immersing itself into a web framework like that. Overall they tend to be much lighter and sit closer the the Go core language itself. Here's a good list of the major frameworks for Go. https://github.com/avelino/awesome-go#web-frameworks https://github.com/avelino/awesome-go#web-frameworks Also, the complete Awesome Go list is a wonderful resource for browsing some of the best Go libraries out there.
- deleted 10y ago[deleted]
- oelmekki 10y agoHi criddell, I switched from ruby (and rails) to golang this year as my main language. If you're thinking "I'm hesitating between ruby on rails and golang", you should probably go with ruby on rails (no pun intended). Golang is more low level, and it expects you prefer conceptual simplicity over abstraction [EDIT: this is why you won't see prominent golang rails-like framework]. This also means you're supposed to already know how to architecture a web application (if that's what you want to do) and to know the techs behind it. You mention you started to learn RoR, but do you have previous and consequent experience with web development? If not, definitely use RoR, it will provide clear guidelines about how to build a web app.
- criddell 10y agoI haven't done a lot of web stuff. My day is spent mostly up to my neck in C++. I think I'm going to keep plugging away at Rails. If I ever reach a point where scale is becoming an issue, then I've got a great problem to have.
- jorangreef 10y agoWhen I think of event loop blocking, the first thing I think of is GC. I find it strange that the author doesn't mention or consider GC. They might easily have been creating too many closures in a loop (a closure per data item, instead of a single handler for all data items), or millions of long lived pointers (using a Javascript object as a hash table for caching, instead of a flat buffer-based hash table). Did the author tune the size of the libuv threadpool or did they leave it at the default of 4 threads? Also, the response times given both for Node and their new system in Go are really not that great. The results for Go are an anti-climax considering it was a rewrite. They could probably undercut both times with a better design, regardless of language. Node is a great control plane, and you can always use C++ as your data plane.
- majewsky 10y agoI would guess that the response times are severely limited by the performance of S3.
- jorangreef 10y agoI haven't worked with S3 for some time. Is latency really that high when in the same availability zone?
- LusoTycoon 10y agoS3 is based on regions. 200ms of latency is quite normal for S3, not designed with that in mind.
- 69mlgsniperdad 10y agoWhat does this even mean? She doesn't understand how Node, or even JavaScript work, spends forever creating "one-offs" and gives up, finds a relevant tutorial in Go, which worked, proving that Go was the best solution, because Go is better than Node in this situation and probably all situations, and she is good at her job and not wasteful, this article is relevant and a great read.
- codingdave 10y agoStep 1 - Learn a new technology. Step 2 - Use it until you find its achilles heel. Step 3 - Learn a new technology which doesn't have that achilles heel. Step 4 - Goto Step 2. To break this cycle, you need to appreciate that every language and library has its strengths and weaknesses. Learning what they are, and tailoring your architecture appropriately is better than jumping from one place to another every time you hit a new problem.
- merb 10y agoWould've been easier to try patching node to support multiple eventloops where you can have N event loops for N threads on the server imo.
- krob 10y agoMost all major problems with scale are due to single-process threads. Node.js had it's moment with single-process thread. Blocking will happen even with events but @ scale. He solved his issue with multiple queue-workers + messaging between. This alleviated his blocking, and some people spoke to the fact that node had a cluster workflow which could have also alleviated this issue as well. Some languages make this workflow more obvious, and some people get stuck in the general way of thinking about problems. I think this is more of an engineering problem and thinking out of the box and ultimately his direction in looking for resources & help within the general community. I think when you run into problems like these, you need to try to contact the community at large to ask about scaling, and ways scaling is generally done with these types of tasks. Thinking you're the only one who ever experiences trouble scaling is very juvenile and expresses inexperience & ultimately ego. Yes, he solved a problem, but he felt he had to uproot himself in the code already there to do it. I guess he solved his problem, but he had a quicker path very possibly, he just didn't know it existed.
- bborud 10y agoThis article is about not being able to analyze problems and only being able to express shallow solutions in terms of permutations of existing solutions without actually thinking about the underlying problem. Whether the author knows it or not. Hence, this does not describe a good argument for switching to Go. It describes a good argument for better education, training and mentoring of developers so that they become programmers rather than "random assemblers of bits and pieces".