こんにちは!2019年度新入社員の飯塚です。
先日、OJTトレーナーの方から「Amazon Aurora DBに格納されているデータをビジュアライズしたい!」という要望を受け、Redash環境を構築することになりました。今回はAWSのEC2インスタンス上に構築していきましたが、構築までの流れが非常に簡潔で、作業自体はほんの30分といったところでした。
今回はその知見をまとめていきたいと思います。
実際の導入手順はこちら。
Redashとは?
Redashとは、データベースのレコードを簡単に可視化できるダッシュボードツールです。
公式サイトのトップページにも以下のような文言が掲げられています。
Redash helps you make sense of your data
Connect and query your data sources, build dashboards to visualize data and share them with your company.
可視化ツールはほかにもたくさんあると思いますが、Redashの良さは何なのか。具体的には「導入が簡単」、「対応データソースが多い」、「ビジュアルのカスタマイズ性が強い」の3点が挙げられます。
導入が簡単
AWS上にRedash環境を構築する場合は、Redash公式のAMIが用意されています(今回の手順でもこちらを利用します)。
AMIが用意されているということは、最低限の環境であればワンクリックで構築できてしまうということです。これは導入コストが小さくて非常に便利です。
対応データソースが多い
2019/8/14現在、34種類のデータソースに対応しているようです。
参考までに、別の可視化ツールの対応データソース数を見てみましょう。
- Tableau:100~
- Looker:35
- Redash:34
- Qlik Sense:17
- Metabase:16
- Superset:7
- Grafana:7
- Kibana:1(Elasticsearchのみ)
Tableauが圧倒的ですが、一方で少々学習コストが高くつきます。簡単に導入できるツールの中では、Readashの対応データソース数はトップレベルといえます。
ビジュアルのカスタマイズ性
Redashでは、ひとつのクエリに対して複数のビジュアルを作成することができ、ビジュアルを複数配置することでダッシュボードを作ります。
利用できるビジュアルには下記の種類があります。
- 折れ線グラフ
- 棒グラフ
- エリアグラフ
- 円グラフ
- 散布図
- バブルチャート
- 箱ひげ図
- コロプレスマップ
- コホート
- カウンター
- マップマーカー
- ピボットテーブル
- サンキーダイアグラム
- サンバーストシーケンス
- テーブル
- ワードクラウド
主要なものは一通り揃っていますね。
もちろん、ひとつひとつのビジュアルも細かく見た目を調整することができます。これらをダッシュボード上で組み合わせることで、見たいものを分かりやすく可視化できるのです。
導入方法
では具体的な導入方法を見ていきましょう。
最低限の導入
「とりあえずRedashだけ使えれば何でもいい!」という場合は、AWSコンソール上でEC2インスタンスを立ててみましょう。あっという間に導入できます。
- Redashの公式サイトから、リージョンがap-northeast-1(東京)であるAMI「ami-0c7d9b740e997aa69」(2019/8/20現在)を選択する。
- EC2インスタンスの作成画面に遷移するので、インスタンスタイプ「t2.small」以上を選択し「確認と作成」ボタンを押す。
- 「セキュリティグループの編集」を押し、「ルールの追加」で既知のIPアドレスからのHTTP接続を許可する。(これでブラウザからアクセスできるようになります)
- 「確認と作成」ボタンを押し、「起動」ボタンを押す。
これだけです。起動したEC2インスタンスのパブリックIPにブラウザからアクセスすると、Redashのウェルカムページが表示されます。
実際に行った導入
セキュリティ面を考慮すると、実際にはもう少し複雑な設定などが必要になります。
今回は、「すでにデータベースが存在する環境にRedashを導入する」というシチュエーションを想定しています。すでに存在しているデータベースまわりの環境は下の構成図のとおりです。
東京リージョンにVPCが立っており、2種類のアベイラビリティゾーンごとにパブリックサブネットとプライベートサブネットを切っています。データベースのインスタンスはプライベートサブネットに置かれています。データベースへは、S3のバケットに置かれたファイルからデータを取得し、Lambda関数を通じてレコードをインサートしています。また、ターミナルからAmazon Aurora DBへアクセスできるようにパブリックサブネットに踏み台サーバーとしてEC2インスタンスを立てています。
さてこの環境に対して、Redash公式のAMIからEC2インスタンスをプライベートサブネットに立て、そこへブラウザからアクセスできるようにアプリケーションロードバランサーを置くことにします。これにより出来上がる環境は下の構成図のとおりです。
これをAWSコンソール上で作成することもできますが、今回は「運用保守がしやすい」「AWSサービスの勉強になる」という観点からCloudFormationを用いて作成することにしました。
(そもそもCloudFormationってなに?という方は、公式ドキュメントを参照ください。)
すでに存在していたデータベースまわりの環境がCloudFormationで管理されていたので、新しいスタックをネストしていきます。
今回はテンプレートファイルのうち、主要な部分は次のようになりました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
AWSTemplateFormatVersion: '2010-09-09' Metadata: # 省略 Parameters: # 省略 Resources: NetworkStack: # VPC,subnet,セキュリティグループを含むスタック Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Join [ "/", [ 'https://s3-ap-northeast-1.amazonaws.com', !Ref S3BucketForTemplates, 'NetworkStack.yaml' ] ] TimeoutInMinutes: '5' Ec2Stack: # BastionEC2を含むスタック Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Join [ "/", [ 'https://s3-ap-northeast-1.amazonaws.com', !Ref S3BucketForTemplates, 'Ec2Stack.yaml' ] ] TimeoutInMinutes: '30' DatabaseStack: # AuroraDBを含むスタック Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Join [ "/", [ 'https://s3-ap-northeast-1.amazonaws.com', !Ref S3BucketForTemplates, 'DatabaseStack.yaml' ] ] TimeoutInMinutes: '30' ##### 今回新たに作るスタック ##### RedashStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Join [ "/", [ 'https://s3-ap-northeast-1.amazonaws.com', !Ref S3BucketForTemplates, 'RedashStack.yaml' ] ] TimeoutInMinutes: '30' Parameters: VpcId: !GetAtt NetworkStack.Outputs.VPC PrivateSubnetAId: !GetAtt NetworkStack.Outputs.SubnetAPrivate BastionSecurityGroupId: !GetAtt NetworkStack.Outputs.BastionSecurityGroup PublicSubnetAId: !GetAtt NetworkStack.Outputs.SubnetAPublic PublicSubnetBId: !GetAtt NetworkStack.Outputs.SubnetBPublic Outputs: # 省略 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
AWSTemplateFormatVersion: '2010-09-09' Metadata: # 省略 Parameters: VpcId: Type: AWS::EC2::VPC::Id PrivateSubnetAId: Type: AWS::EC2::Subnet::Id Ec2Name: Type: String Default: 'RedashHost' BastionSecurityGroupId: Type: AWS::EC2::SecurityGroup::Id PublicSubnetAId: Type: AWS::EC2::Subnet::Id PublicSubnetBId: Type: AWS::EC2::Subnet::Id Resources: ElasticIP: Type: 'AWS::EC2::EIP' Properties: InstanceId: !Ref RedashHost Domain: vpc RedashSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref VpcId SecurityGroupIngress: # 踏み台サーバーからのSSH接続を許可 - IpProtocol: tcp FromPort: 22 ToPort: 22 SourceSecurityGroupId: !Ref BastionSecurityGroupId Description: 'BastionHost' # ALBからのHTTP接続を許可 - IpProtocol: tcp FromPort: 80 ToPort: 80 SourceSecurityGroupId: !Ref LoadBalancerSecurityGroup Description: 'ALB' LoadBalancerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref VpcId SecurityGroupIngress: # 社内プロキシサーバーからのHTTP接続を許可 - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 'your proxy host' Description: 'Proxy' ALB: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: IpAddressType: ipv4 Scheme: internet-facing SecurityGroups: - !Ref LoadBalancerSecurityGroup Subnets: - !Ref PublicSubnetAId - !Ref PublicSubnetBId ALBListener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: DefaultActions: - Type: forward TargetGroupArn: !Ref RedashTargetGroup LoadBalancerArn: !Ref ALB Port: 80 Protocol: HTTP RedashTargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: HealthCheckIntervalSeconds: 30 HealthCheckPath: '/' HealthCheckPort: 80 HealthCheckProtocol: HTTP HealthCheckTimeoutSeconds: 5 HealthyThresholdCount: 2 Matcher: HttpCode: 200 Name: RedashTarget Port: 80 Protocol: HTTP Targets: - Id: !Ref RedashHost Port: 80 TargetType: 'instance' UnhealthyThresholdCount: 2 VpcId: !Ref VpcId RedashHost: Type: 'AWS::EC2::Instance' Properties: SubnetId: !Ref PrivateSubnetAId ImageId: # Redash公式AMI 'ami-0c7d9b740e997aa69' InstanceType: 't2.small' SecurityGroupIds: - !Ref RedashSecurityGroup Tags: - Key: Name Value: !Ref Ec2Name Outputs: RedashSecurityGroup: Value: !GetAtt RedashSecurityGroup.GroupId |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
AWSTemplateFormatVersion: '2010-09-09' Parameters: # 省略 Resources: DBSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref VPCId SecurityGroupIngress: - IpProtocol: tcp FromPort: '3306' ToPort: '3306' SourceSecurityGroupId: !Ref DefaultSecurityGroupId - IpProtocol: tcp FromPort: '3306' ToPort: '3306' SourceSecurityGroupId: !Ref BastionSecurityGroupId # RedashHostからのアクセスを許可 - IpProtocol: tcp FromPort: '3306' ToPort: '3306' SourceSecurityGroupId: !Ref RedashSecurityGroupId # 省略 Outputs: # 省略 |
ここでは以上のファイルの詳しい解説は行いませんが、要するに「構成図を文字に書き起こした」だけです。
では実際に導入作業を行ってみましょう。
- AWSのサービスから「S3」を選択。
- 規定のバケットにテンプレートファイルをアップロードする。
(今回は「親スタックはS3バケットに置かれたファイルを参照して子スタックを作る」という設定にしてあるので、このような手順を踏んでいます。) - AWSのサービスから「CloudFormation」を選択。
- 親スタックを選択し「更新する」をクリック。
(今回は親スタックに変更を加えたため、親スタックを更新しています。子スタックのみの変更の場合は、親スタックを更新する必要はありません。また既存のスタックが存在しない場合は、更新ではなく新規にスタックを作成します。) - エラーが出ずにスタックの更新が完了したら、親スタックの「リソース」>「RedashStack」>「リソース」から今回作成した「ALB」の「物理ID」をコピー。
- AWSのサービスから「EC2」を選択。
- 左のメニューから「ロードバランサー」を選択し、先ほどコピーした物理IDで検索。
- ヒットしたロードバランサーの「DNS名」をコピー。
- ブラウザのアドレスバーにDNS名をペーストしてアクセスします。
- 以下のようなウェルカムページが表示されればOK。
これでRedash環境の導入は終了です。
あとはRedash上での設定を行えば、すぐにレコードを可視化できます。
- 適当なユーザー名、メールアドレス、パスワードを入力し、管理者ユーザーを作成します。
- サインアップすると、以下のようなトップページに遷移します。
- メニューバーの右上にある設定アイコンから「+New Data Source」をクリックすると、データソースの登録を行えます。
- 任意のデータソースを登録したら、メニューバーの「Create」>「Query」からクエリを作成できます。
(作ったクエリは、メニューバーの「Queries」から確認できます。また、クエリ作成画面で「+New Visualization」をクリックすることで、ビジュアルを追加することができます。) - 任意のクエリとビジュアルを作成したら、メニューバーの「Create」>「DashBoard」からダッシュボードを作成できます。
以上です。今回は試しにアクセス解析っぽいダッシュボードを作成してみました。
文字の羅列で見るよりも、アクセス数の変化が断然分かりやすいですね!
冗長化する場合
今回はRedash用のEC2インスタンスを1台だけ作成しました。しかし可用性をより向上させるのであれば、もう1台EC2インスタンスを立てて冗長化するのが良いでしょう。
構成としては下の構成図のようなものが考えられます。
今回EC2インスタンスを配置しなかったプライベートサブネットにもインスタンスを立て、ロードバランサーによってアクセスを振り分けるというものです。構成自体は簡単ですがインスタンスを立てるのにもコストがかかるので、費用対効果を考えて導入を検討したいですね。
感想
今回は、AWS上の既存のデータベース環境に対してRedash環境を構築していきました。
導入までの流れが非常に簡潔で、すぐに使える可視化ツールとしてRedashは大変優秀だと感じました。CloudFormationを利用することで導入面だけでなく運用面でも便利になるので、導入を考えている方はぜひ挑戦してみてください(私は今回初めてCloudFormationに触れましたが、スタックのネストの際のテンプレート間での値の受け渡しなどとても勉強になりました!)。一度導入すればこの先ずっと使えるツールでもあるのでお勧めしたいと思います。
最後までお読みいただきありがとうございました。