よしだのブログ

サブタイトルはありません。

Solr で使う malloc を差し替えてみたら幸せになれるかもしれない話

こんにちは!この記事は Solr Advent Calendar 2017 の1日目の記事です! https://qiita.com/advent-calendar/2017/solr

さて、最近のハードウェア、特に RAM の容量の増加と QPS の増加などに伴い、それにあった malloc が登場してきています。特に有名なのは google が作った tc malloc だったりするのですが、この malloc に差し替えた状態で MySQL を動かすとパフォーマンスが向上するという調査が合ったりします。

www.percona.com

そこで、Solr も malloc 差し替えると速くなるんじゃね?!と思い立ってやってみた、という記録です。

前提知識 : malloc について

Cで使われるメモリアロケーターのライブラリ関数。指定された分量だけメモリを確保して、確保できたメモリのポインタを返すというもの。

http://www9.plala.or.jp/sgwr-t/lib/malloc.html

色々な malloc

普段使っているのは、ほとんどは glibc malloc だと思いますが、大容量の RAM を踏まえた malloc のアルゴリズム&実装が生み出されています。

glibc malloc

RHEL などで デフォルト、デファクト・スタンダードと呼んでよいと思います。 基本的な特長は、ロックがぶつからない限りアリーナを共有するというもの。glibc malloc の仕組みを理解するには以下を見ること (長いですがめちゃくちゃおすすめです)

youtu.be

資料 https://www.slideshare.net/kosaki55tea/glibc-malloc

tcmalloc

google 製 最初っから1スレッド1アリーナでアリーナを共有しない、したがってロックがぶつかることがないので、その分速い。

TCMalloc : Thread-Caching Malloc

jemalloc

FreeBSDでは標準に採用されている malloc arena、もしくはarenaの中のサイズクラスごとにLock を持つことでスレッド間の排他を削減する

http://www.canonware.com/jemalloc/

vespa_malloc

Yahoo Inc. より公開された OSS の検索エンジン vespa で使用されている malloc vespa に最適化されている?

vespa.ai

glibc malloc の課題

スレッドが複数立つ環境において glibc malloc の性能はあまり良くないと言われている。多数のスレッドが稼働する環境では、CPU数を増やしていってもスループットが上がってこないと言われている。頻繁な malloc / free の繰り返しに特に弱く、Java などを始めとしたオブジェクト指向のプログラミング言語では、malloc / free が多くなりがち。

以下は malloc / free を10万回繰り返して、そのタイムを比較した検証結果。glibc では CPU を増やすとむしろ遅くなっている。

https://www.soum.co.jp/misc/individual/multi-thread/

検証内容

各 malloc に差し替え、それぞれパフォーマンスを計測比較しました。

  • 検索のみ実行 (更新は行わず)、予めキャッシュはウォームアップした状態で実施
  • Solr 6.4.2 を使用
  • 1 shard / 2 replica 構成、SolrCloud
  • 検索対象は、170万件、インデックスサイズは約 1.3 GB
  • 使用した malloc は以下の通り
    • glibc malloc 2.12-1.209
    • tcmalloc 1.7-5
    • jemalloc 3.4.0.3
    • vespa_malloc 6.150.49
  • 使用したサーバーは仮想マシン
    • 16 vCPU / 24GB RAM / 120GB Disk (SSD)
  • Solr のキャッシュサイズはデフォルトのまま変更なし
  • 3000 QPS の負荷を1時間かけ、トータルの QPS を計測

計測結果

各 malloc ごとのスループットは以下の通りでした。jemalloc が最も数値が良いものの、tc malloc / vespa_malloc も誤差の範疇でとても良い数字が出ました。

  • glibc malloc : 2848.91 Q/s
  • tc malloc : 3152.74 Q/s (+10%)
  • je malloc : 3174.92 Q/s (+11%)
  • vespa malloc : 3117.68 Q/s (+9%)

というわけで、malloc を置き換えをするととても速くなりそうなので、さらなる検証をかさねているところです。 今回できるだけ参考になるように、一般化した状態で計測を試みてみましたが、仮想マシンと物理マシンだったり、利用しているクラウドサービスの違いだったり、Solr や OS のバージョンの違いだったり、色々と差異はどうしてもあると思うので、是非一度、計測してみることをおすすめします。