Amazon Redshiftではじめるビッグデータ処理入門

第6回Redshiftクラスタを運用してみよう

今回は、本連載の最後のトピックとして、Redshiftクラスタの運用に焦点を当て、アクセス管理、およびデータの管理と運用について説明します。これまでRedshiftクラスタの起動から拡張まで説明してきましたが、起動後も定期的にデータベースに対して必要なメンテナンス作業が存在し、高いクエリパフォーマンスを持続させるために、これらも押さえておくことは運用において非常に重要です。

なお、本連載のチュートリアルをご自身で試される場合には、Redshiftクラスタを起動し、Redshiftクラスタへ接続してSQLが実行可能である状態が必要です。これらの環境を構築するためには、この連載の第3回を参考にしてください。

アクセス権の管理

最初に、Redshiftクラスタのアクセス管理について説明します。

Redshiftでは、データベースやテーブル以外に、後述するスキーマという単位でテーブルのまとまりを管理する仕組みとなっており、ユーザやユーザをまとめたグループと呼ばれる単位で、これらリソースへのアクセスを管理することができます。

なお、Redshiftのデフォルトの挙動としては、管理者権限(superuser)を持つユーザを除き、データベース内のオブジェクト(テーブルなど)を作成したユーザがそのリソースの所有者(オーナー)となり、作成したオブジェクトに対して自由にアクセスすることができることになっています。実際の運用時には、リソースの作成後に権限を追加するなどし、管理する必要が出てくるでしょう。

なお、これまでの説明の通り、RedshiftはPostgreSQLをベースに作られているため、ユーザごとやグループごとによるアクセス管理についてはPostgreSQLとほぼ同じと思ってもらって構いません。

データベースの構造

まず、Redshiftクラスタで管理できるリソースについて確認しておきましょう。

図1 Redshiftクラスタ内部のリソースの構造
図1 Redshiftクラスタ内部のリソースの構造
Databases(データベース)
Redshiftクラスタは複数のデータベースを持つことができ、データベース同士は互いに直接的なつながりを持たず独立しており、この単位で統計データ等も保存されます。なお、1クラスタにつき最大64個ものデータベースの作成が可能です。
Schemas(スキーマ)
データベースには、複数のスキーマを定義することができ、それぞれのスキーマがテーブルを保持することになります。全てのデータベースにはデフォルトのスキーマとして"public"が定義されており、特に指定しない場合は、"public"のスキーマのテーブルに対して操作していることになります。

図1のように、Redshiftクラスタ内部にはデータベースオブジェクトが用意され、その中にスキーマ単位でテーブルをグループ分けして、アクセス管理を行うことになります。また、スキーマが違えば同じテーブル名を利用することができますので、たとえば開発者ごとにスキーマを付与することで、互いの開発者の利用による影響が無くして開発することができます。

ユーザとグループ

続いてユーザとグループについて説明します図2⁠。

図2 ユーザの種別
図2 ユーザの種別
Superusers(スーパーユーザ)
全てのデータベースに対してフルのアクセス権を持つ管理者用のユーザであり、Redshiftクラスタを起動するときに指定したマスターユーザもこのスーパーユーザになります。スーパーユーザは、別のスーパーユーザ、またアクセス権に制限のある一般ユーザを作成できます。スーパーユーザは、非常に強い権限を持つため、一般ユーザの作成や権限設定時など必要な場合を除き、このユーザによる作業は避けるべきでしょう。
Users(一般ユーザ)
一般ユーザは、スーパーユーザにより作成され、データベース、スキーマ、テーブルごとに権限を設定することが可能です。通常の運用時に考えられるアプリケーションからのアクセス、またオペレータによるアクセスなどは、一般ユーザを用いると良いでしょう。
Groups(グループ)
グループには、複数のユーザを所属させることができ、このグループに対して権限を設定することができます。たとえば、営業グループとサポートグループを作成し、それぞれの部署のユーザを追加して、部署(グループ)単位でアクセス権限を設定、管理することが可能となります。

なお、ユーザはデータベース接続時の認証で照合されますが、データベース単位にユーザの設定が保持されるのではなく、全てのデータベースに共通したグローバルな設定として保持されます。

ユーザとグループによるアクセス管理の例

それでは、実際にユーザとグループを作り、アクセス権を設定してみましょう。

例として、Webアプリケーションの開発を想定し、Webアプリケーションからの接続ユーザ用のグループ(webappusers⁠⁠、管理者(webappadmins)の2つのグループを作成し、ユーザをそれぞれのグループに属するように作成します。アクセス対象のスキーマは、"webapp"とします。

グループを作成
create group webappusers;
create group webappadmins;
それぞれのグループごとにユーザを作成
-- Webアプリケーションからの接続グループ(webappusers)
create user webappuser1 password 'webAppuser1pass' in group webappusers;
create user webappuser2 password 'webAppuser2pass' in group webappusers;

-- 管理者用グループ(webappadmins)
create user webappadmin1 password 'webAppAdmin1pass' in group webappadmins;
create user webappadmin2 password 'webAppAdmin2pass' in group webappadmins;
スキーマを作成
create schema webapp;
グループごとにアクセス権を変更
-- webappusersにスキーマの参照権限を付与
grant usage on schema webapp to group webappusers;

-- webappadminsにスキーマの全権限を付与
grant all on schema webapp to group webappadmins;
各ユーザのスキーマの参照設定に、webapp, publicの両方を設定
alter user webappuser1 set search_path to webapp, public;
alter user webappuser2 set search_path to webapp, public;

alter user webappadmin1 set search_path to webapp, public;
alter user webappadmin2 set search_path to webapp, public;

これで、webappadminsグループのみスキーマの変更が可能となり、参照権限のみのwebappusersグループのユーザがテーブルを作成しようとした場合、以下のようにエラーとなります。

development=> create table users(id int, name varchar, email varchar);
ERROR:  permission denied for schema webapp

また、webappスキーマ内に作成したテーブルに対して、webappusersグループのユーザが操作できるようにするには、テーブルを作成したユーザが以下のようにGTRANTコマンドを実行して権限を与える必要があります。

-- webappusersグループに対してusersテーブルへの編集権限を付与
grant all on users to group webappusers;

このように、Redshiftではテーブルやユーザといった単位だけでなく、スキーマとグループを活用し、アクセス権を管理することが実際の運用として考えられるでしょう。

データの管理と運用

続いて、データの管理と運用について説明します。Redshiftにデータを長期に渡って蓄積し、運用していく上で、クエリのパフォーマンスを保つために、統計情報の更新、スキーマの更新などいくつか定期的に行わなければならない作業があります。ここでは、その中でも代表的なものを説明します。

統計情報のアップデート(ANALYZEコマンド)

データベースに対して、大きな変更を行った場合、テーブルの統計情報を最新化するためにANALYZEコマンドを実行する必要があります。この統計情報は、クエリプランの最適化に利用され、クエリのパフォーマンスに影響を及ぼします。テーブルのデータが空の状態で、データを初めて挿入した場合には、自動でANALYZEコマンドは実行されますが、以降は必要に応じてユーザ自身で実行する必要があります。

ANALYZEコマンドの使い方は、以下の通りです。

-- データベース全体を対象
ANALYZE;

-- 特定のテーブルを対象
ANALYZE [table-name];

-- 特定のカラムを対象
ANALYZE [table-name](column-name-1, column-name-2, ...);

上記のように、ANALYZEコマンドは、その対象としてデータベースの全テーブル、1テーブル、またテーブルの中の1カラムを指定することが可能ですが、このコマンドも実行にはリソースを多く消費することもあり、定期的にデータベース全体に対して実行する必要はありません。主に以下のタイミングでAnalyzeを行うと良いでしょう。

  • 定期的なデータのロードやアップデートの作業の後
  • 既存のテーブルに大きな変更があった場合

また、以下のようなカラムに対しては、頻繁にカラム単位にANALYZEコマンドを実行することでパフォーマンスの向上が期待できます。

  • ソートやグルーピング対象となるカラム
  • JOIN時にキーとなるカラム
  • WHERE句で用いるカラム

バキューム処理(VACUUMコマンド)

RedshiftはPostgreSQLと同様に、テーブルに対してレコードを更新(UPDATE)したり、レコードを削除(DELETE)した場合、該当するレコードに対して不要の印を付加(論理削除)し、そのレコードは実際のディスク上からは削除されません。Redshiftでは、こういったスペースの解放は自動で行うことは無く、ユーザ側が手動で行う必要があり、VACUUMコマンドにより、こういったディスク上で不要になったレコードなどのデータの削除を行うことができます。VACUUMコマンドの実行方法は、以下の通りです。

-- データベース全体を対象
VACUUM;

-- 特定のテーブルを対象
VACUUM [table-name];

さらに、Redshiftではこの不要レコードの削除に加えて、sortkeyを指定したカラムのデータをソートされた状態にアップデートする機能もあります。通常、sortkeyを指定したカラムは、初めてデータを挿入した時にはディスク上にソートされた状態で配置されるようになりますが、以降copy, update, insert等でデータの更新を行った場合、このソート状態が崩れてしまい、sortkeyを利用したSELECTクエリのパフォーマンスの劣化につながります。VACUUMコマンドでは、このソートが壊れた状態を再度ソートされた状態へとデータを再配置する処理も行います。なお、VACUUMコマンドは、以下の通りこれら二種類の処理のどちらかのみを選択して実行し、負荷をコントロールすることも可能です。

-- 削除処理のみの場合
VACUUM delete only [table-name];

-- ソート処理のみの場合
VACUUM sort only [table-name];

VACUUMコマンドで気をつけるべき点として、VACUUM対象のデータ量が多いほど、VACUUMの実行時間が長くなり、さらにその間I/Oへの負荷が非常に高くなるため、Redshiftクラスタ内の他の処理への影響が大きくなります。なお、VACUUM実行中はテーブルスキーマの変更などDDL系の処理は受け付けませんが、SELECTなどのクエリを実行することは可能です。実際の運用ではこういったことを考慮し、VACUUMを実行するタイミングとしては、定期的に行うのに加えて、データが大幅に追加された時に、Redshiftクラスタに対する処理負荷の少ない時間帯を選んで行うのが良いでしょう。

テーブルスキーマの更新

Redshiftでは、一度テーブルを作成した後のスキーマの変更に対して制約があり、カラムの属性の変更、エンコーディングの変更、distkeyやsortkeyの設定変更といったことはできません。しかしながら、このようなスキーマの変更を行いたい場合には、以下のようなステップを踏むことでdistkeyやsortkeyも含めテーブルのスキーマを更新することができます。

  • 更新後のスキーマを持つ新しいテーブルを作成
  • "INSERT INTO … SELECT"クエリにより、スキーマ変更前のテーブルから新しいテーブルへ全データをコピー
  • 既存のテーブルをDROP文で削除
  • 新しいテーブルの名前を"ALTER TABLE … RENAME"で、既存のテーブル名に変更

以下は、usersテーブルに対して変更した場合の例です。

CREATE TABLE temp_users (id int distkey, name varchar, email varchar);
INSERT INTO temp_users SELECT * FROM users;
DROP TABLE users;
ALTER TABLE temp_users RENAME TO users; 

この方法は新規のテーブルにデータを再配置することにもなるため、テーブルのスキーマを変更せず上記のステップを行った場合にはVACUUMでソート状態を最新化する機能と同じ効果があり、ソートされていないデータ量が多い場合はVACUUMよりかなり高速です。ただし、トレードオフとして、上記作業実行中はテーブルに対してデータの挿入や更新を行うことができませんので、注意してください。

今回は、Amazon Redshiftの運用に焦点を当てて、アクセス権の管理とデータの管理と運用について説明を行いました。

Amazon Redshiftのドキュメント上において、アクセス管理についてはManaging Database Securityが、データの管理と運用については、Analyzing tablesVacuuming tablesが参考になるでしょう。

最後に

今回でこの「Amazon Redshiftではじめるビッグデータ処理入門」の連載は終了となります。Amazon Redshiftの普及を目指す我々としても、記事を通して一定の成果を得られたのではないかと考えています。今回の連載は入門編ということで、主に使いはじめるための準備や初めの一歩に多く字数を費やしましたが、Amazon Redshiftはそのパフォーマンスやポテンシャル故に、まだまだ書ききれないことも多く、ぜひ具体的な利用例や高度なノウハウも含めた発展編を別の機会に紹介したいと思っています。そのような要望が多ければ、また機会をいただけるかもしれませんので、ぜひ、著者たちのtwitterアカウント@fujibee, @sockspawまでお知らせください。

最後までお読みいただきありがとうございました。


筆者が所属する Hapyrusでは、Amazon Redshift を使いはじめるための継続データインテグレーションサービスFlyData for Amazon Redshiftを提供しています。また、Amazon Redshift の導入コンサルティングも無料で行なっていますので、興味がある方はぜひお気軽に info@hapyrus.com にお問い合わせください。

おすすめ記事

記事・ニュース一覧