Amazon Aurora(MySQL互換) Auto Scalingで追加されたレプリカ(Reader)インスタンスのバッファキャッシュはどうなる?

…と来れば、やっぱりAuto Scalingで追加されたレプリカ(Reader)インスタンスのバッファキャッシュ(バッファプール・バッファプールキャッシュ)が起動時にウォームアップされるのか、についても知りたいところ(?)。

というわけで、いい加減しつこいですが、検証…というには雑なので、確認をしてみました。

1. Amazon Aurora(MySQL互換) Auto Scalingの設定

いつもの通り、すでにクラスメソッドさんのDevelopers.IOに記事があります。

ありがたやありがたや。

というわけで、私の記事では部分的にスクリーンショットを載せておきます。

※以前、以下の記事を書くときに使ったスナップショットからインスタンスを復元して使いました。

クラスター画面から、Auto Scaling ポリシーを追加しようとすると、
aws_as1.png

新コンソールへのお誘いがあり、
aws_as2.png

先へ進むと見慣れない画面が。
aws_as3.png

Auto Scalingを設定するには、新コンソールでもクラスター画面から。
簡単にスケールするよう、「平均アクティブ接続数」を選択して「3」アクティブ接続を指定します。
aws_as4.png

とりあえずAuto Scalingで作成されたレプリカで確認できればいいので、上限は少な目で。
aws_as5.png

書き忘れましたが、Auto Scaling ポリシーを新規追加する前に、最低1つのレプリカ(Reader)インスタンスを作成しておきます(そうしないと怒られます)。

これで、Auto Scalingの準備ができました。

2. Auto Scalingでレプリカが自動追加されるよう負荷を掛ける

引き続き、クライアントから複数セッションで接続します(とりあえず4つぐらい)。

まずは接続。

クライアント接続
$ mysql -u mkadmin -h test-cluster.cluster-ro-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.6.10 MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

(ここで3つ追加接続)

mysql> SHOW PROCESSLIST;
+----+----------+--------------------+------+---------+------+----------------------+------------------+
| Id | User     | Host               | db   | Command | Time | State                | Info             |
+----+----------+--------------------+------+---------+------+----------------------+------------------+
|  2 | rdsadmin | localhost          | NULL | Sleep   |    2 | delayed send ok done | NULL             |
|  3 | rdsadmin | localhost          | NULL | Sleep   |    2 | cleaned up           | NULL             |
|  4 | rdsadmin | localhost          | NULL | Sleep   |   13 | cleaned up           | NULL             |
|  5 | rdsadmin | localhost          | NULL | Sleep   |  568 | delayed send ok done | NULL             |
|  6 | mkadmin  | 172.31.21.22:43318 | NULL | Query   |    0 | init                 | SHOW PROCESSLIST |
|  7 | mkadmin  | 172.31.21.22:43320 | NULL | Sleep   |   99 | cleaned up           | NULL             |
|  8 | mkadmin  | 172.31.21.22:43322 | NULL | Sleep   |   79 | cleaned up           | NULL             |
|  9 | mkadmin  | 172.31.21.22:43324 | NULL | Sleep   |    9 | cleaned up           | NULL             |
+----+----------+--------------------+------+---------+------+----------------------+------------------+
8 rows in set (0.00 sec)

各セッションで、SQLを実行していきます。

SQL(SELECT)実行
mysql> USE akptest2;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> SELECT s.member_id memb, SUM(s.total_value) tval FROM dept d, member m, sales s WHERE d.dept_id = m.dept_id AND m.member_id = s.member_id AND d.dept_name = '部門015' GROUP BY memb HAVING tval > (SELECT SUM(s2.total_value) * 0.0007 FROM dept d2, member m2, sales s2 WHERE d2.dept_id = m2.dept_id AND m2.member_id = s2.member_id AND d2.dept_name = '部門015') ORDER BY tval DESC;
+-------+---------+
| memb  | tval    |
+-------+---------+
| 28942 | 1530300 |
| 47554 | 1485800 |
(中略)
| 29294 | 1176700 |
| 70092 | 1176300 |
+-------+---------+
41 rows in set (24.33 sec)

(別セッションで)

mysql> SELECT s.member_id memb, SUM(s.total_value) tval FROM dept d, member m, sales s WHERE d.dept_id = m.dept_id AND m.member_id = s.member_id AND d.dept_name = '部門015' GROUP BY memb HAVING tval > (SELECT SUM(s2.total_value) * 0.0007 FROM dept d2, member m2, sales s2 WHERE d2.dept_id = m2.dept_id AND m2.member_id = s2.member_id AND d2.dept_name = '部門002') ORDER BY tval DESC;
(中略)
60 rows in set (0.19 sec)

すると、めでたく(?)レプリカインスタンスが自動的に追加されました!(手動で作成するのと同様、ちょっと時間が掛かりましたが。)
aws_as6.png

※1個目のレプリカインスタンスはAZ-cに作成しましたが、こちらはAZ-aに追加されました。

3. いよいよ確認

そこで、このインスタンスに直接指定で接続してみます。

自動追加されたレプリカインスタンスに接続
$ mysql -u mkadmin -h application-autoscaling-d43255f2-e133-4c84-85a1-45478224fdd2.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.6.10 MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> USE akptest2;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show variables like 'aurora_server_id';
+------------------+--------------------------------------------------------------+
| Variable_name    | Value                                                        |
+------------------+--------------------------------------------------------------+
| aurora_server_id | application-autoscaling-d43255f2-e133-4c84-85a1-45478224fdd2 |
+------------------+--------------------------------------------------------------+
1 row in set (0.01 sec)

さあ、いよいよ、バッファキャッシュがどうなっているか、確認です!
最初に発行したものと同じSQLを発行してみます。
バッファキャッシュに載っていれば、1秒未満で実行できるはずですが…。

追加インスタンスで確認
mysql> SELECT s.member_id memb, SUM(s.total_value) tval FROM dept d, member m, sales s WHERE d.dept_id = m.dept_id AND m.member_id = s.member_id AND d.dept_name = '部門015' GROUP BY memb HAVING tval > (SELECT SUM(s2.total_value) * 0.0007 FROM dept d2, member m2, sales s2 WHERE d2.dept_id = m2.dept_id AND m2.member_id = s2.member_id AND d2.dept_name = '部門015') ORDER BY tval DESC;
+-------+---------+
| memb  | tval    |
+-------+---------+
| 28942 | 1530300 |
| 47554 | 1485800 |
(中略)
| 29294 | 1176700 |
| 70092 | 1176300 |
+-------+---------+
41 rows in set (24.71 sec)

残念!!
…まあ、予想通りですね。

接続を切ってしばらく待つと、自動追加されたインスタンスは削除されます。
aws_as7.png

※私が試したときには、設定した時間よりはるかに長い時間が経過してから削除が始まりました。安全を見ているのでしょうか?

さて、プロキシが間に入り、コンテナ(多分)でDBノードが構成されるAmazon Aurora Serverlessでは、どうなるんでしょうか?


続きを読む

AWS S3上のオブジェクトのメタデータを取得する

// Groovy Version: 2.4.11 JVM: 1.8.0_144 Vendor: Oracle Corporation OS: Mac OS X
@Grab('com.amazonaws:aws-java-sdk-s3:1.11.184')
import com.amazonaws.regions.Regions
import com.amazonaws.services.s3.AmazonS3
import com.amazonaws.services.s3.AmazonS3ClientBuilder

AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
        .withRegion(Regions.AP_NORTHEAST_1)
        .build()

def bucketName = 'your-bucket-name'
def key = 'some/s3/key'

def s3metadata = s3Client.getObjectMetadata(bucketName, key)
s3metadata.properties.each { k, v ->
    if(k in ["metaClass", "class"]) return
    println "$k: $v"
}

結果

serverSideEncryption: null
ETag: bff9fd94c2d3d672213687840a21d3d4
instanceLength: 258770
userMetadata: [:]
contentDisposition: null
rawMetadata: [Accept-Ranges:bytes, Content-Length:258770, Content-Type:image/jpeg, ETag:bff9fd94c2d3d672213687840a21d3d4, Last-Modified:Fri Nov 10 18:18:39 JST 2017]
replicationStatus: null
contentRange: null
ongoingRestore: null
SSECustomerAlgorithm: null
requesterCharged: false
expirationTimeRuleId: null
storageClass: null
restoreExpirationTime: null
contentLength: 258770
lastModified: Fri Nov 10 18:18:39 JST 2017
versionId: null
cacheControl: null
SSECustomerKeyMd5: null
SSEAwsKmsKeyId: null
contentEncoding: null
SSEAlgorithm: null
contentType: image/jpeg
contentMD5: null
httpExpiresDate: null
contentLanguage: null
partCount: null
expirationTime: null

参考

続きを読む

AWS GlueでDBのデータをマスキングして出力してみる

はじめに

AWS Glueは2017年8月に発表された、フルマネージドでサーバレスなETLサービスです。
RDSからS3にデータを抽出したり、S3にあるログファイルをカタログに登録してAmazon Athenaで解析したりできます。
現在は、バージニア北部・オハイオ・オレゴンの3つのリージョンのみしかサポートされていませんが、もうまもなく東京リージョンもサポートされるのではないでしょうか。

本記事では、AWS Glueを使用してRDSインスタンスのデータを特定のカラムのみマスキングしてから、CSV形式でS3に抽出してみます!

前提

以下のRDSインスタンスが準備されているものとします。

  • MySQL RDSインスタンス

また、今回は以下のようなテーブルを使用します。
ID, ユーザ名、パスワードの3フィールドのみの簡単なテーブルです。
(まずパスワードが平文で保存されていることはありえませんが。。)

#+---+---------+------------+
#| ID| username|    password|
#+---+---------+------------+
#|  1|    alice|   alicepass|
#|  2|      bob|     bobpass|
#|  3|  charlie| charliepass|
#|  4|     dave|    davepass|
#|  5|    ellen|   ellenpass|
#+---+---------+------------+

また、事前に任意のS3バケットに以下のファイルをアップロードしておいてください。

job.py
import sys
from awsglue.transforms import *
from awsglue.utils import getResolvedOptions
from pyspark.context import SparkContext
from awsglue.context import GlueContext
from awsglue.job import Job

## @params: [JOB_NAME]
args = getResolvedOptions(sys.argv, ['JOB_NAME'])

sc = SparkContext()
glueContext = GlueContext(sc)
job = Job(glueContext)
job.init(args['JOB_NAME'], args)

# ---------- ここに書いていく ----------

job.commit()

ETL処理の作成

AWS GlueでETL処理を行うには、主に以下の手順で行います。
(DataCatalogを使用しない場合は、2と3は省略可能です。)

  1. Connectionの作成
  2. Crawlerの作成
  3. Crawlerを実行し、DataCatalogの登録
  4. Jobの作成
  5. JobのPythonスクリプトの記述
  6. Jobの実行

今回のケースでは、DataCatalogの登録にこれといったメリットが感じられないので使用しないことにします。

1. Connectionを作成する

まずはRDSへの接続情報を保持するConnectionを作成してみましょう。

  1. AWS Glueのコンソール画面の左メニューからConnectionsを選択します。
  2. Add connectionボタンをクリックします。
  3. 表示されたフォームに以下の通りに入力します。

    Connection name 任意
    Connection type Amazon RDS
    Database engine MySQL
  4. Nextをクリックします。

  5. フォームのInstance, Database name, Username, Passwordの欄を自分の環境のものに合わせて指定してください。

  6. Nextをクリックします。

  7. 問題なければFinishをクリックしてConnectionを作成します。

2. Jobを作成する

次に、ETL処理を行うJobを作成しましょう。

  1. AWS Glueのコンソール画面の左メニューからJobsを選択します。
  2. Add jobボタンをクリックします。
  3. 表示されたフォームに以下の通りに入力します。

    Name 任意
    IAM role Glue実行用のサービスロール
    This job runs An existing script that you provide
    S3 path where the script is stored 最初にアップロードしたS3のjob.pyファイル
    Temporary directory 任意のS3パス
  4. Nextをクリックします。

  5. Connectionの一覧から先ほど作成したConnectionを探し、Addをクリックします。

  6. Nextをクリックします。

  7. 問題なければFinishをクリックしてJobを作成します。

無事作成が完了するとスクリプトエディタが表示されるかと思います。

3. JobのPythonスクリプトを書く

ここからは具体的にETL処理を行うスクリプトを記述していきます。

データベースに接続する(Extract)

データベースに接続する際には、DynamicFrameというものを作成します。
AWS Glueでは、以下3つの方法で作成することができます。

create_dynamic_frame.from_catalog AWS Glueのデータカタログから作成します
create_dynamic_frame.from_rdd Resilient Distributed Dataset (RDD)から作成します
create_dynamic_frame.from_options JDBCやS3などの接続タイプを指定して作成します

今回は、DataCatalogは使用しないのでcreate_dynamic_frame.from_optionsを使用します。

glueContext.create_dynamic_frame.from_options(
    connection_type='mysql',
    connection_options={
        'url': 'JDBC_URL',
        'user': 'USER_NAME',
        'password': 'PASSWORD',
        'dbtable': 'TABLE_NAME'
    })

connection_typeは、jdbcと思ってしまうところですが、どうやらjdbcではエラーになってしまうようですので、接続先データベースのベンダー名を指定します。今回で言えば、mysqlです。
connection_optionsについては、直接記述するのもいいですが、せっかくConnectionを登録しているので、その情報を利用してみましょう。

Connectionから接続情報を取得

以下のようにして、AWS Glueに登録したConnectionの情報を取得することができます。

glueContext.extract_jdbc_conf(connection_name='CONNECTION_NAME')

この関数を使用することで、次のような情報が取れます。

url JDBCのURL
vendor vendor名
user ユーザ名
password パスワード

ただ、ここで注意があります。
AWS GlueのConnectionに登録されているJDBCのURLは、jdbc:[ベンダー名]://[ホスト名]:[ポート番号]/[データベース名](Oracleの場合は、jdbc:[ベンダー名]:thin://@[ホスト名]:[ポート番号]/[データベース名])となっているのですが、この関数で取れるURLは、jdbc:[ベンダー名]://[ホスト名]:[ポート番号]とデータベース名の部分が欠けていることに注意してください。また、Oracleのみ、jdbc:oracle:thin://@のところが、jdbc:oracle://という形で取得されるので、ここも注意してください。

この情報を用いて、以下のようにDynamicFrameを作成できます。
urlの部分は仕方なく、取得したURLにデータベース名を追加してあります。

job.py
# Connectionの情報を取得
jdbc_conf = glueContext.extract_jdbc_conf(connection_name='CONNECTION_NAME')

# DynamicFrameを作成
dynamicframe = glueContext.create_dynamic_frame.from_options(
                   connection_type='mysql',
                   connection_options={
                       'url': "{0}/{1}".format(jdbc_conf['url'], 'DB_NAME'),
                       'user': jdbc_conf['user'],
                       'password': jdbc_conf['password'],
                       'dbtable': 'TABLE_NAME'
                   })

マスキングしてみる(Transform)

次に、データのマスキングを行なってみましょう。
AWS GlueのビルトインTransformに、Mapというものがありますので、それを使ってマスキングを行います。
今回は、passwordカラムのデータをすべて****************に変えちゃいましょう。

job.py
# マスク用の関数
def mask(dynamicRecord):
    dynamicRecord['password'] = '****************'
    return dynamicRecord

# DynamicFrameにマスク用の関数を適用
masked_dynamicframe = Map.apply(frame=dynamicframe, f=mask)

データをCSV形式で出力する(Load)

最後は、データをCSV形式で書き出してみましょう。
データの書き出しは、以下3つの方法で行えます。

write_dynamic_frame.from_catalog AWS Glueのデータカタログを指定して書き出します
write_dynamic_frame.from_options JDBCやS3などの接続タイプを指定して書き出します
write_dynamic_frame.from_jdbc_conf JDBCオプションを指定して書き出します

今回は、CSV形式でS3に書き出すので、write_dynamic_frame.from_optionsを使用します。
S3のバケットは任意のものを指定してください。

job.py
# DynamicFrameをCSV形式でS3に書き出す
glueContext.write_dynamic_frame.from_options(
    frame=masked_dynamicframe,
    connection_type='s3',
    connection_options={'path': "s3://{0}/{1}".format('CSV_BACKET_NAME', 'TABLE_NAME')},
    format='csv')

最終的なコードはこのようになりました。

job.py
import sys
from awsglue.transforms import *
from awsglue.utils import getResolvedOptions
from pyspark.context import SparkContext
from awsglue.context import GlueContext
from awsglue.job import Job

# マスク用の関数
def mask(dynamicRecord):
    dynamicRecord['password'] = '****************'
    return dynamicRecord

## @params: [JOB_NAME]
args = getResolvedOptions(sys.argv, ['JOB_NAME'])

sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
job = Job(glueContext)
job.init(args['JOB_NAME'], args)


# Connectionの情報を取得
jdbc_conf = glueContext.extract_jdbc_conf(connection_name='CONNECTION_NAME')

# DynamicFrameを作成
dynamicframe = glueContext.create_dynamic_frame.from_options(
                   connection_type='mysql',
                   connection_options={
                       'url': "{0}/{1}".format(jdbc_conf['url'], 'DB_NAME'),
                       'user': jdbc_conf['user'],
                       'password': jdbc_conf['password'],
                       'dbtable': 'TABLE_NAME'
                   })

# DynamicFrameにマスク用の関数を適用
masked_dynamicframe = Map.apply(frame=dynamicframe, f=mask)

# DynamicFrameをCSV形式でS3に書き出す
glueContext.write_dynamic_frame.from_options(
    frame=masked_dynamicframe,
    connection_type='s3',
    connection_options={'path': "s3://{0}/{1}".format('CSV_BACKET_NAME', 'TABLE_NAME')},
    format='csv')


job.commit()

4. Jobの実行

最後にRun JobボタンをクリックしてJobを実行してみましょう。

出力されたCSVを確認するとしっかりとデータがマスクされています!

output.csv
id,username,password
1,alice,****************
2,bob,****************
3,charlie,****************
4,dave,****************
5,ellen,****************

おわりに

AWS Glueを使用してRDSインスタンスのデータを特定のカラムのみマスキングしてから、CSV形式でS3に抽出してみました。
今回はCSV形式での出力を行いましたが、RDSインスタンスのデータベースにデータを書き出すこともできます。ただ、この場合は書き出し先のテーブルの末尾にデータが追加されてしまいますので、もしテーブル内のデータをTruncateしてから書き出したい場合はPySparkのAPIを使用する必要があります。
AWS GlueのDynamicFrameは、PySparkのDataFrameをラップしていますので、DataFrameへの変換が可能です。DataFrameに変換すればもっと柔軟なETL処理を行うことができます。

AWS Glueは、新しいサービスということもあり日々進化しています。昨日できなかったことが今日できたりします。今後、DynamicFrameでもっと多くのことができるようになり、AWS Glueがさらに便利に使えることを期待しています。

参考

(公式)AWS Glue Documentation

続きを読む

AWS 上に JobScheduler を構築した話

AWSには自前でジョブ実行用のサービスがあるので、こういうのはあまりやらないと思いますが、色々とハマったのでメモ。

インストール

JobScheduler インストール

  1. インストーラーをここからダウンロードします。

    スクリーンショット 2017-06-08 0.33.37.png

  2. 解凍した中にある jobscheduler_install.xml を以下の形に修正します。

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <!--
    XML configuration file for JobScheduler setup
    
    The JobScheduler is available with a dual licensing model.
    - GNU GPL 2.0 License (see http://www.gnu.org/licenses/gpl-2.0.html)
    - JobScheduler Commercial License (see licence.txt)
    
    The setup asks you for the desired license model
    (see <entry key="licenceOptions" .../> below).
    
    If you call the setup with this XML file then you accept
    at the same time the terms of the chosen license agreement.
    -->
    <AutomatedInstallation langpack="eng">
    <com.izforge.izpack.panels.UserInputPanel id="home">
        <userInput/>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="licences">
        <userInput>
    
            <!-- Select the license model (GPL or Commercial) -->
            <entry key="licenceOptions" value="GPL"/>
    
            <!-- If you selected GPL as license model than the licence must be empty.
                 Otherwise please enter a license key if available.
                 It is also possible to modify the license key later. -->
            <entry key="licence" value=""/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.HTMLLicencePanel id="gpl_licence"/>
    <com.izforge.izpack.panels.HTMLLicencePanel id="commercial_licence"/>
    <com.izforge.izpack.panels.TargetPanel id="target">
    
        <!-- SELECT THE INSTALLATION PATH FOR THE BINARIES AND LIBRARIES
             The installation expands this path with the Scheduler ID as subdirectory.
             The path must be absolute!
             Default paths are
             /opt/sos-berlin.com/jobscheduler for Unix
             C:Program Filessos-berlin.comjobscheduler for Windows -->
        <installpath>/opt/sos-berlin.com/jobscheduler</installpath>
    
    </com.izforge.izpack.panels.TargetPanel>
    <com.izforge.izpack.panels.UserPathPanel id="userpath">
    
        <!-- SELECT THE DATA PATH FOR CONFIGURATION AND LOG FILES
             The installation expands this path with the Scheduler ID as subdirectory.
             The path must be absolute!
             Default paths are
             /home/[user]/sos-berlin.com/jobscheduler for Unix
             C:ProgramDatasos-berlin.comjobscheduler for Windows -->
        <UserPathPanelElement>/home/joc/jobscheduler</UserPathPanelElement>
    
    </com.izforge.izpack.panels.UserPathPanel>
    <com.izforge.izpack.panels.PacksPanel id="package">
    
        <!-- SELECT THE PACKS WHICH YOU WANT INSTALL -->
    
        <!-- Package: JobScheduler
             JobScheduler Basic Installation
             THIS PACK IS REQUIRED. IT MUST BE TRUE -->
        <pack index="0" name="Job Scheduler" selected="true"/>
    
        <!-- Package: Database Support
             Job history and log files can be stored in a database. Database support is
             available for MySQL, PostgreSQL, Oracle, SQL Server, DB2.
             THIS PACK IS REQUIRED. IT MUST BE TRUE -->
        <pack index="2" name="Database Support" selected="true"/>
    
        <!-- Package: Housekeeping Jobs
             Housekeeping Jobs are automatically launched by the Job Scheduler, e.g. to send
             buffered logs by mail, to remove temporary files or to restart the JobScheduler. -->
        <pack index="5" name="Housekeeping Jobs" selected="true"/>
    
    </com.izforge.izpack.panels.PacksPanel>
    <com.izforge.izpack.panels.UserInputPanel id="network">
        <userInput>
            <!-- Network Configuration -->
    
            <!-- Enter the name or ip address of the host on which the JobScheduler is operated -->
            <entry key="schedulerHost" value="localhost"/>
    
            <!-- Enter the port for TCP communication -->
            <entry key="schedulerPort" value="4444"/>
    
            <!-- Enter the port for HTTP communication -->
            <entry key="schedulerHTTPPort" value="40444"/>
    
            <!-- To enter a JobScheduler ID is required.
                 The IDs of multiple instances of the JobScheduler must be unique per server.
                 The JobScheduler ID expands the above installation paths as subdirectory.
                 Please omit special characters like: /  : ; * ? ! $ % & " < > ( ) | ^ -->
            <entry key="schedulerId" value="schedulerId_XXXX"/>
    
            <!-- It is recommended to enable TCP access for the host where the JobScheduler will install,
                 optionally enter additional host names or ip addresses. To enable all hosts in your
                 network to access the JobScheduler enter '0.0.0.0'. -->
            <entry key="schedulerAllowedHost" value="0.0.0.0"/>
    
            <!-- Choose (yes or no) wether the JobScheduler should be started at the end of the installation -->
            <entry key="launchScheduler" value="yes"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="cluster">
        <userInput>
            <!-- Cluster Configuration -->
    
            <!-- The JobScheduler can be installed independent of other possibly JobSchedulers,
                 as a primary JobScheduler in a backup system or as a backup JobScheduler.
                 Use '' for a standalone, '-exclusive' for a primary
                 or '-exclusive -backup' for a backup JobScheduler.
                 A database is required for a backup system. All JobSchedulers in a backup system
                 must have the same JobScheduler ID and the same database.
                 Further you can set '-distributed-orders' for a load balancing cluster.
                 For more information see
                 http://www.sos-berlin.com/doc/de/scheduler.doc/backupscheduler.xml
                 http://www.sos-berlin.com/doc/de/scheduler.doc/distributed_orders.xml -->
            <entry key="clusterOptions" value=""/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="smtp">
        <userInput>
            <!-- Mail Recipients Configuration / SMTP Authentication -->
    
            <!-- Enter the ip address or host name and port (default: 25) of your SMTP server -->
            <entry key="mailServer" value=""/>
            <entry key="mailPort" value="25"/>
    
            <!-- Configure the SMTP authentication if necessary. -->
            <entry key="smtpAccount" value=""/>
            <entry key="smtpPass" value=""/>
    
            <!-- Enter the addresses of recipients to which mails with log files are automatically
                 forwarded. Separate multiple recipients by commas -->
    
            <!-- Account from which mails are sent -->
            <entry key="mailFrom" value=""/>
    
            <!-- Recipients of mails -->
            <entry key="mailTo" value=""/>
    
            <!-- Recipients of carbon copies: -->
            <entry key="mailCc" value=""/>
    
            <!-- Recipients of blind carbon copies -->
            <entry key="mailBcc" value=""/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="email">
        <userInput>
            <!-- Mail Configuration / Event Handler -->
    
            <!-- Choose in which cases mails with log files are automatically forwarded. -->
            <entry key="mailOnError" value="no"/>
            <entry key="mailOnWarning" value="no"/>
            <entry key="mailOnSuccess" value="no"/>
    
            <!-- The Housekeeping package is required for configure JobScheduler as event handler
                 Choose this option if you intend to use JobScheduler Events and
                 - this JobScheduler instance is the only instance which processes Events
                 - this JobScheduler instance is a supervisor for other JobSchedulers which submit Events -->
            <entry key="jobEvents" value="off"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="database">
        <userInput>
            <!-- JobScheduler Database Configuration -->
    
            <!-- Choose the database management system. Supported values are 'mysql' for MySQL,
                 'oracle' for Oracle, 'mssql' for MS SQL Server, 'pgsql' for PostgreSQL,
                 'db2' for DB2 and 'sybase' for Sybase. -->
            <entry key="databaseDbms" value="mysql"/>
    
            <!-- You can choose between 'on' or 'off' to create the database tables.
                 If you have modified the initial data of an already existing installation,
                 then the modifications will be undone. Data added remains unchanged.
                 This entry should be only 'off', when you sure, that all tables are already created. -->
            <entry key="databaseCreate" value="on"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="dbconnection">
        <userInput>
            <!-- JobScheduler Database Configuration -->
    
            <!-- Enter the name or ip address of the database host -->
            <entry key="databaseHost" value="the host of RDS"/>
    
            <!-- Enter the port number for the database instance. Default ports are for MySQL 3306,
                 Oracle 1521, MS SQL Server 1433, postgreSQL 5432, DB2 50000, Sybase 5000. -->
            <entry key="databasePort" value="3306"/>
    
            <!-- Enter the schema -->
            <entry key="databaseSchema" value="jobscheduler_data"/>
    
            <!-- Enter the user name for database access -->
            <entry key="databaseUser" value="databaseUser"/>
    
            <!-- Enter the password for database access -->
            <entry key="databasePassword" value="databasePassword"/>
    
            <!-- You have to provide the MySQL, MS SQL Server, Sybase or DB2 JDBC driver respectively if you selected
                 corresponding DBMS type. For license reasons MySQL, Sybase and MS SQL Server JDBC Drivers are
                 not provided. Alternatively you can use the mariadb JDBC Driver for MySQL and
                 the jTDS JDBC Driver for MS SQL Server and Sybase which is provided. -->
    
            <!-- You can choose between 'yes' or 'no' for using the jTDS JDBC Driver
                 This entry affects only MS SQL Server or Sybase -->
            <entry key="connectorJTDS" value="yes"/>
    
            <!-- You can choose between 'yes' or 'no' for using the mariadb JDBC Driver
                 This entry affects only MySQL -->
            <entry key="connectorMaria" value="yes"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="jdbc">
        <userInput>
            <!-- JobScheduler Database Configuration -->
    
            <!-- Configuration for JDBC Driver
                 This entry is only necessary if you selected a DBMS type such as MySQL,
                 MS SQL Server, Sybase ot DB2 in the previous <userInput> element. -->
    
            <!-- You have to provide the MySQL, MS SQL Server, Sybase or DB2 JDBC driver respectively if you selected
                 corresponding DBMS type. For license reasons MySQL and MS SQL Server JDBC Drivers are
                 not provided. Specify the JDBC Driver source (e.g. mysql-connector-java-*.jar for MySQL,
                 sqljdbc.jar for MS SQL Server, jconn3.jar for Sybase). Alternatively you can use the mariadb
                 JDBC Driver for MySQL and the jTDS JDBC Driver for MS SQL Server and Sybase which is provided. -->
    
            <!-- Select the path to JDBC Driver -->
            <entry key="connector" value="/usr/share/java/mariadb-connector-java.jar"/>
    
            <!-- Only for DB2: Select the path to DB2 license file for JDBC Driver -->
            <entry key="connectorLicense" value=""/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="reportingDatabase">
        <userInput>
            <!-- Reporting Database Configuration
                 NOT SUPPORTED FOR SYBASE AND DB2 -->
    
            <!-- Set 'yes' if the JobScheduler and the Reporting database are the same.
                 If 'yes' then further Reporting database variables are ignored. -->
            <entry key="sameDbConnection" value="yes"/>
    
            <!-- Choose the database management system. Supported values are 'mysql' for MySQL,
                 'oracle' for Oracle, 'mssql' for MS SQL Server, 'pgsql' for PostgreSQL. -->
            <entry key="reporting.databaseDbms" value="mysql"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="reportingDbconnection">
        <userInput>
            <!-- Reporting Database Configuration
                 NOT SUPPORTED FOR SYBASE AND DB2 -->
    
            <!-- Enter the name or ip address of the database host -->
            <entry key="reporting.databaseHost" value="qnet-jobscheduler.c58hqrvwigfw.ap-northeast-1.rds.amazonaws.com"/>
    
            <!-- Enter the port number for the database instance. Default ports are for MySQL 3306,
                 Oracle 1521, MS SQL Server 1433, postgreSQL 5432. -->
            <entry key="reporting.databasePort" value="3306"/>
    
            <!-- Enter the schema -->
            <entry key="reporting.databaseSchema" value="jobscheduler_data"/>
    
            <!-- Enter the user name for database access -->
            <entry key="reporting.databaseUser" value="reporting.databaseUser"/>
    
            <!-- Enter the password for database access -->
            <entry key="reporting.databasePassword" value="reporting.databasePassword"/>
    
            <!-- You have to provide the MySQL or MS SQL Server JDBC driver respectively if you selected
                 corresponding DBMS type. For license reasons MySQL and MS SQL Server JDBC Drivers
                 are not provided. Alternatively you can use the mariadb JDBC Driver for MySQL and the
                 jTDS JDBC Driver for MS SQL Server which is provided. -->
    
            <!-- You can choose between 'yes' or 'no' for using the jTDS JDBC Driver
                 This entry affects only MS SQL Server -->
            <entry key="reporting.connectorJTDS" value="yes"/>
    
            <!-- You can choose between 'yes' or 'no' for using the mariadb JDBC Driver
                 This entry affects only MySQL -->
            <entry key="reporting.connectorMaria" value="yes"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="reportingJdbc">
        <userInput>
            <!-- Reporting Database Configuration
                 NOT SUPPORTED FOR SYBASE AND DB2 -->
    
            <!-- Configuration for JDBC Driver
                 This entry is only necessary if the package 'Database Support' is chosen and you
                 selected a DBMS type MySQL or MS SQL Server in the previous
                 <userInput> element. -->
    
            <!-- You have to provide the MySQL or MS SQL Server JDBC driver respectively if you selected
                 corresponding DBMS type. For license reasons MySQL and MS SQL Server JDBC Drivers are
                 not provided. Specify the JDBC Driver source (e.g. mysql-connector-java-*.jar for MySQL,
                 sqljdbc.jar for MS SQL Server). Alternatively you can use the mariadb JDBC Driver for
                 MySQL and the jTDS JDBC Driver for MS SQL Server which is provided. -->
    
            <!-- Select the path to JDBC Driver -->
            <entry key="reporting.connector" value="/usr/share/java/mariadb-connector-java.jar"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="end">
        <userInput/>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.InstallPanel id="install"/>
    <com.izforge.izpack.panels.ProcessPanel id="process"/>
    <com.izforge.izpack.panels.FinishPanel id="finish"/>
    </AutomatedInstallation>
    
    
  3. setup.sh を実行します

    ./setup.sh jobscheduler_install.xml
    

JOC インストール

  1. JobScheduler と同様に JOC をダウンロードします。

    スクリーンショット 2017-06-08 0.35.42.png

  2. joc_install.xml を修正します。

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <!--
    XML configuration file for JOC
    
    If you call the installer with this XML file then
    you accept at the same time the terms of the
    licence agreement under GNU GPL 2.0 License
    (see http://www.gnu.org/licenses/gpl-2.0.html)
    -->
    <AutomatedInstallation langpack="eng">
    <com.izforge.izpack.panels.UserInputPanel id="home">
        <userInput/>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.HTMLLicencePanel id="gpl_licence"/>
    <com.izforge.izpack.panels.TargetPanel id="target">
    
        <!-- SELECT THE INSTALLATION PATH
             It must be absolute!
             For example:
             /opt/sos-berlin.com/joc on Linux
             C:Program Filessos-berlin.comjoc on Windows -->
        <installpath>/opt/sos-berlin.com/joc</installpath>
    
    </com.izforge.izpack.panels.TargetPanel>
    <com.izforge.izpack.panels.UserInputPanel id="jetty">
        <userInput>
    
            <!-- JOC requires a servlet container such as Jetty.
                 If a servlet container already installed then you can use it.
                 Otherwise a Jetty will be installed in addition if withJettyInstall=yes.
                 You need root permissions to install JOC with Jetty. -->
            <entry key="withJettyInstall" value="yes"/>
            <entry key="jettyPort" value="4446"/>
            <!-- Only necessary for Windows -->
            <entry key="jettyStopPort" value="40446"/>
            <!-- Only necessary for Unix (root permissions required) -->
            <entry key="withJocInstallAsDaemon" value="yes"/>
            <!-- Path to Jetty base directory
                 For example:
                 /homer/[user]/sos-berlin.com/joc on Linux
                 C:ProgramDatasos-berlin.comjoc on Windows -->
            <entry key="jettyBaseDir" value="/home/joc/jetty"/>
    
            <!-- Java options for Jetty. -->
            <!-- Initial memory pool (-Xms) in MB -->
            <entry key="jettyOptionXms" value="128"/>
            <!-- Maximum memory pool (-Xmx) in MB -->
            <entry key="jettyOptionXmx" value="512"/>
            <!-- Thread stack size (-Xss) in KB -->
            <entry key="jettyOptionXss" value="4000"/>
            <!-- Further Java options -->
            <entry key="jettyOptions" value=""/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="reportingDatabase">
        <userInput>
            <!-- Reporting Database Configuration -->
    
            <!-- Choose the database management system. Supported values are 'mysql' for MySQL,
                 'oracle' for Oracle, 'mssql' for MS SQL Server, 'pgsql' for PostgreSQL. -->
            <entry key="reporting.databaseDbms" value="mysql"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="reportingDbconnection">
        <userInput>
            <!-- Reporting Database Configuration -->
    
            <!-- Enter the name or ip address of the database host -->
            <entry key="reporting.databaseHost" value="qnet-jobscheduler.c58hqrvwigfw.ap-northeast-1.rds.amazonaws.com"/>
    
            <!-- Enter the port number for the database instance. Default ports are for MySQL 3306,
                 Oracle 1521, MS SQL Server 1433, postgreSQL 5432. -->
            <entry key="reporting.databasePort" value="3306"/>
    
            <!-- Enter the schema -->
            <entry key="reporting.databaseSchema" value="jobscheduler_data"/>
    
            <!-- Enter the user name for database access -->
            <entry key="reporting.databaseUser" value="qnet_admin"/>
    
            <!-- Enter the password for database access -->
            <entry key="reporting.databasePassword" value="7sYne7aFEsFSK7xh"/>
    
            <!-- You have to provide the MySQL or MS SQL Server JDBC driver respectively if you selected
                 corresponding DBMS type. For license reasons MySQL and MS SQL Server JDBC Drivers are
                 not provided. Alternatively you can use the mariadb JDBC Driver for MySQL and
                 the jTDS JDBC Driver for MS SQL Server which is provided. -->
    
            <!-- You can choose between 'yes' or 'no' for using the jTDS JDBC Driver
                 This entry affects only MS SQL Server -->
            <entry key="reporting.connectorJTDS" value="yes"/>
    
            <!-- You can choose between 'yes' or 'no' for using the mariadb JDBC Driver
                 This entry affects only MySQL -->
            <entry key="reporting.connectorMaria" value="yes"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="reportingJdbc">
        <userInput>
            <!-- Reporting Database Configuration -->
    
            <!-- Configuration for JDBC Driver
                 This entry is only necessary if you selected a DBMS type such as MySQL and
                 MS SQL Server in the previous <userInput> element. -->
    
            <!-- You have to provide the MySQL or MS SQL Server JDBC driver respectively if you selected
                 corresponding DBMS type. For license reasons MySQL and MS SQL Server JDBC Drivers are
                 not provided. Specify the JDBC Driver source (e.g. mysql-connector-java-*.jar for MySQL,
                 sqljdbc.jar for MS SQL Server). Alternatively you can use the mariadb
                 JDBC Driver for MySQL and the jTDS JDBC Driver for MS SQL Server which is provided. -->
    
            <!-- Select the path to JDBC Driver -->
            <entry key="reporting.connector" value="/usr/share/java/mariadb-connector-java.jar"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="database">
        <userInput>
            <!-- JobScheduler Database Configuration -->
    
            <!-- Set 'yes' if the Reporting and the JobScheduler database are the same.
                 If 'yes' then further JobScheduler database variables are ignored. -->
            <entry key="sameDbConnection" value="yes"/>
    
            <!-- Choose the database management system. Supported values are 'mysql' for MySQL,
                 'oracle' for Oracle, 'mssql' for MS SQL Server, 'pgsql' for PostgreSQL,
                 'db2' for DB2 and 'sybase' for Sybase. -->
            <entry key="databaseDbms" value=""/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="dbconnection">
        <userInput>
            <!-- JobScheduler Database Configuration -->
    
            <!-- Enter the name or ip address of the database host -->
            <entry key="databaseHost" value="qnet-jobscheduler.c58hqrvwigfw.ap-northeast-1.rds.amazonaws.com"/>
    
            <!-- Enter the port number for the database instance. Default ports are for MySQL 3306,
                 Oracle 1521, MS SQL Server 1433, postgreSQL 5432, DB2 50000, Sybase 5000. -->
            <entry key="databasePort" value="3306"/>
    
            <!-- Enter the schema -->
            <entry key="databaseSchema" value="jobscheduler_data"/>
    
            <!-- Enter the user name for database access -->
            <entry key="databaseUser" value="qnet_admin"/>
    
            <!-- Enter the password for database access -->
            <entry key="databasePassword" value="7sYne7aFEsFSK7xh"/>
    
            <!-- You have to provide the MySQL, MS SQL Server, Sybase or DB2 JDBC driver respectively if you selected
                 corresponding DBMS type. For license reasons MySQL, Sybase and MS SQL Server JDBC Drivers are
                 not provided. Alternatively you can use the mariadb JDBC Driver for MySQL and
                 the jTDS JDBC Driver for MS SQL Server and Sybase which is provided. -->
    
            <!-- You can choose between 'yes' or 'no' for using the jTDS JDBC Driver
                 This entry affects only MS SQL Server or Sybase -->
            <entry key="connectorJTDS" value="yes"/>
    
            <!-- You can choose between 'yes' or 'no' for using the mariadb JDBC Driver
                 This entry affects only MySQL -->
            <entry key="connectorMaria" value="yes"/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="jdbc">
        <userInput>
            <!-- JobScheduler Database Configuration -->
    
            <!-- Configuration for JDBC Driver
                 This entry is only necessary if you selected a DBMS type such as MySQL,
                 MS SQL Server, Sybase ot DB2 in the previous <userInput> element. -->
    
            <!-- You have to provide the MySQL, MS SQL Server, Sybase or DB2 JDBC driver respectively if you selected
                 corresponding DBMS type. For license reasons MySQL and MS SQL Server JDBC Drivers are
                 not provided. Specify the JDBC Driver source (e.g. mysql-connector-java-*.jar for MySQL,
                 sqljdbc.jar for MS SQL Server, jconn3.jar for Sybase). Alternatively you can use the mariadb
                 JDBC Driver for MySQL and the jTDS JDBC Driver for MS SQL Server and Sybase which is provided. -->
    
            <!-- Select the path to JDBC Driver -->
            <entry key="connector" value="/usr/share/java/mariadb-connector-java.jar"/>
    
            <!-- Only for DB2: Select the path to DB2 license file for JDBC Driver -->
            <entry key="connectorLicense" value=""/>
    
        </userInput>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.UserInputPanel id="end">
        <userInput/>
    </com.izforge.izpack.panels.UserInputPanel>
    <com.izforge.izpack.panels.InstallPanel id="install"/>
    <com.izforge.izpack.panels.ProcessPanel id="process"/>
    <com.izforge.izpack.panels.FinishPanel id="finish"/>
    </AutomatedInstallation>
    
  3. setup.sh を実行します

    ./setup.sh joc_install.xml
    

続きを読む

クラウドベンダーの比較

はじめに

3大クラウドと呼ばれているAWS、GCP,Azureのリソースを比べてみました。
2017年11月時点の比較となります。

インフラ・サービスレベル

比較項目 AWS GCP Azure 備考
データセンター 各地で借りている すべて自前 各地で借りている(一部自前)
仮想化技術 Xen KVM Hyper-V
リージョン(国内) 1個所 1個所 2個所
リージョン(全国) 15個所 12個所 36個所
SLA 99.95 99.95 99.95 仮想サーバ

サービス面

比較項目 AWS GCP Azure 備考
仮想サーバ Amazon EC2 Google Compute Engine Azure Virtual Machines
仮想サーバ対応OS Amazon Linux,CentOS,RedHat,Windows Server,等 CentOS,RedHat,SLES,Windows Server,等 CentOS,RedHat,Windows Server,等
仮想サーバディスク SSD,HDD SSD,HDD SSD,HDD
仮想サーバスナップショット
仮想サーバオートスケール
コンテナ Amazon ECS Container Engine Container Service
RDB RDS Cloud SQL SQL Database
RDB冗長化
RDBリードレプリカ
RDB DB種別 Aurora,MySQL,MariaDB,Oracle,SQL Server,PostgreSQL MySQL,PostgreSQL SQL Server
NoSQL DynamoDB Cloud Datastore Cosmos DB
ビックデータ Redshift BigQuery App Service
メール Amazon SES
モニタリングツール CloudWatch Stackdriver Azure Monitor
ロードバランサー(L4) CLB Network load balancing Azure Load Barancer
ロードバランサー(L7) ALB HTTP load balancing Application Gateway
CDN Amazon CloudFront Google Cloud CDN Azure CDN
VPN Amazon VPC Google Cloud VPN VPN Gateway
DNS Route53 Google Cloud DNS Azure DNS
専用線 Direct connect Dedicated Interconnect Express Route

サポート面

比較項目 AWS GCP Azure 備考
ランク低 開発者 ($29/月 or 利用料の 3%/月) シルバー ($150/月) Standard($300/月)
ランク中 ビジネス($100/月 or 利用料 の10%/月) ゴールド($400/月) Professional Direct($1,000/月)
ランク高 エンタープライズ($15,000/月 or 利用料の10%) プラチナ(問合せ) Premier(問合せ)

費用面(リージョン日本)

比較項目 AWS GCP Azure 備考
課金単位
ディスカウント リザーブドインスタンス(前払い) 継続利用割引、利用確約の割引(前払い) エンタープライズ契約(前払い)
仮想サーバ(Type) t2.medium(2vCPU,4GB) n1-standard-2(2コア,7.5GB) A2 V2(2コア,4GB)
仮想サーバ(時) $0.0464(5.336円)※1 $0.0950(10.925円)※1 $0.15(17.25円)※1
仮想サーバ(月) $33.408(3841.92円)※1 $48.17(5539.55円)※1,※2 $108(12,420円)※1
インターネットへの転送量 $0.140/GB(10TBまで) $0.12/GB(1TBまで) $0.138/GB(5GB-10TB、5GBまでは無料)
ストレージ利用料 $0.025/GB (最初の50TB/月まで) ※S3 $0.016/GB 月 ※Regional Storage $0.2/GB(最初の50TB/月まで) ※BLOG Storage

※1 $1=115円換算
※2 継続利用割引含む

総括

 AWS、GCP,Azureでのサービス面では同じようなサービスを展開していることが判明。
 インフラ・サービスレベルでは、Azureがリージョン36個とTOPに。
世界的に見て幅を利かせているように思えた。
ただ、GCPはすべて自前のセンターでクラウドサービスを展開していることから、
新しいことをやるにも制約が低いように思えた。
私のイメージ的に一番シェアが高いAWSは、インフラ面ではGCP,Azureに劣っている結果となった。
 費用面では、Azureは割高。AWSが思ったよりも頑張っているように思えた。
 イメージ的にGCPは費用は安いと思っていたが、仮想サーバ比較だと、継続利用割引を使用してもAWSのほうが安い結果となった。
 ただ、費用に関しては、日々値下げ合戦が繰り広げられているので、今後のベンダーさんの努力に期待です。

最後に、費用面での算出に使用した見積もりツールです。
【AWS】http://calculator.s3.amazonaws.com/index.html
【GCP】https://cloud.google.com/products/calculator/?hl=ja
【Azure】https://azure.microsoft.com/ja-jp/pricing/calculator

続きを読む

AWS Database Migration Service データ移行時におけるエラーレコードの特定方法

こんにちは。
Fusic Advent Calendar 2017 2日目は 若干ニッチなお話をさせていただきます。

AWS Database Migration Service とは

AWS Database Migration Service (AWS DMS) は、Oracle、PostgreSQL、Microsoft SQL Server、Amazon Redshift、Amazon Aurora、MariaDB、MySQL など、幅広く使用されている商用およびオープンソースデータベースとの間でデータを移行できます。このサービスでは、Oracle から Oracle など、同機種間の移行をサポートしているほか、Oracle から MySQL、MySQL から Amazon Aurora など、異なるデータベースプラットフォーム間の異機種の移行もサポートしています。
AWSユーザーガイドより抜粋

今回は DMS を使用した初期データ移行時に、
エラーが発生した際の、原因の特定方法を紹介します。

エラーが発生したテーブルのみを指定してタスクを実行

当たり前のことなのですが、
エラーが発生した際は、対象のテーブルのみを指定してタスクを作成・実行してみましょう。
その際、ロギングの有効化は忘れずに。
※ CloudWatch にログが出力されます。

実行後、CloudWatchログを確認してみてください。

エラー部分のログの例

2017-12-01T10:44:43 [TARGET_LOAD     ]E: Failed to wait for previous run (csv_target.c:937)
2017-12-01T10:44:43 [TARGET_LOAD     ]E: Failed to start load process for file '2' [1020403] (csv_target.c:1300)
2017-12-01T10:44:43 [TARGET_LOAD     ]E: Failed to load file '2' [1020403] (csv_target.c:1407)
2017-12-01T10:44:43 [TASK_MANAGER    ]W: Table 'db_name'.'table_name' (subtask 1 thread 1) is suspended (replicationtask.c:2094)
2017-12-01T10:44:43 [TARGET_LOAD     ]E: Failed to load data from csv file. [1020403] (odbc_endpoint_imp.c:5233)

  • エラーが特定出来た → おしまい
  • エラーが特定出来ない → 次へ進む

タスクのログレベルを上げる

エラーの原因となっている コンポーネントアクティビティ (↑の例だと TARGET_LOAD ) のログレベルを

  • LOGGER_SEVERITY_DEBUG

もしくは

  • LOGGER_SEVERITY_DETAILED_DEBUG

に設定します。

参照) AWS Database Migration Service ユーザーガイド

なお、ログレベルの変更は 2017/12/2 現在 Management Console からは行うことが出来ません。
AWS CLI より、

  1. aws dms describe-replication-tasks で タスク の情報を抽出
  2. ↑の情報から ReplicationTaskSettings.Logging.LogComponents の対象となる コンポーネントアクティビティ のログレベルを変更したタスクを複製

といった流れで別タスクを作成します。
別タスクを実行後、CloudWatchログを確認してみてください。

エラー部分のログの例

2017-12-01T11:03:24 [TARGET_LOAD     ]D:  Going to load file '/rdsdbdata/data/tasks/HU2DPNPG5RNCUJDBZPZZYTI5J4/data_files/1/LOAD00000002.csv'  (csv_target.c:1285)
2017-12-01T11:03:24 [TARGET_LOAD     ]D:  Load data command. Path: , Exe name: psql, Exe params: -h rds_name.ccsis9ijpw43.ap-northeast-1.rds.amazonaws.com -p 5432 -U ***** -w -d db_name -c """\copy ""db_name"".""table_name"" from '/rdsdbdata/data/tasks/HU2DPNPG5RNCUJDBZPZZYTI5J4/data_files/1/LOAD00000002.csv' WITH DELIMITER ',' CSV NULL 'attNULL' ESCAPE '\'"""  (provider_syntax_manager.c:2595)
2017-12-01T11:03:24 [TARGET_LOAD     ]D:  Before wait for command  (csv_target.c:827)
2017-12-01T11:03:24 [TARGET_LOAD     ]D:  wait for load command process returned status '10'  (csv_target.c:839)
2017-12-01T11:03:24 [TARGET_LOAD     ]D:  Load command output: psql: /usr/lib64/libcom_err.so.2: no version information available (required by /rdsdbbin/attunity-2.3.0.R1/lib/libgssapi_krb5.so.2), psql: /usr/lib64/libcom_err.so.2: no version information available (required by /rdsdbbin/attunity-2.3.0.R1/lib/libkrb5.so.3), ERROR:  date/time field value out of range: "0000-00-00 00:00:00", CONTEXT:  COPY table_name, line 83299, column deleted: "0000-00-00 00:00:00"  (csv_target.c:895)
2017-12-01T11:03:24 [TARGET_LOAD     ]D:  Failed to wait for previous run  (csv_target.c:937)
2017-12-01T11:03:24 [TARGET_LOAD     ]D:  Failed to start load process for file '2' [1020403]  (csv_target.c:1300)
2017-12-01T11:03:24 [TARGET_LOAD     ]D:  Failed to load file '2' [1020403]  (csv_target.c:1407)
2017-12-01T11:03:24 [TARGET_LOAD     ]D:  Failed to load data from csv file. [1020403]  (odbc_endpoint_imp.c:5233)
2017-12-01T11:03:24 [TARGET_LOAD     ]D:  Handling End of table 'db_name'.'table_name' loading failed by subtask 1 thread 1 [1020403]  (endpointshell.c:2147)
2017-12-01T11:03:24 [TARGET_LOAD     ]E:  Failed to wait for previous run  (csv_target.c:937)
2017-12-01T11:03:24 [TARGET_LOAD     ]E:  Failed to start load process for file '2' [1020403]  (csv_target.c:1300)
2017-12-01T11:03:24 [TARGET_LOAD     ]E:  Failed to load file '2' [1020403]  (csv_target.c:1407)
2017-12-01T11:03:24 [TASK_MANAGER    ]W:  Table 'db_name'.'table_name' (subtask 1 thread 1) is suspended  (replicationtask.c:2094)
2017-12-01T11:03:24 [TARGET_LOAD     ]E:  Failed to load data from csv file. [1020403]  (odbc_endpoint_imp.c:5233)

※↑の例だと5行目にエラーの原因が出力されていますね

  • エラーが特定出来た → おしまい
  • エラーが特定出来ない → 次へ進む

S3 に出力したファイルを見て実際のレコードを特定する

ターゲットエンドポイントをS3に指定したタスクを作成し、実行します。
前述のエラーの例の場合、83299行目にエラーが発生しています。(line 83299)
S3に出力されたファイルを確認することで、
エラーが発生したレコードを特定することが可能です。

  • エラーが特定出来た → おしまい
  • エラーが特定出来ない → 次へ進む

サポートに問い合わせる

ターゲットエンドポイントの “追加の接続属性” に「keepCSVFiles=true;keepErrorFiles=true」を設定し、
タスク実行時にレプリケーションインスタンス上に、一時的に保存される移行対象テーブルのデータを、
永続的に保存するようにします。
ただ、2017/12/2 現在では、レプリケーションインスタンスには、
AWSの中の人しかログイン出来ません。
設定後、タスクを再実行し、移行対象テーブルのデータを保存したら、
AWSサポートに問合せてみましょう。

ここまでやったらエラーは特定できてる!…はず

明日のAdvent Calendarは Fusicの核弾頭 @Junkins です。
皆様、お楽しみに!

続きを読む

AWS DMSでオンプレミス OracleSE1からRDS for OracleSE1移行時のハマったところなど

はじめに

現在弊社ではシステムを非AWS環境からAWSに移行する作業をしております

本記事は、AWS移行作業の一部であるDB移行を、AWS DMSで行った際に遭遇したつまずきポイントなどをまとめます

目次

  • DMS側のつまずきポイント

    • レプリケーションインスタンスのインスタンスクラス問題
    • 新機能のデータ検証使えない問題
    • インスタンスごとのエンドポイント設定数制限問題
  • ソースDB側のつまずきポイント
    • 社内セキュリティポリシーの問題
    • 1日たったら変更データキャプチャ (CDC) 動かなくなる問題
  • ターゲットDB側のつまずきポイント
    • 適切なRDSのスペック選定問題
    • データベースリンクの問題
    • ユーザー作成+シーケンスの問題

DMS側のつまずきポイント

レプリケーションインスタンスのインスタンスクラス問題

DMSを初めて触るに辺りお試しで移行しようと思い、ケチってレプリケーションインスタンスのインスタンスクラスをmicroで作ったのですが、これがまずかったです

microインスタンスだと100%エラーが発生し、タスクが失敗しました

設定自体は完璧なのにタスクが実行できず、以下のようなエラーログが出たら、インスタンスクラスをアップグレードすることをおすすめします

Task error notification received from subtask 0, thread 0 [XXXXXX] Oracle CDC maximum retry counter exceeded.
Task 'XXXXXXXXXXXXXXXXXXXXXXX' encountered a fatal error

新機能のデータ検証使えない問題

移行作業中にDMSの機能がアップグレードし、移行前のタスク評価移行後のデータ検証が使えるようになりましたので、早速データ検証を使ってみた所ハマりました

データ検証を使用するにはレプリケーションエンジンのバージョンを2.4.0(東京リージョンの場合)にする必要があります

レプリケーションエンジンの2.4.0バージョン情報は、本記事作成時点では公式マニュアルに記載されていませんでした

使うにはタスク設定画面の検証の有効化をONにすることで使えるようです

ただうちの環境でここをONにすると、そのタスクは100%失敗しました

CloudWatchのログには以下のように出てます

Cannot get special table's id for table awsdms_validation_failures

公式マニュアルによると、検証の有効化をONにするとターゲットDBに「awsdms_validation_failures」というテーブルを作るようです

このテーブルには診断情報を書き込むようで、検証エラーのトラブルシューティングに使えるようなのですが、このテーブルすら作られていませんでした

また、一度検証の有効化をONにすると、タスク編集でOFFにして再度タスク実行しようとしても、そのタスクは以降ずっと失敗するようになりました

公式記載の制限事項はクリアしていたかと思いますが、原因がわからなかったので、検証機能は使わないようにしました

インスタンスごとのエンドポイント設定数制限問題

DMSには結構作成リソースの制限が厳しいです

以下公式記載の東京リージョンでの制限値です

リソース デフォルトの制限
レプリケーションインスタンス 20
ストレージの合計 6TB
イベントサブスクリプション 100
レプリケーションサブネットグループ 20
レプリケーションサブネットグループあたりのサブネット 20
エンドポイント 100
タスク 200
インスタンスごとのエンドポイント 20

今回DB移行する対象のサービスは、DB4台のスキーマ数100以上でした

レプリケーションインスタンスは2台だったので、エンドポイントを作っては消し、作っては消し…を繰り返しました

後からレプリケーションインスタンスの数を増やすことが社内事情で難しかったため、もし大量の移行作業をする場合は、予めレプリケーションインスタンスを大量に作っておいたほうがいいでしょう

ソースDB側のつまずきポイント

社内セキュリティポリシーの問題

AWSに移行前の環境では、DBに関してのレコード操作以外の作業はすべてDBGという部署が管理していました

  • GIPを割り当てることNG
  • root権限使用NG
  • VPC環境外からのDB接続NG
  • スキーマ・ユーザー作成NG

制限だらけです

AWS外の環境からDMSを使って移行する場合、AWS Direct Connectや、VPN接続といった複数のオプションを使用して繋ぐ方法もありますが、GIPでの接続が一番簡単で安価です

また、DMSを使うための専用ユーザーを作る必要もあります

OracleをソースとしてDMSを使う場合は、ARCHIVELOGモードやサプリメンタルロギングをオンに設定する作業もありますし、ポリシーと相違する事だらけです

ここの対応をお願いする調整が大変でした

DBGに対応依頼をしても「無理です」の一点張りになりますので、一番偉い人に土下座してお願いするのが手っ取り早いです

1日たったら変更データキャプチャ (CDC) 動かなくなる問題

今回のDB移行作業は1つのタスクを1日以上実行しっぱなしにすることはないのですが、たまたま作業が日をまたいだ時がありました

出社してタスクの状況を見たらタスクが止まっており、何故かを調べた所1日1回DBのセッションをリフレッシュする処理が入ってました

この処理を止めることは社内ルールとしてできなかったため、「1日以上かかるタスクは作らない」という運用でカバー(魔法の言葉)しました

ターゲットDB側のつまずきポイント

適切なRDSのインスタンスクラス選定問題

旧環境ではかなり余裕を見たテーブルスペースサイズをそれぞれのスキーマーに割り当てており、正式な必要ディスク領域を算出することが難しかったです

単にDBのHDD使用量を見るだけではわからないということです

データベースリンクの問題

旧環境では一部スキーマにDatabase linkがLIPで設定されていました

当然RDSからは使えないのでここの修正が必要です

Database linkの問題はすぐに気が付かなかったので、検証・調査に結構時間がかかりました

ユーザー作成+シーケンスの問題

DMSはセカンダリインデックス、シーケンス、デフォルト値、ストアドプロシージャ、トリガー、シノニム、ビューなど、データ移行に特に関係ないスキーマオブジェクトは移行しません(公式マニュアル

また、ターゲットDBにスキーマを作成してくれません(公式マニュアル

なので一個一個のスキーマ、シーケンス等を作成するSQLを作り、RDS Oracleに作る作業が面倒でした


以上、色々つまずきましたがDMSのお陰で、4つのDB、100位上のスキーマの移行作業が、サービス停止すること無く1ヶ月で出来ました

DMSバンザイ!

続きを読む

AWSとOracle Cloudのサービス比較

今、クラウドにするならどこ? と聞いたら、情シス的には、ほぼ100%AWSと答える。なぜなら、情シスには技術力はあまりないので、みんなが使ってるやつに乗っかりたいからである。 ただ、そうはいかないケースもある。既存の取引先とか、今のインフラの環境とかもろもろの事情で、Oracleクラウドも検討せなあかんときもある。 続きを読む