こんにちは、南條です。
今年もあとひと月と3分の1くらいになりましたね。
皆さんにとって今年一年はどのような年だったでしょうか?
さて、今回もtech
summit2018で聞いてきたセッションについてまとめていきたいと思います。
今回紹介するのは、太田 智行さんのDA08「性能問題を起こしにくい信頼されるクラウドRDBのつくりかた」です。
このセッションは、時間としては他と同じ50分のものだったのですが、スライド数が多く、内容も濃厚であり、纏めようとするとかなりの量になりそうなので、2回に分けて投稿したいと思います。
セッションのスライドは下記のurlから閲覧できます。
性能問題を起こしにくい信頼されるクラウド RDB のつくりかた
このセッションでは、主にAzureのSQL
Databaseにおいて、スループットやレイテンシの低下といった性能問題を防ぐためにはどうすればいいか?といったことについて紹介されていました。
基本的に、性能問題への対策は、構築時に行うものと運用時と改善時に行うものがあります。
このセッション中ではこの中の構築時と運用時に行うものについて順を追って説明する形式となっていました。
本稿では、まず構築時の対策についてまとめたいと思います。
構築時
ストレージ構成の最適化
ストレージシステムのI/O性能は、それを構成するリソースそれぞれのI/O性能のうち、最も低いものになります。
スライドでは、この辺りが管のイメージが描かれていて、どれか一つのパーツの管が細いと全体の管が細くなってしまうイメージで描かれていたのが印象的でした。
Azureでストレージ構成に関わるリソースは、ディスク、ストレージアカウント、VMの3つがあり、これらのパーツの管の大きさを揃えることでそれぞれのリソースのI/Oスループットを最大化しよう、というお話です。
しかし、これらのリソースそれぞれで選べるI/Oスループットの上限は、リソースごとに異なるので、注意が必要です。
それぞれのリソースにおいて、なるべく同じ程度のI/Oスループットで揃えたり、あるいはディスクのRAID構成を作るなどして性能を向上させる必要があります。
あるいは、SQL
Database Managed Instanceを利用してこの中のディスクについて選択を自動化する方法もあります。
これは、使用するディスクをDBファイルの大きさに応じて自動調節してくれるサービスです。
さらに、SQL
Database Single Database, Elastic Pool, SQL Data Warehouse等を利用するとDBファイルまで意識せず自動で選択してくれるようになります。
こういったサービスを利用することで性能問題について考えることを少なくすることができます。
分散キーの設定
データベースにおいて、そのデータが地理的に離れた場所に飛び飛びにあると、それらを保存するストレージ間でデータ移動が発生し、ストレージの性能を大きく下げることがあります。
これは、特定の列の集計など、広範囲なデータを集めてくる際に起きることで、これによって同じような集計のクエリを送った際のコストが大きく変化します。
データ移動を最小化するためにできる対策として、データの分散ルールを設定することが挙げられます。
つまり、データ集計を行う際になるべくスムーズにデータを集めてくるために、データの分散の法則を設定し、その法則にのっとってデータを探しに行くことでデータ移動を抑えるという方法です。
この方法はさらに3つの分散ルールに分けられます。
- ハッシュ分散
- ラウンドロビン分散
- レプリケート
この中で、レプリケートは分かりやすく、全部のデータをそれぞれのストレージにコピーし、集計に利用する一つのストレージ以外は全部冗長化のために利用します。
ラウンドロビン分散は、それぞれのストレージにデータを均等に分散することを目指すもので、その分散にルールはあまりまりません。なので、他の表と結合する際はコストが大きく上がってしまうことがあります。
比べて、ハッシュ分散は、分散キーのハッシュ値によってデータを振り分けるストレージを決めるので、データは等しく分散しないかもしれませんが、そのデータが保存されるストレージを見つけるのが容易になり、結合のコストを下げることができます。
この振り分けられるデータの量の偏りをスキューと呼び、これを解決しようとすると元々の目的であった集計コストが上がったりするので、バランスを見ながらうまく両立させる必要があります。
なので、全体のデータ容量が大きいものはハッシュ分散を利用し、データ量が少ないもの、目安として2GB未満のものはラウンドロビン分散やレプリケートを使い分けるというのがガイドラインとして紹介されていました。
アクセスパスの最適化
データベース内で特定のデータを検索する際、そのデータがどこにあるか探す方法にはテーブルを全検索するものとインデックスを用いるものの二つがあります。
インデックスとは、データベース内においてどのデータが物理的にどこにあるかの目安を示す索引のことです。
なので、インデックスを設定する目的は、データベース内での検索を高速化することにあると言えます。
しかし、そのインデックスを適切に定義しておかないと、下手をすると全件検索をかけるよりも検索の効率が落ちてしまうことがあります。
なので、インデックスは適切に設定しましょう、また、その作ったインデックスはクエリできちんと利用しましょうというのがここでのお話でした。
さて、その適切なインデックスをどのように設定するかという話ですが、まず、適切なインデックスはテーブルの性能やデータの内容によって変化します。
なので、方法の目安として頻繁に利用される一意な値が入った列を対象にするべき、分布の偏りの小さいものを選ぶべきといったものはありますが、定期的にテーブルの統計情報を得て、それを元にしてどのようにインデックスを設定するかの判断を下す必要があります。
前半のまとめ
本稿では、セッション中に紹介されたRDBの構築時における性能改善の方法をまとめてきました。
その内容をそれぞれ一行でまとめると
ストレージシステムのIOPSはリソースによって合わせること
分散キーはスキューとデータ移動量のバランスを見ながら適切に設定すること
インデックスは統計情報を見ながら適切に設定すること
となります。
RDBの設定を適切に行い、性能を想定通りに発揮できることを目指しましょう!