1.はじめに
情報システムやネットワークサービスの大規模化に伴い，データベース管理システムのスケーラピリティが重要視されるようになっている.スケーラビリティの高いデータペース管理システムの一つにKVS (Key-Value Store)がある．KVSは，データ構造の簡素化と一貫性保証の程度を下げることでスケーラピリティの向上を図っており，サーバ増設による性能向上と面障害性向上を実現している[1].また，仮想計算機を用いるクラウドコンピューティングが普及し，仮想化環境にて情報サービスが稼働する状況が増加している.仮想計算機を用いるクラウドコンピューティグを使用することにより，サーバ管理の負荷やサーバ設置スペースなどの問題の解決や，短期間でのサービスの開始を実現したりすることが可能であり，今後ますます重要性が増していくと考えられる．特に多数の仮想計算機を用いて性能のスケールアウトが可能であるKVSは仮想計算機を用いるクラウドコンピューティング環境で動作することが多いと予想され,仮想化環境におけるKVS性能の向上は重要な課題の一つであると考えられる.また,クラウド環境では単一の物理計算機上で複数のVMや複数のデータベースが稼働するマルチテナント環境であることも想定される.本研究では，KVSの一つであるCassandra[2]と，仮想計算機システムの一つであるKVMに着目し，複数VM環境におけるKVSの性能向上手法について考察する.
2. CassandraとKVM
2.1. KVS
KVSは，KeyとValueの組を書き込み，Keyを指定することでValueを得ることができるシンプルなデータ管理手法の１つである．RDBMSなどより機能が単純になっているが，高いスケーラビリティを得ることができる.  KVSの代表的な実装にCassandraがある.
2.2. Cassandra
CassandraはFacebook社が開発したKVSであり，現在はApache Software Foundationのトップレベルプロジェクトである. Amazon社のDynamo[3]の分散ハッシュテープルとGoogle社のBigTable[4]のデータモデルを併せ持ち，結果整合性の一貫性を持つ．耐障害性の高さ，ノードの非集中性，高可用性，動的に伸縮可能なスケーラビリティなどの特徴を持つ. Cassandraでは複数のノードで分散してデータを保持し，そのノードの集合はクラスタと呼ばれる. Cassandraクラスタを構成する各ノードは,トークンと呼ばれるハッシュ値が割り当てられ，リング上のハッシュ空間にトークンを元に配置される.リング上の各ノードは，ハッシュ値が自身のトークン値以下で，かつ直前のノードのトークン値より大きい範囲を担当し,その範囲のKeyとValueの組を保持する．このとき,トークン値の担当範囲をノード別に指定することで,各ノードに公平にデータ量を分散することができる. KVSの読み込み処理または書き込み処理を行う際, Keyをハッシュ関数にかけ，そのハッシュ値を担当するノードが読み込み処理や書き込み処理を実行するノードとなる.ただし,レプリカが存在する場合,それを持つノードも実行するノードの対象となる. Cassandraではデータペースの複製（レプリカ）の数を指定することが可能である.レプリカ数は初期設定では１であるが，２以上の値にすることによって耐障害性を向上させることができる．レプリカは上記の担当ノードの後続ノードに配置される. CassandraはJava言語で実装されており，起動する際にメモリ量やCPUコア数に基づきJavaヒープサイズを決定し，メモリ領域を確保している．設定されるヒープサイズにMax_heap_size(景大ヒ一プ領域)とHeap NewSize(若い世代のヒープサイズ)がある．表1にCassandraにおけるJavaヒープサイズ決定方法を示す.

2.3. Cassandraにおけるデータ保存
Cassandraシステムに保存されているデータはMemtableとSStableの二種類のテープルに保存される. Memtable はメモリ上に作成されるテープルであり, SStableはディスク上に作成されるテープルである.書き込み要求を受けた時にノードはCommitlogをディスクに書き込み,その後Memtableにデータを書き込む.そして書き込み要求に完了の返答をする. Flush命令が発行されたり，Memtableの大きさがMemtableに設定された関値を超えると，Memtableはディスクに書き込まれSStableとなる.読み込み要求受信時にはMemtableとSStableが同時に読み込まれる. SStableは主にData.db,  Index.db,  Filter.dbの3つのファイルで構成されている. Data.dbにkeyとvalueのペアといったSStableの主なデータを格納する. Index.dbけkeyとoffsetのペアが保存されており, Data.dbの各keyとvalueペアが格納されている場所へのポインタが格納されている. Filter.dbには自ノードが担当するkeyが保存されている．読み込み要求を受けた時は，SStableはFilter.db，Index.db，Data.dbの順で読み込まれる.
2.4. KVM (Kernel-based Virtual Machine)
KVMは代表的な仮想化システムの一つであり,本研究ではKVMを用いて調査を行う. KVMはLinuxカーネル内に実装されており, OSをハイババイザとして稼働する. KVMの仮想HDDの構築方法にはイメージファイルを使用するモードとパーティションを用いるモードがある.本研究では，仮想HDDはイメージファイルモードを使用し，同モードではゲストOS上のアプリケーションはゲストOSファイルシステム,仮想計算機,ホストOSファイルシステムを介してHDDへのアクセスが行われる.
2.5. KSM (Kernel Same-page Merging)
KSM[5]は各VMが利用しているページの内，同一内容のメモリページ群を１つの物理ページにまとめる機能であり，VMのページキャッシュサイズを減らすことなく利用可能な物理ページを増やすことができる. KSMはカーネル内でデーモンとして動作し，匿名ページを周期的に親測し，重複するページ群を特定してCoW方式でマージする.
2.6. ActCache
ActCache[6]手法は，特定のファイルが頻繁にアクセスされることが既知である環境にて，そのファイルを定期的にアクセスしOSのページキャッシュに格納させ続ける手法である.通常，頻繁にアクセスされるファイルはOSのページ置換アルゴリズムにより優先的にキャッシュ内に格納され，破棄されない．ただし，該当ファイル以外のファイルに対して膨大な量のアクセスが発生する様な環境では，頻繁にアクセスされる様なファイルもページキャッシュから破棄されてしまい，その様な環境では本手法が有効となる。ファイルを積極的にページキャッシュ内に格納させる別の手法としてlinux-fadviceコマンドがあるが，両手法の比較については付録にて言及する.
3.基本性能評価
本章にて，仮想化療境におけるCassandra性能の評価を行う.
3.1.測定環境
仮想計算機上でCassandraを稼働させ,クライアントPC上からYCSB(Yahoo! Cloud Serving Benchmark)[7]で得られる性能を評価した. 2台の物理計算機を使用し，1台の物理計算機上で3台の仮想計算機を起動し，合計6台の仮想計算機上でCassandraクラスタを構築した.   Cassandraのデータベースサイズは17[GB],レプリカ数１とし,各ノードが担当するデータ範囲は均等とした(各ノード約2.9[GB]のデータを保持).以下この環境をシングルテナント環境と呼ぶ。シングルテナント環境の模式図を図１に示す.また,データベースの数を３に増やし,仮想計算機2台ずつでデータベースサイズ17[GB]のCassandraクラスタを構築し，各ノードが約8.5[GB]のデータを保持する環境を構築した．この環境を以下マルチテナント環境と呼ぶ. YCSBは読込負荷100%,スレッド数18,操作数50000回，一貫性レベルONEとし，10回測定した平均を結果とした．測定環境を図1，2に示し，使用した物理計算機と仮想計算機の仕様を表2に示す.

3.2.仮想化菓塊におけるCassandra性能
シングルテナント環境とマルチテナント環境におけるCassandra性能(以下，この実験を"default"と呼ぶ)を図3の“single tenant”と“multi tenant”に,ペンチマーク中における物理計算機の平均 CPU・I/O使用率を図4に示す.図3より,マルチテナント環境ではシングルテナント環境に比べてスループットが低くなることが確認された．これは，各VMが担当するデータベースサイズがマルチテナント環境の方が大きく，これが原因でマルチテナント環境のスループットが低く，負荷が高くなったものと思われる．また，図４よりどちらの環境でもベンチマーク中におけるdisk I/O使用率が高くなることが確認された．このことから，ベンチマーク時のボトルネックは物理計算機のdisk I/Oであることが考えられる.仮想化環境におけるシングルテナント環境図 3とマルチテナント環境でのCassandra性能
3.3.ファイルアクセス回数.
前節の結果より,ボトルネックは物理計算機のdisk I/Oであることが考えられる.ここで, Cassandraのdisk I/O処理の調査としてCassandraファイルへのアクセス回数を調査した．アクセス回数は仮想計算機(ゲストOS)上のSCSIサプシステム実装を改変して観察し，各ファイルのアドレスに対して発行されたHDDアクセス命令の数を表している.すなわち, OSページキャッシュがミスし実際にHDDアクセスが生じた回数を表している.測定環境としてシングルテナント環境を使用し,１ノード上の読込負荷中におけるCassandraファイルアクセス数を観測した．測定結果を図5に示す6000 5000 4000 3000 2000 1000図５の左縦軸はファイルサイズを示し，右縦軸はファイルアクセス回数を示している.図５より, Cassandraファイルへのアクセス回数はData.dbとIndex.dbが最も多いことが確認された.よって，ボトルネックであるdisk I/O処理にはIndex.dbとData.dbへのアクセスが強く関係していることが考えられる．また，Data.dbのファイルサイズが16[GB]であるのに対してIndex.dbのファイルサイズは500[MB]と小さい. 1バイトあたりのアクセス回数で比較すると, Index.dbが8318[回/MB]であり，Data.dbが315[回/MB]であり，Index.dbの方が大きく上回っていることが分かる.このことから,既存手法であるActCache手法を用いてアクセス回数の多いIndex.dbファイルをページキャッシュに固定的に格納することにより，性能向上が可能であると考えられる.
4.提案手法
本稿では，(1)既存手法であるActCache手法を用いてIndex.dbファイルをキャッシュに載せる, (2) Javaヒープサイズを縮小してゲストOS上のページキャッシュサイズを増やす, (3) KSMを適用しホストOSページキャッシュサイズを増やす，の3手法を適用し, Cassandraの性能を向上させる手法を提案する. ActCacheは第2.6節にて紹介した手法であり，本手法により頻繁にアクセスされるIndex.dbファイルをページキャッシュに格納させ続けることによりCassandra性能の向上が期待できる．また，Javaヒープサイズの縮小は，ゲストOSページキャッシュが増えることが期待され，ActCache手法などによりページキヤッシュが効果的に使用される環境においてはメモリをJava VMのヒープに与えることよりもゲストOSのページキャッシュに与える方がより大きな性能向上を可能であると考えられる. KSMの適用は，複数のゲストOS上で同じカーネル，同じアプリケーションが起動していることから多くの重複ページを集約することでき，ホストOSページキャッシュサイズを増やすことでdisk I/O負荷の低減に繋げることが可能であると考えられる.
5.評価
本章にて，提案手法による性能の向上の評価を行う.
5.1.ヒープサイズ箱小
第3.2節のdefaultと,  CassandraのJavaヒープサイズを1/2, 1/4, 1/8と縮小した場合での性能比較を,シングルテナント環境とマルチテナント環境で行った.このとき，縮小したヒープサイズはMax_heap_sizeとHeap  NewSizeであり,測定環境とベンチマークの内容は３章の基本性能調査時と同一である.測定結果を図6に示す.図6より，シングルテナント環境においてヒープサイズを縮小すると性能が向上(defaultと比較し最大51%向上)することが確認された．これは，CassandraのJava VMがヒープ領域として確保していたメモリを減らし，仮想計算機のメモリキャッシュを増やしたことが性能向上につながったことを示しており，巨大なJava VMヒープサイズは必ずしも効果的に使用されていないと予想できる．同様に，マルチテナント環境でも性能向上が確認され，default計測と比較して最大28%の性能向上が確認された.
5.2. KSM適用
第3.2節のdefaultに対してKSMを適用し，シングルテナント環境とマルチテナント環境で性能評価を行った.このとき,前節の手法であるCassandraヒープサイズの縮小時に対してもKSMを適用した.測定環境とベンチマークの内容は３章の基本性能調査時と同ーである．測定結果を図7，8に示す．図7, 8より, KSMを適用することによりdefaultよりもスループットが向上することが確認された．これは，すべての仮想計算機上で同じアプリケーション,同じカーネルが起動しているため, KSMによるページマージングが効果的に働き，物理ページの重複削除によりホストOSのメモリキャッシュが増え，disk I/O処理が速くなったことが原因だと考えられる.また,図7, 8より，ヒープサイズを縮小していくほど，KSMによる性能向上率が減少することが確認された. default時とヒープサイズ縮小時のKSMによる共有物理ページ数について調査した．結果を図9に示す.図9より，ヒープサイズとKSMによるページマージングに相関はないことが確認された.このことから, KSMのマージ対象はJavaヒープではなく，Linuxカーネルにあると考えられる.
5.3.ページキャッシュ固定
第3.2節のdefaultに対してActCache手法を適用し,シングルテナント環境，マルチテナント環境で性能評価を行った.前節と同様にCassandraヒープサイズの縮小時に対してもActCache手法を適用した.測定環境とベンチマークの内容は３章の基本性能調査時と同一である．測定結果を図10,  11に示す．図10, 11より, Java VMヒープサイズを縮小した状態でActCache手法を用いると,同手法により性能が向上することが確認された.これは,頻繁にアクセスされるIndex.dbファイルがページキャッシュ内に破棄されることなく固定的に格納されつづけ，これにより同ファイルに起因するディスクアクセス(仮想化環境であるため仮想ディスクであるイメージファイルへのアクセス)が軽減されCassandra性能が向上したとためであると考えられる．ただし，ヒープサイズを初期設定のままActCache手法を適用すると性能が劣化することも確認された．これは，初期設定ではJava VMのヒープサイズが仮想計算機のメモリの半分を占有しており，ページキャッシュが小さくIndex.dbファイルを安定的に格納し続けることができず，同手法が性能を劣化させたと思われる.同様に，マルチテナント環境でも性能向上を確認できる．また，シングルテナント環境でのActCache手法による性能向上率は3%だったのに対し，マルチテナント環境でのActCache手法による性能向上率は最大18%となっている．このことから，Indexファイルサイズが大きくなるにつれてActCache手法による性能向上率が高くなることが分かる.
5.4.三手迭適用
前述の三手法のすべてを用いない場合と，すべてを用いる場合の性能を図12に示す.図12より,提案手法をすべて用いることにより大幅な性能向上が実現され，本計測の例にて56%の性能向上が実現されていることが分かる.
6.まとめ
本稿では，ページキャッシュ固定化，Javaヒープサイズの縮小，KSMの適用によりKVS性能を向上させる手法を提案した．そして，性能評価により提案手法の有効性を確認した．今後はさらなる性能向上を目指していく予定である.
動群
本研究はJSPS科研費25280022, 26730040,15H02696の助成を受けたものである. [1]堀内浩基,山口実靖,“KVSにおける動的性能拡研究報告マルチメディア通信と分張性の向上”散処理(DPS-154, 03, 2013) [2]  Avinash Lakshman and Prashant Malik, "Cassandra- A Decentralized Structured Storage System", LADIS 09, 2009 [3] Giuseppe DeCandia, Deniz Hastorun, Madan Jampani, Gunavardhan Kakulapati,  Avinash Lakshman, Alex Pilchin, Swaminathan Sivasubramanian, Peter Vosshall and Werner Vogels, "Dynamo: Amazon's Highly Available Key-value Store", SOSP '07, 2007 [4] Fay Chang, Jeffrey Dean, Sanjay Ghemawat, Wilson C. Hsieh, Deborah A. Wallach, Mike Burrows, Tushar E. Chandra, Andrew Fikes and Robert Gruber, " Bigtable: A Distributed Storage System for Structured Data", IOSDI '06 pages 205--218, 2006 Izik Eidus, [5] Andrea Arcangeli, Chris Wright,"Increasing by density memory using KSM",Proceedings of the Linux Symposium,2009 [6] ShoheiMiyokawa, TaikiTokuda, SaneyasuYamaguchi, "ElasticityImprovementofCassandra," ACM IMCOM (ICUIMC) 2016, The 10th International Conference Ubiquitous Information Management on and Communication, 2016 [7] Brian F. Cooper, Adam Silberstein, Erwin Tam, Raghu Ramakrishnan, Russell Sears "Benchmarking Cloud Serving Systems with YCSB” 3章のシングルテナント環境において, Index.dbをActCache手法を用いてページキャッシュ内に格納させようとした場合と，fadvice手法を用いて格納させようとした場合の性能を図13に示す. fadviceを用いる手法では, ゲスト OS 内にて 1 秒おきにPOSIX_FADV_WILLNEEDオプションをつけたlinux- fadviceコマンドを用いて*Index.dbファイルを優先的にページキャッシュ内に格納するように指示をした．この時, Javaヒープサイズは1/2として測定した．図より，fadviceを用いる手法より，ActCacheを用いる手法の方が性能向上を実現できていることが分かる. ActCache手法とfadvise手法におけるヒープサイズ1/2におけるCassandra性能の比較