— Eric Hammond (@esh) November 30, 2017
在「zetcd: running ZooKeeper apps without ZooKeeper」這邊介紹了用 etcd 當作 ZooKeeper 伺服器。程式碼在「Serve the Apache Zookeeper API but back it with an etcd cluster」這邊可以看到。
但 etcd 用 Go 寫 (省下 JVM tuning？)，可能是個不錯的誘因...
標靶是 RocksDB，號稱比 RocksDB 快好幾倍：
Based on benchmarks, Badger is at least 3.5x faster than RocksDB when doing random reads. For value sizes between 128B to 16KB, data loading is 0.86x - 14x faster compared to RocksDB, with Badger gaining significant ground as value size increases. On the flip side, Badger is currently slower for range key-value iteration, but that has a lot of room for optimization.
不過我覺得有些重要的功能在 Badger 不提供，這比起來有種橘子比蘋果的感覺... 像是 RocksDB 提供了 Transaction，而 Badger 則是直接講明他們不打算支援 Transaction：
Keep it simple, stupid. No support for transactions, versioning or snapshots -- anything that can be done outside of the store should be done outside.
This sad to see that Grumpy is mean to be a replacement of CPython 2.7 instead of CPython 3.x . I presume the code from youtube was written in python 2.x hence the reason but I hope we'll see Grumpy supporting python 3.x :)
回到原文，這次的需求主要是出自 YouTube 的需求：
The front-end server that drives youtube.com and YouTube’s APIs is primarily written in Python, and it serves millions of requests per second! YouTube’s front-end runs on CPython 2.7, so we’ve put a ton of work into improving the runtime and adapting our application to work optimally within it.
然後 Python 的 GIL 又被拿出來鞭屍：
除了 C extension 不支援外，還是有些「過於動態」的語法不支援：
compile: These dynamic features of CPython are not supported by Grumpy because Grumpy modules consist of statically compiled Go code. Supporting dynamic execution would require bundling Grumpy programs with the compilation toolchain which would be unwieldy and impractically slow.
這樣可用的範圍少不少，這個專案可以當作 YouTube 這種規模的網站所做的改善，而不是什麼可以拿來用的工具 :o
Cloudflare 這次閏秒炸掉：「How and why the leap second affected Cloudflare DNS」，影響範圍包括了 DNS query 與 HTTP request：
At peak approximately 0.2% of DNS queries to Cloudflare were affected and less than 1% of all HTTP requests to Cloudflare encountered an error.
RRDNS is written in Go and uses Go’s time.Now() function to get the time. Unfortunately, this function does not guarantee monotonicity. Go currently doesn’t offer a monotonic time source (see issue 12914 for discussion).
In this patch we allowed RRDNS to forget about current upstream performance, and let it normalize again if time skipped backwards.
應該是因為 Cloudflare 這段程式還沒遇過 leap second 造成的...
Update：被提醒後仔細看了一下，是 1.8 預設生效 (但保留選項切回來 debug)，如果沒問題的話 1.9 把舊的方式拔乾淨：
Assuming things go smoothly, we will remove stack re-scanning support when the tree opens for Go 1.9 development.
目標是解決最大的 GC pause 來源：
As of Go 1.7, the one remaining source of unbounded and potentially non-trivial stop-the-world (STW) time is stack re-scanning.
然後拿新的解法來戰，目前初步的測試看起來可以降到 50µs (== 0.05ms)：
We propose to eliminate the need for stack re-scanning by switching to a hybrid write barrier that combines a Yuasa-style deletion write barrier [Yuasa '90] and a Dijkstra-style insertion write barrier [Dijkstra '78]. Preliminary experiments show that this can reduce worst-case STW time to under 50µs, and this approach may make it practical to eliminate STW mark termination altogether.
在「runtime: eliminate stack rescanning · Issue #17503 · golang/go」這邊可以看到進度，現在已經在 master branch 上了，看起來會在 1.9 的時候被放出來... 不過 worst case 的時間上修了 XDDD
The high level summary is that this reduces worst-case STW time to about 100 µs and typical 95%ile STW time to 50 µs (assuming, of course, that the OS doesn't get in the way and that the system isn't otherwise overloaded).
但看起來應該還是很大的效能改善，尤其是 CPU bound 的應用？
Typical programs, ranging from tiny toys to large production programs, are about 30% smaller when built with Go 1.7.
由於現代 CPU 的速度與 L1/L2/... cache 有緊密關係，當 binary size 變小時，常常會伴隨著 memory access 變快 (因為 hitrate 提昇)，所以 binary size 也是效能指數蠻重要的一環。