ページキャッシュを制御したい時に使えるcachectlがpure Go実装になりました

qiita.com

以前こんな記事を書きました。ページキャッシュを制御したい場合はcpanモジュールのSys::PageCacheが便利ですが、最近流行りのGoにできればバイナリを配るだけで使えるので便利です。

Sys::PageCacheと同様のことが出来るGo製のツールとしてcubicdaiya/cachectlがあります。

github.com

cachectlはcgoを使っています。cgoを使うと以下のようないくつかの問題があります。

  • Goはクロスコンパイルが売りだが、クロスコンパイルが難しくなる
  • Go以外にもgccなどにも依存が出るので環境を用意する難易度が上がる
  • コンパイル速度が落ちる
  • コメントでCのプログラムが書かれるなど、Goだけで書かれたプログラムより複雑さが上がる
  • Goのバージョンアップに追従するのが難しくなる

cachectlで使っているCのプログラムは以下のエントリーのように非常にシンプルなものです。

tech.mercari.com

C言語で書かれているライブラリを呼び出しているとかなら、cgo依存を剥がすことは不可能ですが、cachectlの場合は数十行レベルのC言語のプログラムです。

しかもGo言語はgolang.org/x/sys/unix - GoDocを使うと、Linuxでしか動かない機能を呼び出すことができます。その場合は当たり前ですが、Go言語の特徴であるクロスコンパイルはできなくなります。

具体的に言うと、cachectlで使用している関数はいくつかありますが、以下のCの関数は

  • posix_fadvise
  • mmap
  • mincore

それぞれcgoを使わなくても、Goから直接呼び出せます。

  • unix.Fadvise
  • unix.Mmap
  • unix.Syscall(unix.SYS_MINCORE, ...)

なのでGoだけで実装出来るのでは?と思ってやってみたら普通に書き換えられました。なのでPRにして、取り込んでもらいました。

github.com

この後少し修正したものも取り込んでもらいました。

https://github.com/cubicdaiya/cachectl/pull/6github.com

これでpure Go実装のcachectlを用意することが出来ました。今のところ私自身はSys::PageCacheしか本番に投入したことがないですが、折角pure Go実装になったので、今度はcachectlを本番に投入してみたいと思います。