Jocko – Kafka implemented in Golang
github.com
github.com
I know go has all the hype at the moment, but i'm curious to know what the benefits are in practice. Those real world reimplementation project make for a great benchmark.
My goals for building Jocko to start:
1. Learn more about distributed systems to the point I could build one "What I cannot build, I do not understand." sort of thing. 2. Simplify running Kafka—so remove ZK, only need to install a binary, and so on 3. Maintain compatability—so people can just drop Jocko in, Kafka clients and anything else that uses Kafka's protocol works
After that, I have some ideas on things to do but am waiting to get feedback from people. For instance, I think the configuration around setting how much disk space topics use could be better.
the downside is that in order to use something like kafka locally (afaik?) you have to run zookeeper locally as well.
For the Kafka deployment itself, you wouldn't need to install scala or java. Just download the go executable compiled for your architecture and away you go.
First, the "proof": https://days2011.scala-lang.org/sites/days2011/files/ws3-1-H.... That's a paper from Google. The memory footprint of the Go program was 501MB, the Java version 617MB, and the Scala version 293MB. Now, given that the Scala version and Java versions were so far off in memory just tells you that a bunch of it just depends on some specific things used. Most importantly, it should dispel the myth that Java uses more memory than Go. The JVM isn't perfect, but arguing that Java uses an order of magnitude more memory is simply wrong.
Java has a bad reputation for memory usage among people who have never run substantial programs because a Java hello-world (or other small programs) will often allocate itself a decently sized heap. Java programs also take a while to start up because of the JVM, but that doesn't make Java slow.
Go certainly has some good things. Structs can help with memory locality and avoiding some unnecessary pointers. But that's not going to help one with attaining an order of magnitude better memory usage.
But Go's garbage collector isn't made for memory efficiency, but rather short pause times. That can be great, but Go seems to have made the choice that shorter pause times are preferable to throughput (actually accomplishing work) or using less memory (might as well throw more RAM at the problem).
Now let's talk about Kafka specifically. It's been a while since I've looked at it, but Kafka actually doesn't keep the data on the JVM heap. It writes to the filesystem using the kernel's built-in async flushing and uses sendfile to write data directly from the OS page cache to sockets. In a lot of ways, Kafka bypasses its own runtime and just leans on the OS for the heavy lifting.
I like Go, but it isn't magical. It certainly doesn't offer an order of magnitude memory improvement over Java. Go has some great bits, but if you're thinking that you'll get an order of magnitude memory improvement, it's not there. It might even use more memory than Java.
> Java has a bad reputation for memory usage among people who have never run substantial programs because a Java hello-world (or other small programs) will often allocate itself a decently sized heap. Java programs also take a while to start up because of the JVM, but that doesn't make Java slow.
Since those "micro services" have just a few features, their memory won't grow up that much over time, so the startup memory is an important factor.
I'm not saying that Java applications can't be built to be small and fast, but its not how most of industry had thought about building them. Golang has the benefit of not having that legacy to begin with.
Rebalancing partitions isn't fast.
https://blog.golang.org/profiling-go-programs
Better and updated link for benchmark is following:
http://benchmarksgame.alioth.debian.org/u64q/compare.php?lan...
Here are web related benchmarks:
https://www.techempower.com/benchmarks/#section=data-r13&hw=...
Following link details for Java memory bloat:
https://www.cs.virginia.edu/kim/publicity/pldi09tutorials/me...
In short Java memory bloat is not myth but well known fact.
Also in Java (if not better there).
> single binary deployment
Also possible in Java
> straightforward compilation from source
ditto
> easy to contribute to
ditto
Edit: a much more expanded reply here: https://news.ycombinator.com/reply?id=13451098&goto=item%3Fi...
> Also possible in Java
Does not mean that's the default. Default matters quite a bit.
Not to mention the verbosity of Java that I guess you can use other languages on top of Java to deal with. But Go makes a lot of sense for these sorts of projects which in the past would be written in C or C++
Really? When working with Java system-level tools I always need a shell script to manage JAVA_HOME and CLASSPATH, or an OS package where the maintainer has done that for me.
I've seen these generated, but in a way that places an artificial upper bound on the number of command line arguments. Some programs like to have tons of these, so only going up to $10 doesn't cut it.
With Go I can literally just copy the binary over and execute it.
You're confusing static compilation and portability. Static compilation produces a single binary artifact that can run on the platform for which it was compiled. This doesn't imply that it will run on every (or even any) other platforms--in fact, it's not possible for a single binary to run on every platform.
Also AMPS for the commercial software version: http://www.crankuptheamps.com/
I imagine that a Go implementation would be orders of magnitude less lines of code, resource usage and tree-four times more performant.
Go is only marginally ~10% faster then Java [2]
[1] https://days2011.scala-lang.org/sites/days2011/files/ws3-1-H...
It obviously does. Java's strings and other objects representation, JNI coersions, necessary copying of buffers, common aliasing bugs in code which affects GC, bloatware of dependencies, etc, etc.
Knowledge of some principles protects one from being distracted by noise.
Care to elaborate?
You point to measurements [2] that show Go programs (for tasks that need memory to be allocated -- reverse-complement, regex-dna, k-nucleotide, binary-trees) using 2-3x less memory!
Kafka gives so much responsibility to the client that most implementations are incomplete and don't cope well with state changes (e.g. adding or removing a node, migrating partitions to an other node, etc).
So, unless you are using Java and the official client, you don't benefit from all of Kafka goodness, fault tolerance and scaling abilities.
Good to see more users of hashicorp/raft though, it's definitely the implementation that is looking to have the better long term future.
Kafka clients tend to be very resource intensive. It would be interesting to support a smaller/scalable footprint and a lower latency mode of operation.