フロムスクラッチ開発者ブログ

from scratch Engineers' Blog

運用中のRedshiftを旧世代から最新世代に移行する方法

はじめまして。

フロムスクラッチでエンジニアをしている山崎と申します。
普段はAWSを用いたインフラの運用・構築、およびコスト管理を担当しています。

今後私からは、AWSを用いたインフラに関わる「技術」「コスト管理」について、他社の方もご興味ありそうなトピックを共有させて頂ければ幸いです。

 

さて1回目のテーマは、「運用中のRedshiftを旧世代から最新世代に移行する方法」です。

2017年10月にアナウンスがあり、Redshiftにて第二世代のdc2を冠した性能を選ぶことができるようになりました。

 

Amazon Redshiftに新世代のDC2ノードが追加 – 価格はそのままで最大2倍の性能向上

https://aws.amazon.com/jp/blogs/news/amazon-redshift-dc2/

 

価格はそのままで性能が向上するなら、そりゃdc1からdc2に移行したくなるのは当然ですね。問題は”どうやってサービス影響が最も小さくなるように移行するか”ということになります。

 

移行方法のアイディアは2つあります。

 

(1)dc1のRedshiftクラスタをリサイズしてdc2にする。

(2)dc1のRedshiftクラスタの更新を止め、スナップショットを取得して復元。その後名前を入れ替える。

 

具体的に中身を見ていきます。

(1)について

こちらはシンプルですね。以下の通り、クラスタの性能をdc2にそのまま変えるだけです。

 

Redshiftダッシュボード>クラスター>対象クラスタを選択>クラスター>サイズ変更>ノードの種類をdc2にする>サイズ変更 

f:id:daisuke-yamasaki:20180301170946p:plain

f:id:daisuke-yamasaki:20180301172324p:plain

 

ただし、リサイズ中はクラスタが”Read-Only”になるので注意しましょう。で、問題はリサイズにどのくらいの時間がかかるか。2017年11月に検証した時の情報ですが、非常に時間がかかりました。具体的には、約430GBのデータがあり3ノードで運用しているクラスタのdc1→dc2のリサイズに392分の時間がかかりました。とてもじゃないですが、この間”Read-Only”にしておけません。



(2)について

こちらは若干作業に手間がかかりますが、作業時間が読めるのでお勧めします。作業時間は約1時間、うちクラスタへの接続断時間は約2分程度でした。
ただし、クラスタのエンドポイントは移行前後で同じですが、クラスタのIPアドレスは変わると推測されるので、クラスタのIPアドレスを指定して接続するシステムの場合は作業前に充分な検討をしてください。

 

1.移行対象クラスタ(名前=クラスター識別子をAとする)への更新を止める。

 

2.クラスタ(A)のスナップショットを取得する。スナップショット識別子は分かり易い名前にしましょう。

f:id:daisuke-yamasaki:20180301172422p:plain

f:id:daisuke-yamasaki:20180301172425p:plain

 

3.2で取得したスナップショットを、「ノードタイプ:dc2、クラスター識別子:スナップショット取得元と別名(Bとする)、その他の設定:同じ」で復元する。

f:id:daisuke-yamasaki:20180301172630p:plain

f:id:daisuke-yamasaki:20180301172723p:plain

 

4.Aのクラスター識別子をCにする。

f:id:daisuke-yamasaki:20180301172901p:plain

f:id:daisuke-yamasaki:20180301172904p:plain

 

5.Bのクラスター識別子をAにする。

 

6.Aへのアプリからの接続がOKであることを確認する。

 

7.Cを削除する。

f:id:daisuke-yamasaki:20180301173037p:plain

 

8.Aへの更新を開始する。




以上、「運用中のRedshiftを旧世代から最新世代に移行する方法」について書いてきました。本内容はあくまで弊社で試した内容になりますので、実施する際は必ず事前検証をお願い致します。ご覧頂きありがとうございました。

Apache ZooKeeperを内部解析してみる vol.1 〜概要とデータノード編〜

こんにちは、fukuです。

フロムスクラッチでは主にアーキテクチャー周りの仕事に従事しています。

今回から数回に分けてApache ZooKeeper(以下ZooKeeper)について記事を書いて行こうと思います。ゆくゆくはソースコードレベルで解説を行なっていけたら良いかなと思っています(不安...)。1回目の今回はZooKeeperの紹介を行なっていきます。

昨今ではApache Hadoopをはじめとし、さまざまな分散処理フレームワークのOSSがありますが、そのいくつかの分散処理のシステム管理はZooKeeperを用いて行われています。

ZooKeeperとは

f:id:fuku_dw:20171227180655p:plain

分散処理のアプリケーションではアプリケーションのロジックだけでなく、分散処理されるアプリケーションプロセス同士を協調させながら処理を行うことが重要になってきます。

ZooKeeperではそのような分散処理における協調動作を行うための分散コーディネーションサービスを提供します。

ZooKeeperはApacheのトッププロジェクトの1つであり、元々はGoogleのChubbyを元にYahooによって開発が行われました。

ZooKeeperではアプリケーションに対してAPIを提供して、APIを通して分散システムにおける構成管理や、リーダー選出、分散ロック、メッセージキューなどの用途に利用されます。

分散システムの制御

ここではZooKeeperを離れて、少し 分散システムの制御について記述します。下記の図のような一般的なHadoopなどのマスタ・ワーカの分散システムにては、以下のような事に関しての問題を考える必要があります。

f:id:fuku_dw:20171227190148p:plain

マスタ障害

マスタに障害がおこると、ワーカ対するタスクの割り当てなどが行えなくなります。マスタに障害が発生した場合には、バックアップのマスタが処理を元のマスタの役割を引き継ぐ必要があります。さらにクラスタ状態の障害前の状態に戻すためには、元のマスタの状態を知る必要があります。当然、障害がおきたマスタ上でデータを管理していると、元のマスタの状態を知ることができなくなってしまいます。

ワーカ障害

ワーカの障害では、そのワーカに割り当てられているタスクに実行が完了しなくなります。そのためマスタはワーカの障害を検知して、障害がおこったワーカに割り当てていたタスクを、別のワーカに再度割り当てる必要があります。

また部分的にタスクが実行されていたりしていると、ワーカの障害がおこった場合に、部分的に実行された内容に関するリカバリなどを考慮する必要がある場合も考えられます。

通信障害

通信障害ではネットワークが分断されてワーカが マスタから切り離されることが考えられます。この場合に問題になるのはロックなどの同期処理への影響を考える必要があることです。分断されたワーカが何かしらの資源に対する排他ロックを行なっていた場合には対象のリソースが永久に解放されなくなってしまうかもしれません。

 これらの分散システムにおける問題を扱うために ZooKeeperではさまざまな機能を提供しています。次はZooKeeperの基本的な機能について見ていきましょう。

ZooKeeperの基本

ZooKeeperではデータツリーと呼ばれるファイルシステムのような階層的なツリー構造を構成しています。ツリー構造の各ノードはznodeと呼ばれ、各znodeノードの名前は、スラッシュ(/)で区切られるパス要素によって識別されます。

以下にデータツリーの例を示します。図からわかるように一般的な木構造のデータ構造をとっており、ルートのznodeは"/app1"と"/app2"の2つの子ノードを持ってることがわかります。

f:id:fuku_dw:20171227165956p:plain

さらに各znodeにはデータを格納することができ、データはバイト配列として格納されます。そのため多くのアプリケーションではProtocol BuffersやMessage Packなどのシリアライズ を行うためのパッケージを利用してデータを格納することが多いです。

znodeのモード

znodeにはモードと呼ばれる、znodeの振る舞いを変える機構があります。代表的なモードとして以下の4つがあります。

  • PERSISTENT
  • EPHEMERAL
  • CONTAINER
  • PERSISTENT_TTL

ここではそれぞれのモードの特徴について見ていきましょう。

PERSISTENT

PERSISTENTモードは永続化されるノードです。PERSISTENTなノードを削除する場合にはノードを削除するAPIを実行して、明示的に削除を行うしかありません。

PERSISTENTなノードはアプリケーションに関わるデータを保持して、ノードを作成したプロセスがクラッシュ・終了した場合でもデータを保持しなければならない場合などに用いられます。

EPHEMERAL

EPHEMERALモードは一時的なノードとして作成されます。ノードを作成したクライアントがクラッシュ(セッションが切れる)した場合や、ZooKeeperへのセッションをクローズしたりした場合に自動的に削除されます。

EPHEMERALなノードはノードを作成したセッションが維持されて間だけ存在するアプリケーション情報データを格納する場合に利用します。具体的にはマスタ・ワーカアーキテクチャ型のシステムにおけるマスタ情報などです。マスタはEPHEMERALなノードを作成しておくことで、マスタの生存を対象のノードが存在するかどうかのチェックを行うことで行うことができます。

CONTAINER

CONTAINERモードはバージョン3.5.1から提供されており、ガベージコレクションの機能をもつノードとなります。具体的にはCONTAINERなノードの子ノードがなくなると、ZooKeeperによって対象ノードは自動的に削除されます。

クラスターに参加するノード情報をCONTAINERなノードの子のEPHEMERAノードとして管理しておき、対象のクタスター全体を終了した場合などに、クラスタ情報全体を削除するといった利用方法が考えられます。

PERSISTENT_TTL

PERSISTENT_TTLモードはバージョン3.5.3から提供されており、期限付きの一時ノードとして作成されます。ノードに設定された期限がきた場合に自動的に削除されます(子ノードがない場合などの制限はあります)。

TTLなノードを利用することによって、タイムアウトをもつセッション情報を管理したりすることができます。

上記のモードを上手に使い分けながら、分散システムの状態を管理するのは、ZooKeeperを利用するアプリケーションの役割となります。

znodeの監視と通知

znodeの存在の有無や、データの変更などデータツリーの状態をチェックするために、毎回クライアントがアクセスを行うことを考えると、ZooKeeperに対して負荷がかかることが考えられます。

そのためZooKeeperではクライアントが状態をポーリングしなくてもよいように、データツリーの変更をクライアントに対して通知する機構があります。クライアントは特定のznodeに対しての変更などを通知してもらうために、監視(Watc

her)の設定を行う必要があります。ここで注意しなければならないのは、設定された監視は1度しか通知が行われないことです。そのため何度も通知を受けたい場合などは、通知を受け取ったのちに新しい監視情報を登録する必要があります。

f:id:fuku_dw:20171227185311p:plain

ここで不安になるのが監視を設定して通知をされて時に、再度監視を設定する間に端子対象のznodeに対して変更などがあった場合です。

f:id:fuku_dw:20171227185314p:plain

監視の設定では、監視を設定した時のznodeの状態も取得できるため、上記のようなパターンでは2度目の監視の設定の時に取得できるznodeの状態を見ることによって、対象のznodeの状態が変更されているかをチェックすることができます。

おわりに

今回はZooKeeperの概要から、データノードに関しての説明を行いました。ZooKeeperではあくまで分散システムの強調動作を実現するための基本機能の実装しか行われていないので、制御のためのロジックを実装するのはアプリケーション側の役割となります。

次回は実際にZooKeeperを動かしながらZooKeeperに対して、できることを紹介していく予定です。

ではでは...

参考文献: ZooKeeperによる分散システム管理(2014/10/8 オライリージャパン)

マイクロサービスアーキテクチャと技術選定

こんにちは。

フロムスクラッチでエンジニアをしている原口と申します。

普段はアーキテクトとしてスクラムチームのサポートを行ったり、それ以外にもAWS EMR周りの管理を担当したりしています。

先日、フロムスクラッチ Advent Calendar 2017 - Qiitaにて、AWS EMRのコストと安定稼働の両立に関する記事を執筆させていただきました。もしよろしければそちらもご覧ください。

【AWS】【EMR】スポットインスタンスでの安定稼働を目指して(1/3):スポットインスタンスとは - Qiita

【AWS】【EMR】スポットインスタンスでの安定稼働を目指して(2/3):インスタンスフリートを考える - Qiita

【AWS】【EMR】スポットインスタンスでの安定稼働を目指して(3/3):処理特性と設定指針 - Qiita

 

さて、はじめてはてなブログで執筆するブログの記事、どうしようかなと思ったのですが、まあ・・・初回は真面目に書きましょうかね?

ということで、今回取り上げるのはマイクロサービスアーキテクチャと技術選定というお題でブログを書こうと思います。

 

マイクロサービスアーキテクチャとは

マイクロサービスアーキテクチャについて、ここで改めて細かく言及するつもりはありません(章末にいくつかのリンクを記載しておきます。)が、

  • アプリケーションのコンポーネントを小さな単位に分割する
  • それぞれのコンポーネントは極力疎結合の状態にし、コンポーネント間のインタラクションはAPIを通じてやりとりすることで実現する

という特徴があります。

f:id:shun-haraguchi:20180103225558p:plain

マイクロサービスアーキテクチャの図例

(出典:Microsoft Azure アーキテクチャスタイル https://docs.microsoft.com/ja-jp/azure/architecture/guide/architecture-styles/microservices

そうすることによって、例えばアプリケーションの改修を行う際にその影響範囲を小さくすることができたり、障害が発生した場合の影響範囲を小さくすることができるというメリットがあります。逆にデメリットとしては、インフラ面が細かい単位で分断されるので、管理が煩雑になることが挙げられるでしょう。

フロムスクラッチのプロダクトであるb→dash 2.0においても、このマイクロサービスアーキテクチャを採用しています。フロムスクラッチでは複数のスクラムチームで、おおよそ2週間スパンでのアジャイル開発を行っているため、マイクロサービスアーキテクチャのメリットが開発の効率化に繋がっています。

マイクロサービスアーキテクチャにおける技術選定

フロムスクラッチの各コンポーネントは、例えば"分析機能"や"レコメンド機能"といった、それ単独でお客様に価値を提供するサービスの単位で分割されています。それぞれのコンポーネント内はそれぞれのサービスごとに設計・開発していますが、プログラミング言語にはWeb系にRails+Vue.js、バッチ系にJavaやScalaなど、おおよそお決まりのパターンがあります。

 

話は少し変わりますが、私は昨年、米IBMが毎年ラスベガスで開催しているイベントInterConnect 2017に参加しました。その中で印象に残ったセッションの1つに、「Java, Node.js and Swift: Which, When, and Why?」にというセッションがありました。

このセッションはマイクロサービスモデルにおいて、どういう時にどの言語(ここではJava, Node, or Swift)を選定するべきかという内容のセッションで、ざっくり内容を述べるならば、

せっかくコンポーネント間が疎結合で、かつAPIでやりとりするのであれば、コンポーネントごとにその特性に合わせた言語選定をすれば良いのではないか。それは例えば、

  • ファイルI/OやDBとのやりとりが中心になるコンポーネント:Java
  • 外部サービスとのやりとりなどでJSONの変換が多く発生するコンポーネント:Node

といったように。(注:セッション内では言語のスペック比較を示して上記の結論を出していましたが、ここではそこまでは紹介しません。)

このセッションではアプリケーションの言語選定のみを考えていましたが、もっと攻めるならば、例えば外部サービス:メール配信サービスをスループット重視なのか価格重視なのかをサービスによって変えてみたり、といったことなど、言語に限らずもっと様々な範囲で活用できる話だと思っています。もっとも、上記のセッションでは技術的な観点だけで考察しており、その他の要素(例えば、組織の柔軟性や、コスト面などの組織やビジネスの観点)は一切考えていないので、現実的にはもっと様々な観点で判断する必要があるでしょうが・・・。

ただ、マイクロサービスアーキテクチャによって、これまでにはできなかった組み合わせや設計も実現できる可能性がある。だから、固定観念にとらわれず、もっと大胆に色んなことを考えることができるのではないかな、と思っています。

 

この章の冒頭でも述べましたが、フロムスクラッチのb→dashではおおよそお決まりのパターンがあります。それにより、必要なスキルセットをコンポーネント間である程度固定することによって、組織の柔軟性を確保している面があります。

そのため、新しい技術要素を取り入れるということは、そういった流動性を一時的に損なってしまったり(その技術要素のスキルを持った人に依存してしまう)、管理が煩雑になってしまうというデメリットもあります。

しかし、私はマイクロサービスアーキテクチャにはまだまだ可能性が眠っていると思っています。なので、アーキテクトとして固定観念にとらわれることなく大胆な発想で様々な選択肢を、しかし冷静に客観的にそれらの選択肢を評価して、その上で良いと思うものはしっかりと取り入れていきたいと思っています。

まだまだb→dashは発展途上。これからも進化していきます。もちろん使っている技術も、私たちエンジニアも。

 

今後のフロムスクラッチに益々ご期待いただければ幸いです! 

それでは、ごきげんよう!

 

参考文献