MapR-DBのチューニング

本記事ではMapR-DBをシステムサイドからチューニングする方法について紹介します。
MapR-DBではサーバサイドとクライアントサイド共にチューニングが可能となりますが、クライアントサイドはタブレットごとにPuts命令をペンディングさせてキャッシュするなど、デフォルトで効率よく動作するアーキテクチャになっております。
そのため、**一般的にクライアントサイドでチューニングが必要になることはありません**が、本記事ではサーバサイドとクライアントサイドそれぞれについて紹介していきます。


# サーバサイド側のチューニング

## MFSのメモリ

MapR-DBはMapR Fileserver(MFS)プロセス上に実装された機能となり、MapR-DBが利用するヒープのサイズはMFSに設定するヒープサイズと同様となります。
MFSのヒープサイズは`warden.conf`内の`service.command.mfs.heapsize.percent`で設定され、デフォルトではノード上のメモリの35%が割り当てられます。
この値を増やしてwardenを再起動するのが一番手っ取り早いチューニングとなります。

MFSのヒープサイズが不足し始めていることを知らせるサインとして、[`NODE_ALARM_HIGH_MFS_MEMORY`](https://mapr.com/docs/60/ReferenceGuide/NodeAlarms-MFS-HighMemoryAlarm.html)アラームがあります。
このアラームは設定したヒープサイズを超えてMFSがヒープサイズを確保した場合に発生します。
MFSがヒープを開放して閾値を下回るとアラームは消えますが、その後も頻繁に発生するようであれば、上述のヒープサイズの設定を増やしてwardenを再起動しましょう。

ちなみに、MapR-DBを使わない場合には`configure.sh`のオプションに`-noDB`を選択することで、ヒープサイズの設定は35% -> 20%に削減されます。

## リージョンサイズ

リージョン（MapR-DBではtabletと呼びます）のサイズの変更が効く場合もあります。
tabletのサイズが小さい場合、データはより多くのノードに配置される可能性が高くなりますので、小さいテーブルを扱う場合においては、小さいサイズのtabletが有利となる場合があります。
一方でtabletのサイズが大きいと、クライアント側でキャッシュしなければいけないtabletの数が減り、Putバッファがフラッシュする場合に必要なRPC命令の数を減らすことが出来ます。
そのため、テーブルのサイズが大きい場合には、tabletの数を大きくしたほうが良いでしょう。

リージョンサイズの変更には[`maprcli table edit -regionsizemb`](https://mapr.com/docs/60/ReferenceGuide/table-edit.html)コマンドを利用します。

## キャッシュ領域の用途ごとのサイズ変更

まず最初に、こちらのチューニングは非常に注意を払う必要がありますので、基本的には推奨されません。
が一応書いてみます。

`mfs.conf`ファイル内の`mfs.cache.lru.sizes`パラメタではキャッシュ領域のデータごとの配分を設定します。
具体的に以下のような区分けとなります。

|       パラメタ |    説明    |
|:------------------|:------------------:|
|              inode |       ファイルのinodeのキャッシュ領域       |
|              meta |        中間BTreeブロックやアロケータブロックなどのメタデータブロックのキャッシュ領域       |
|              dir |        ディレクトリやkvstore領域 |
|              valc |        リピートされるGets命令用の領域       |
|            db |       MapR-DB memindex用       |
|              small |        64KBよりも小さいファイルページ用の領域        |
|                large |         64KBよりも大きいファイルページ用の領域。この領域については指定されることはなく、上の項目を差し引いた値が割り当てられる         |


実際に適用されたサイズに関しては`mfs.out`に以下のように表示されます

```
HighLatencyTraceThresh : 3000 msCidtimeout: 3600 2018-07-12 15:36:32,7066 mfs using default cachePercentages: inode:10:log:5:dir:10:meta:10:small:20:db:19:valc:1, mfs memMB 1727 MB
```

本件の趣旨とは異なりますが、[mfs.confのドキュメント](https://mapr.com/docs/60/ReferenceGuide/mfs.conf.html)にはCLDBオンリーのノードや、CLDBが動いておらず、かつ、MapR-DBを使わないクラスタのノードに関する推奨値などが記載されているので、そのようなクラスタ/ノードを稼働させている場合には変更してみましょう。

## クライアント側に間接的に影響を与えるサーバ側のパラメタ

サーバサイド側のパラメタ中でクライアントの性能に影響を与える可能性があるものに以下があります。
ただし、これらのパラメタに関してはドキュメントでの言及もほとんどないので、使う場合は注意しましょう。
設定先のファイルは`/opt/mapr/asynchbase/asynchbase-<version>/conf/asynchbase.conf`です。

| パラメタ       |       内容 |    デフォルト値    |
|:-----------------|------------------:|:------------------:|
| fs.mapr.async.worker.threads             |              アウトバウンドな非同期リクエスト用のキューを処理するスレッド数 |        128        |
| fs.mapr.async.callback.threads           |            コールバックを処理するスレッド数 |       5       |


# クライアントサイド側のチューニング

クライアントサイド側のチューニングについては[こちら](https://mapr.com/docs/60/MapR-DB/tuning-parameters-maprdb.html)に書いてありますので、本記事ではささっと紹介します。

クライアントサイドではノード上の`/opt/mapr/hbase/hbase-<version>/conf/hbase-site.xml`か、`/opt/mapr/hadoop/hadoop-<version>/etc/hadoop/core-site.xml`に以下のパラメタの設定を行います。
両者に同一パラメタで異なる値の設定があった場合には、`hbase-site.xml`が優先されます。


| パラメタ       |       内容 |    デフォルト値    |
|:-----------------|------------------:|:------------------:|
| fs.mapr.tabletlru.size.kb             |          クライアントアプリケーション内の全てのテーブル用が利用するメタデータキャッシュのサイズ |       512KB       |
| fs.mapr.threads             |          put bufferをフラッシュする時に使うスレッド数 |       64       |
| db.mapr.putbuffer.threshold.mb           |           クライアントアプリケーション内の全てのタブレット用が利用する累積put bufferのサイズ |       32MB       |
| db.mapr.putbuffer.threshold.sec             |         アイドルなput bufferをフラッシュする前にMapR-DBが待機する時間 |        3 sec        |


# おわりに

MapR-DBの性能を引き出す上ではkeyやテーブルの設計がまず第一となりますので、本記事で紹介した内容を試す機会はあまりないかもしれませんが、すでに運用段階に入った場合のチューニングとして試してみるのは良いかもしれません。

以上です。