インフラ」カテゴリーアーカイブ

HadoopからSparkへの移行

こんにちは。配信/インフラチームの佐々木です。 今回は、adstirの集計システムをHadoopからSparkに移行したお話をしたいと思います。

以前の構成

adstirでは以前はAWS上のEMRでHadoopを使って集計していました。一つの集計のフローとしては以下のようになります。

Mapper(UNIQ集計)

SQSにメッセージを送信

Reducer(UNIQ集計)

SQSにメッセージを送信

Mapper(通常集計)

SQSにメッセージを送信

Reducer(通常集計)

このシステムでは以下のような問題点があり、それを解消するために移行を計画しました。

・Hadoopのパフォーマンスがあまり良くなく、集計に時間がかかり、かつ料金的なコストもかかる。
・MapperとReducerでアプリケーションがを分ける必要があり、UNIQ集計も別で必要になるため、煩雑な仕組みになる。
・かなり昔に開発したシステムの為、利用しているサービスや構成が古く、パフォーマンス・安定性等お世辞にも良いと言えない為、最新のアーキテクチャに刷新したい。

Sparkに移行すれば、UNIQ集計を分ける必要もなく、SQSでの通知も不要になります。つまり上記のフローが一つの処理で完結するわけで、システムが大幅に簡素化し、かつ時間短縮・コスト削減するのを見込み開発をしました。

移行する集計用のソフトウェアの検討

当初はAthenaに移行する想定でしたが、Athenaは分析用のサービスで、今回のようなバッチでの集計処理には向いていないことがわかり、Hadoopから移行しやすくかつパフォーマンスの良いSparkを採用することにしました。 ですが手動での分析ではAthenaを使いたいとの要望があり、バッチ集計をSpark、分析用にAthenaを使い分けをするようにしました。

Sparkについて

Sparkとは一言で言えば「オンメモリで動くHadoop」の事で、AWSではEMRでのマネージドサービスを使うことが出来ます。 利用できる言語はScala、Python、R、Java等ですが一般的にはScalaとPythonを使うことが多いようです。Spark自体はScalaで実装されています。

採用した言語とAPI

当初はPythonで実装したのですが、テストしてみたところHadoopとあまりパフォーマンスが変わりませんでした。原因はRDDでの処理がボトルネックになっている事でした。 Sparkで使える用意されているAPIはRDD、Dataframe、Datasetの3種類があります。APIの特徴は以下のページに詳しく書かれています。

https://yubessy.hatenablog.com/entry/2016/12/11/095915 https://databricks.com/blog/2015/02/17/introducing-dataframes-in-spark-for-large-scale-data-science.html

一見PythonでDataframeを使うのが良さそうなのですが、Dataframeは色々制限がある為、複雑なデータ構造を扱う場合はRDDの方が向いています。 そこで全てScalaに書き換え、APIにRDDとDataframeを併用する実装にしました。 またSparkはExecuter(分散)とDriver(非分散)で処理が分かれており、できる限りExecuter側で処理をすればパフォーマンスが向上しますので、そこを意識して実装する事が大事でした。

結果

集計時間とコストが1/3程度になり、期待する結果を得る事が出来ました。 AWSでは集計用のマネージドサービスが他にも多々あり、これからも追加されていくと思われますので、今後もキャッチアップして行きたいと思います。

今回は以上となります。

EC2上のMySQLからRDSへの移行

こんにちは。配信/インフラチームの佐々木です。

少し前の話になりますが、Bypass(DSP)のRDBをEC2上のMySQLからからRDS(Aurora)に移行しました。 データ容量が膨大なためmysqldumpを利用した移行は出来ず、色々苦労しましたのでそう言った点を記載します。

移行時のレプリケーション構成

移行するにあたり、事前に本番のデータをRDSに移しレプリケーションさせておく必要があるのですが、移行対象のMySQLはステートメントベースのレプリケーションのため、構成としては以下のようになります。

本番のMySQL(EC2)
↓ステートメントベースでレプリケーション
レプリケーション用のMySQL(EC2)
↓行ベースでレプリケーション
Aurora

AMIイメージを利用したMySQLのレプリケーション

前述の通りEC2 to EC2のレプリケーションをmysqldumpでは出来ないため、AMIイメージでMySQLをインスタンス丸ごとコピーしレプリケーションすることで実現しました。 あまり一般的なやり方では無いのですが、イメージを取得する直前(バイナリログの最後のポジション)のポジションを探し出し、レプリケーション開始時にそのポジションを指定することで実現しました。

RDSへのレプリケーション

EC2からRDSにレプリケーションする際はDMS(Database Migration Service)を利用するのが一般的と思います。
ですがDMSを利用してのレプリケーションが上手くいかなかったため、XtraBackupというMySQL用のバックアップツールを利用してS3上にデータをバックアップし、そのデータをRDSにリストア後、レプリケーションを開始することで実現しました。 このツールはバックアップ時にバイナリログのポジションもinfoとして残るため、バイナリログの差分を探す必要もありません。XtraBackup はDMSと違いCLIでの設定になりますが、使ってみた感じでは特に難しいところはなく、バックアップ時間もmysqldumpに比べると大幅に削減できますので、大容量のDBのバックアップ時にはオススメ出来るツールです。

Auroraの設定

RDSの仕様として文字コードが一部変更されてしまっていたので、クラスターのパラメータグループで設定し直しました。
参考:https://qiita.com/reoy/items/e355debf1e2b2abd703b
またユーザ関連の設定も一部差分が出ましたが、大きな問題はありませんでした。

今回は以上となります。

DynamoDBストリームの利用

こんにちは。技術開発部・配信/インフラチームの二階堂です。 弊社DSP「Bypass」ではDynamoDBを利用しております。 今回はその機能の一つであるDynamoDBストリームを紹介したいと思います。

DynamoDBストリームとは

DynamoDBストリームはDynamoDBへの書き込み・更新・削除処理(ttlによる自動削除を含む)を最大24時間保存する機能です。 テーブル設定で「ストリーム有効」にすると保存されるようになります。 保存内容は「キーのみ」「新しいイメージ」「古いイメージ」「新旧イメージ」の4種類から選択可能で、必要な情報のみを保存することで使用料を抑えることが可能です。

ストリームレコードの保存形式

DynamoDBストリームに保存されたデータを扱うにあたり、まずはデータがどのような形式で保存されるかを説明したいと思います。低レベルAPIを利用する場合はこの知識が必須です。

DynamoDBストリームのデータは下図のように複数のシャードから構成され、シャードは複数のストリームレコードから構成されます。 ストリームレコードはDynamoDBへの書き込み処理などリクエスト一つ一つに対応します。 シャードには順番が存在し各シャードには次のシャードのidが保存されています。

(図は公式ページより引用)

ストリームレコードの取得方法

低レベルAPIを利用してデータを取得する際には次の手順で取得します。

  1. DynamoDBのテーブル名からdescribe-tableでLatestStreamArnを取得する
  2. DynamoDBStreamsのdescribe-streamで取得したLatestStreamArnからシャードのリストを取得する
  3. リストの一番最初のシャードのシャードidとLatestStreamArnを使ってget-shard-iteratorでイテレータを取得する
  4. 取得したイテレータを使ってget-recordsでストリームレコードのリストを取得する
  5. ストリームレコードを各々処理する
  6. 2で取得したシャードそれぞれに対して3~5を行う

この手順の注意点は2,4でリストを取得する時に対象が多すぎると一度に全て取得することができない点です。 手順2ではLastEvaluatedShardIdが入っていた場合、手順4ではNextShardIteratorが入っていた場合にはその値を使って再度取得する必要があります。

また、手順4ではシャードが閉じていない場合には次のストリームレコードが存在しなくてもNextShardIteratorが入っています。 そのため常時実行するタイプの処理ではない場合には、数回連続でget-recordsの結果が空だった場合にはNextShardIteratorが入っていても中断するなどの処理が必要になります。

まとめ

DynamoDBストリームはttlによる削除検知など痒いところに手が届く便利な機能ですが取得方法が複雑で躓きやすい部分でもあります。 この記事にがその一助となれば幸いです。

今回は以上となります。

ClassicLinkを使用してVPCとEC2-Classic間の相互通信を行う

こんにちは。技術開発部部長の川住です。

弊社DSP「Bypass」はシステムをAWSに移行してから5年以上が経過しました。近年ではEC2インスタンスをVPC (Virtual Private Cloud) 内に作成し運用していますが、AWSへの移行当初にVPC外(EC2-Classic)に作成したサーバがいくつか現在も稼働しており、「VPC内で稼働しているインスタンス」と、「VPC外で稼働しているインスタンス」が混在している環境となっています。今回はこのような環境で使用すると便利な「ClassicLink」という機能を紹介します。

ClassicLinkを使うとできること

  • VPC外のインスタンスと特定のVPCの相互接続

ClassicLinkを使用すると、VPC内(外)のサーバがあたかも同一のLAN上に存在するかのように、VPC外(内)のインスタンスからアクセスできるようになります。これによって、VPC外インスタンスのVPC内への移行を段階的に行えますし、移行の際のダウンタイムを減らせます。

ClassicLinkではできないこと

  • 異なるVPC間の相互接続

ClassicLinkでは、「VPC外 (EC2-Classic) 」のインスタンスと特定のVPCとの相互接続を行う機能であり、VPC間の相互接続には使用できません。このような場合には、「VPC peering」機能を使用して相互接続の設定を行う必要があります。

  • VPC外のインスタンスと、複数のVPCとの相互接続

ClassicLinkはサーバごとに相互接続を行うVPCを設定できますが、ClassicLinkで接続できるVPCは1インスタンスに対して1つだけです。複数のVPCへのアクセスを実現にするには「VPC peering」機能と、VPCのルーティング設定を組み合わせる必要があります。

ClassicLinkの使い方

ClassicLinkの設定はAWSのコンソール画面上、またはaws-cliで行えます。設定したいインスタンスを選択し、接続したいVPC名と、VPC外からの通信の際にVPC側で適用するセキュリティグループを選択します。VPC内のセキュリティグループからはVPC外のセキュリティグループは参照できないので、EC2-ClassicのIP帯などを指定したインバウンドルールを設定したセキュリティグループを作成しておく必要があります。

ClassicLink使用時の注意点

ClassicLinkは起動中のインスタンス対してのみ設定でき、停止すると設定が失われてしまうので注意が必要です。

まとめ

使用できる場面は少ないですが、ClassicLinkを使用することで、VPC内外の相互接続を簡単に行えて、それによってVPC内への移行作業の手間やダウンタイムの削減が可能です。

今回は以上となります。

SQS + Lambdaでs2sの基盤を作った話

こんにちは。技術開発部・配信/インフラチームの二階堂です。

弊社のプロダクトでは連携している効果測定ツールに対して、S2Sで通知を行う場合があります。 この通知処理を以前まではEC2上に配置したデーモンプログラムで行っていたのですが、処理の共通化・高速化・インフラ費用削減などの目的でSQS+Lambdaに移行しました。 この経験を踏まえて移行時のポイントを紹介したいと思います。

移行前のフローと問題点

  1. 通知先のURLの入ったログを通知用インスタンス(複数ある内のどれか一つ)に書き出す
  2. EC2上に配置したデーモンプログラムがログを読み込み通知を行う
  3. 同じくデーモンプログラムが通知結果のログを書き出す

問題点

  1. 常時起動のインスタンスが高価
  2. 時間帯によって通知量が変化するため通知量が多い時に時々遅延が発生する
  3. 通知漏れが発生した際にどの通知用インスタンスが原因か調査するコストが高い

SQS + Lambda のフロー

  1. 通知先のURLの入ったログをSQSに送信
  2. 定期実行されるLambda(図中a)がSQSに送られたメッセージ数(NumberOfMessageSent)に比例した数の通知用Lambda(図中b)をキック
  3. 通知用LambdaがSQSからメッセージを取得→通知→結果をS3に保存を5分間繰り返す

特徴・改善点

  • 常時起動EC2よりLambdaの方が圧倒的に安価 (問題点1)
  • 全てのログを一度SQSに送る事でそれ以降のフローを共通化し調査コストを下げた (問題点3)
  • Lambdaを2段構成にする事で通知量の変化に柔軟に対応できるようになった (問題点2)
  • 通知用Lambdaはログのパースと通知しかしていないので他の通知にも容易に対応できる

効果

  • インフラコストが約10分の1に減った
  • リリース以前には定期的に発生していた調査や再通知などの対応もほぼ無くなり安定して動作している

移行した感想

Lambdaの料金は実行時間*メモリ使用量なのでその辺を意識したコードになっていないと高い効果が得られません。 今回の処理内容はただの通知なのでメモリはあまり使わないので速度を上げる工夫として通知部分を並列化しました。 最初は並列化していなかったのですがその時は移行前とあまり費用が変わらなかったことを考えるとコスト意識の重要性が判りやすいのではないかと思います。

今回の基盤開発は並列化対応も含めて何かと初めての経験が多い開発だったので効果にしても経験にしてもとても有意義なものだったと思います。

今回は以上となります。

APIを利用したCloudWatchの設定

こんにちは。配信/インフラチームの佐々木です。

弊社ではAWS上にシステムを構築していますが、前回お話しした通り監視ツールはCloudWatchを利用するケースが増えております。 今回はAPIを利用してCloudWatchを設定する手順をご説明します。

Alarmの設定

CloudWatchの用途としてインスタンスの監視に使うケースは多いと思います。そこでインスタンスのAlarmを設定するスクリプトを作ってみました。aws-cliとbotoどちらかを利用するのですが、今回はaws-cliで実装しています。

このように引数にNameタグを指定して利用します。

インスタンスIDで指定する方がシンプルな実装になるのですが、インスタンスIDはコピーペーストする必要がありますし、Nameタグの方がワイルドカード指定も出来て便利です。またアラーム名にもNameタグが入っていた方わかりやすくて良いと思います。ただNameタグが一意である必要がありますのでその点は注意が必要です。

Dashboardの設定

CloudWatchのDashboardもAPIを利用して設定することが可能です。その手順を記載します。

APIの仕様は以下になるのですが、元になる設定が無いと難しいと思いますので、適当なDashboardから定義をコピーします。ここでは2台のインスタンスのCPU使用率とNetworkInのメトリックを登録しています。

https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_PutDashboard.html

[アクション]の[ダッシュボードの編集]を選択すると、Jsonの定義を取得できます。ここから直接変更することも可能です。

コピーしたJsonを元に編集します。インスタンスを1台増やしてサイズも倍にしてみました。

作成したJsonファイルを以下のコマンドで適用します。

完成しました。

またこちらのページに、複数インスタンスを自動で登録するスクリプトが載っております。台数や取得するパラメータが多い場合などにはかなり有用かと思います。

https://aws.amazon.com/jp/blogs/news/new-api-cloudformation-support-for-amazon-cloudwatch-dashboards/

今回は以上になります。

監視ツールの比較

こんにちは。配信/インフラチームの佐々木です。

今回は監視用ミドルウェアについて比較(と個人的な所感)について記載したいと思います。 私自身が実際に利用したことのあるツールが殆どなので、使用感なども踏まえてお話できればと思います。

Zabbix

ZabbixはラトビアのZabbix社で開発されているツールで、OSSの監視ツールではNagiosと並んでシェアが高い製品になります。Zabbixの特徴としては非常に多機能で、監視については大抵の事がZabbixで出来ますので、監視を一元管理したい場合には非常に有効なツールになります。その一方設定が複雑で、動作も他のツールと比較すると重いです。C言語/PHPで書かれており、設定ファイルがXML(GUIで設定することの方が多いと思いますが)、データストアにMysql/PostgreSQLが利用されていますが、大規模なインフラの監視の場合はRDBの知識が必要になってきます。

Nagios

NagiosはZabbixとよく比較されるツールですが、この二つは意外と差異が多い印象です。Nagiosはアラート機能に特化しているツールで、メトリクス可視化用のツール(munin等)と使い分けて利用する事が多いです。その分軽量かつ設定もシンプルで、バックエンドにデータストアの利用もありません。設定はテキストファイルに記述し、この点もGUIで管理するZabbixとは大きな違いがあります。

Munin

前述の通りNagios等と組み合わせて使われる事が多いツールですが、可視化用のツールなもののアラート通知の機能もちゃんと搭載されています。

Monit

Monitはアラート機能に特化しているツールで、導入と設定が簡単なため、カジュアルに最低限の監視だけしたい!という場合にお勧めできるツールです。一応WEBインターフェースも用意されているのですが、メトリクスを見るのにはあまり適していません。

Sensu

SensuはNagiosの問題点を解決する用途で開発されたツールで、クラウド環境に適した作りになっているのが大きな特徴です。Chef/Puppetを利用することで、エージェントをインストールするだけで監視を開始でき、オートスケール等に対応しやすいのが売りです。SensuはRubyで書かれていますが、データストアにRedis、エージェントとの通信部分にRabbitMQ、WEBインターフェースにGraphite等が使われていて、様々なミドルウェアを必要としますがそれをChef/Puppetで簡単にインストールする、というコンセプトの製品です。設定は全てJsonで行うので、この点もコードとして扱いやすいというメリットがあります。

PandraFMS

PandraFMSはスペインのArtica社で開発されているツールで、AWS等のクラウド/仮想環境への対応やスマートフォンでのWEBインターフェースを備えており、最近の環境に適した製品になっています。無償版と有償版の他にSaasがあるのが特徴で、こういった料金体系の製品はかなり珍しいかと思います。有償版があるだけに使いやすいUIを備え、設定もGUIで行います。開発言語はPerlなようです。

私は今回紹介する中でSensuとPandraFMSだけは利用経験が無いのですが、双方とも機会があれば使ってみたいと思う製品です。

Amazon CloudWatch

監視ツールというよりAWSの機能の一つなのですが、APIを利用することによりAWS以外のリソースも監視可能です。昔は使いにくかったのですが最近かなり改善されており、実際弊社でもアラート通知・メトリクス可視化でCloudWatchを利用するケースが増えています。料金がかかってしまうのが難点ではありますが、監視サーバ用にインスタンスを立てるよりも安く済むケースもありそうですし、AWSを利用している場合はぜひお勧めしたい機能です。

Makerel

はてな社で開発されているSaas型の監視ツールで、日本国内で開発されているだけに日本人向けのUIになっているのが特徴です。面白いのはサーバサイドがScala、エージェントがGo言語で書かれているのですが、エージェント部分はソースが公開されているという点です。Pluginのプルリクエストも受け付けているようで、開発に参加してみるのも面白いかもしれません。

今回は以上となります。

AWS利用におけるIAMの設計

こんにちは。配信/インフラチームの石田です。
現在DACから出向でユナイテッドでお世話になっております。
DACでも社内/サービス側両方のインフラ担当を担っております。

弊社では、AWSをDSP/SSPのサービスの基盤として利用しております。
また、AWSの利用者も、インフラチームや開発者、データ解析チームまで様々です。
「皆が同じルートアカンウトでログインし、全操作可能な状態」はセキュリティ的に問題があると考えております。

今回は、AWSのリソースアクセスコントロールを行い、セキュリティを向上する目的で導入したIAMの設計を紹介します。ルートアカウントでのAWSログインの廃止、CloudTrailでの操作ログ取得を実施するまでの過程を紹介します。

■IAMとは

IAMとは、Identity and Access Managementのことです。
ユーザーに対してAWSへのアクセスを安全に制御するための仕組みで、無料で導入できるのが魅力です。簡単に言うと、「AWSアカウントの中で、だれが何をできるかをコントロールするためのサービス」です。

■認証情報の種類

AWSにおける認証情報の種類としてはと下記の4つのクレデンシャルがあります。

  • AWSアカウントのパスワード
  • AWSアカウントのAPIキー
  • IAMユーザのパスワード
  • IAMユーザのAPIキー

■前提方針

前提条件としては、下記2つです。当然ですが、AWSルートカウントを利用しない方針でなければCloudTrailでの操作ログとして成立しません。

  • AWSルートアカウントはパスワードを変更し、利用しない。
    登録情報等の管理と請求関連操作にだけ使う。
  • AWSルートアカウントのAPIキーは利用しない。

■設計

今回弊社では、「管理者・開発者・運用者の役割を設け、開発者の自由度を考慮した設計案」を採用しました。基本的には、個人にポリシーを付与する形ではなく、グループにポリシーを付与する形式をとっております。また、ポリシーを個別に作成することも可能ですが、AWS側であらかじめ準備しているポリシーを利用します。

◉グループ
弊社では、AWS利用ユーザを3分類し、開発者の自由度を高く設計しております。

  • 管理者(Admin)
    →全サービス操作可能

  • 開発者(Developers)
    →IAM以外全サービスの操作可能

  • 運用者(Operators)
    →全サービスの参照のみ可能

◉ポリシー
今回は下記5つのポリシーを上記グループに付与する形で権限管理を行っております。

  • ”Administrator Access”
    →AWSアカウントに代わる強力な権限。全操作可能(既存)

  • ”Power User Access”
    →上記、Admin用からIAM操作権が省かれたポリシー(既存)

  • ”Read Only Access”
    →参照用ユーザ向けポリシー(既存)

  • ”ViewBilling”
    →請求情報参照用ポリシー(独自)

  • ”ChangePassword"
    →初回ログインPW変更可能ポリシー(独自)

◉グループとポリシーの関係
最終的なグループへの付与ポリシーは下記の通りです。

  • 管理者(Admin)
    ”Administrator Access”, ”ChangePassword"

  • 開発者(Developers)
    ”Power User Access”,”ChangePassword"

  • 運用者(Operators)
    ”Read Only Access”,”ChangePassword",”ViewBilling”

■設定手順

--ユーザ作成編--

1)ルートアカウントでログインする。

2)IAMに移動し、ユーザを作成する。ユーザ名を入力し、「ユーザごとにアクセスキーを生成」にチェックを入れる。
iam-05

3)「認証情報をダウンロード」を選択し、アクセスキー、シークレットキーを保管する。

4)作成したユーザを選択し、認証情報タブを開き、「パスワードの管理」を選択する。
iam-06

5)初回ログイン時に必要になるユーザのパスワードを生成する。「自動作成パスワードの割り当て」を選択する。また、「次回のサインインで新しいパスワードを作成するようにユーザに求める」にチェックを入れる。
iam-07

6)「認証情報ダウンロード」から発行したパスワードを保管する。

--ポリシー作成編--

1)ルートアカウントでログインする。

2)アカウント>請求情報に対するIAMユーザアクセスの編集を選択する。
iam-01

3)請求情報に対するIAMユーザアクセスの「IAMアクセスのアクティブ化」にチェックする。
iam-02

4)IAMに移動し、ViewBillingポリシーの作成を行う。

5)ポリシーの作成>Policy Generatorを選択する。

6)アクセス許可の編集にて効果「許可」、AWSサービス「AWS Billing」、アクション「ViewAccount」「ViewBilling」にチェックを入れ, ステートメントを追加を選択する。
iam-03

7)ポリシードキュメントが作成されるので、「ポリシーの検証」を実行後、作成する。今回のポリシー名は「ViewBilling」とする。
iam-04

--グループ作成編--
1)ルートアカウントでログインする。

2)IAMに移動し、グループ>新しいグループの作成を選択する。

3)Admin には”Administrator Access”と”ChangePassword"を付与する。

4)Developersには”Power User Access”と”ChangePassword"を付与する。

5)Operatorsには”Read Only Access” と”ViewBilling”と”ChangePassword"を付与する。

--Cloud Trail編--
1)ルートアカウントでログインする。

2)Cloud Trailを選択する。
iam-07

3)証跡名、S3バケットを指定することでログ取得が可能になる。
iam-06

■まとめ

AWSのルートアカウントでのログインを行っている人もまだまだ、多いと思います。
例えば、退職者が発生する度にAWSのルートアカウントのパスワードを変更するといった運用を続けるのはどうなのでしょうか。 AWSといった責任共有モデルでは、個々のセキュリティレベルの意識によってセキュリティレベルも大きく変わってきます。 今回のIAMの導入は、ユーザ、グループ、ポリシーといったコアな機能のみで構成されており、既存のポリシーを生かしつつ、簡単に導入できます。