top | item 6714371

Two years of production Go at CloudFlare

178 points| jgrahamc | 12 years ago |blog.cloudflare.com | reply

65 comments

order
[+] tptacek|12 years ago|reply
Golang is perfect for DNS: its concurrency model matches that of DNS extremely well, its standard library is heavily informed both by Unix and by Internet protocols, and its fast and simple. That's unsurprising, since Golang's charter was to modernize C/C++, and DNS is essentially an expression of 1980's C code style.
[+] staunch|12 years ago|reply
Go is perfect for almost every kind of server!

Though handling DNS requests over UDP is pretty easy and fast in almost any language. TCP connections are much more pleasant to handle by spawning a goroutine per connection. I do assume using goroutines is slower than multiplexing though, but still plenty fast.

[+] staunch|12 years ago|reply
CloudFlare is awesome. They're living out one of my fantasies of productizing really well done front-end web serving infrastructure, which I love to see. They appear to have gathered solid team. And they're doing it with Go!

I'd love to see those libraries (sans proprietary modules) show up on GitHub!

[+] billmalarky|12 years ago|reply
>CloudFlare is awesome.

Seconded, I'll throw my website's name into the hat of "websites saved by cloudflare."

I was really skeptical of them at first but I'm really glad I decided to give them a try.

[+] alberth|12 years ago|reply
I wonder how Lua fits into the picture at CloudFlare with this Go infrastructure, since CloudFlare is also a heavy user of Lua [1] as well and key financial sponsor of LuaJIT [2].

[1] http://blog.cloudflare.com/pushing-nginx-to-its-limit-with-l...

[2] http://luajit.org/sponsors.html#sponsorship_perf

[+] dknecht|12 years ago|reply
Every request that passes through CloudFlare goes through Lua. It has how we look up and apply a customer rules to a recess. We just recently realized a non-blocking logger option for Nginx [2] using Lua and are in the process of developing a new KT library [3] in Lua.

Here are the most recent lua libraries we have open sourced... [1] https://github.com/agentzh/lua-resty-lock [2] http://github.com/cloudflare/lua-resty-logger-socket [3] http://github.com/cloudflare/lua-resty-kyototycoon

[+] eastdakota|12 years ago|reply
I would say that C, Lua, and Go are our three primary systems languages. We also use PHP for some of our frontend UI. Dabble in Python in places it makes sense, but usually not in the critical path.
[+] jbarham|12 years ago|reply
Nice writeup. Especially interesting to see that CloudFlare is using Go for its DNS service. I run a DNS hosting service (https://www.SlickDNS.com) and currently use tinydns from the djbdns suite in my name servers, but I'm writing a drop-in replacement in Go. The goal is to make it much higher performance by using multiple goroutines (tinydns is a single process).
[+] tptacek|12 years ago|reply
Have you done any analysis to see if tinydns was actually a bottleneck? The work of an authoritative DNS server is extraordinarily simple, and tinydns capitalizes on that.
[+] fizx|12 years ago|reply
I want an independent write-up of Red October! Sounds really cool.
[+] pjscott|12 years ago|reply
I'm not an expert, so take this speculation with a grain of salt, but I'd guess this is how it encrypts something in such a way as to require two people:

1. Generate a key, and use it to encrypt and sign your payload. Nothing fancy here; just plain old symmetric encryption and authentication.

2. Use Shamir's Secret Sharing to split the key into pieces. You need any two pieces to reconstruct the key. This is where the magic happens:

http://en.wikipedia.org/wiki/Shamir's_Secret_Sharing

3. Encrypt-and-sign each piece with a secret key derived from its owner's password/passphrase using a secure KDF like scrypt.

4. Throw away the keys, and put those encrypted pieces on disk.

Now you need passwords from any two people to decrypt the secret payload. Cool, right?

[+] camus2|12 years ago|reply
Very good article,though i dont use go(yet) ,that's the kind of writeup i'd like to see more on HN home page.
[+] pstuart|12 years ago|reply
The "seamless binary upgrade" part is intriguing (unless it's just a reference to the fact that binaries are self-contained (which is indeed wonderful)).
[+] free652|12 years ago|reply
I have a feeling they just change symlinks between self-contained binaries. Easy to upgrade or revert binaries.
[+] jorgem|12 years ago|reply
Pretty cool stuff. How big is the team working on these Go projects?
[+] alec|12 years ago|reply
"The guarantees needed to avoid leaving the server in a bad state when handling panics would be impossible without the defer mechanism Go provides."

I'm only passingly familiar with defer, but I understand it to be equivalent to RAII in C++, Python's with statement, Common Lisp's unwind-protect, and others - does is actually provide something more, and if so, what?

[+] pcwalton|12 years ago|reply
Go's "defer" is not equivalent to RAII. It is function-scoped rather than block-scoped and has semantics based on mutating hidden per-function mutable state at runtime. For example:

    func Foo() {
        for i := 0; i < 5; i++ {
            if Something() {
                defer Whatever()
            }
        }

        // ... the compiler can't tell how many
        // Whatever()s run here ...
    }
Compared to RAII as implemented in for example D with its "scope" statement, "defer" has much more complex semantics, inhibits refactoring since moving things to function bodies or inlining function bodies silently changes semantics, and cannot be optimized as easily, because of the dynamic aspects. IMHO, it has essentially no advantages over RAII and many disadvantages.
[+] tptacek|12 years ago|reply
It's not at all equivalent to RAII, or really any of those other examples; it's a way of clearing up the control flow of a function that needs cleanup work before it returns, but it is a fussy and error-prone way of expressing scoped resource access.

"Defer" is nice to have, and because it does less than scoped acquisition, it's easier to repurpose for other jobs; that's kind of thematic of Golang --- simple, orthogonal advances over C/Java/C++; a distinct lack of "theoretical" ambition.

[+] raybejjani|12 years ago|reply
Deferred statements will run even when the program panics so you can ensure you clean up. It's more like a finally statement in some languages.
[+] craigyk|12 years ago|reply
I do part time IT and I have repeatedly wanted a more programatically friendly DNS and DHCP solution for our small network. dnsmasq doesn't have a great high-availability story, and BIND+ISCDHCP can be quite complicated to configure for high-availability (plus BIND doesn't seem to have convenient options such as expand-hosts from dnsmasq).

Does this mean Go is ready to use to make a 'simple' forwarding/caching DNS server with the ability to have DHCP update local hostnames? How about DNSSEC validation?

[+] tptacek|12 years ago|reply
There's no official support for DNSSEC in Golang, but then, there's very very little support for DNSSEC in the real world. Which is just as well.
[+] amalag|12 years ago|reply
You can try powerdns
[+] sard420|12 years ago|reply
CloudFlare is great stuff just wish they offered SSL on their free tier, should anyone really be running without?