Apache IgniteでバックエンドにH2 Databaseを利用して永続化する

概要

Apache Igniteはインメモリデータグリッドを実現するミドルウェアであるがデータを永続化したいことがある。
永続化の方法としてディスク領域に保存するNative Parsistenceと外部のデータベース等に保存する3rd Party Persistence機能があり、 この記事では後者の3rd Party Persistence機能試してみる。

apacheignite.readme.io

環境

構成

f:id:hkou:20180518234016p:plain

手順

H2 Database

All Platformsのzipファイルをダウンロードして、解凍する。

www.h2database.com

binディレクトリのh2.batを起動するとWeb管理画面が開く
Apache Igniteからも接続したいので設定済みファイルをServerにして接続する

f:id:hkou:20180518234733p:plain

build.sbt

ignite関連のlibraryを追加

libraryDependencies ++= {
  val igniteVersion = "2.4.0"
  Seq(
    "org.apache.ignite" % "ignite-core" % igniteVersion,
    "org.apache.ignite" % "ignite-spring" % igniteVersion,
    "org.apache.ignite" % "ignite-indexing" % igniteVersion
  )
}

config(xml)

Apache Igniteは設定をxmlファイルで保持する。
xmlファイルはsrc/main/resources/META-INFディレクトリに配置した。

H2 Databaseへの接続設定

先程のH2 DatabaseのWeb管理画面に指定した接続先設定と同じものを指定する。

<bean id= "simpleDataSource" class="org.h2.jdbcx.JdbcDataSource">
    <property name="user" value = "sa" />
    <property name="url" value="jdbc:h2:tcp://localhost/~/test" />
</bean>

キャッシュの設定

  • CacheJdbcBlobStoreFactoryを利用してBLOB形式でデータベースに保存
  • write, readスルー機能を有効化
<property name="cacheConfiguration">
    <list>
        <bean class="org.apache.ignite.configuration.CacheConfiguration">
            <constructor-arg name="name" value="testCache"></constructor-arg>
            <property name="cacheStoreFactory">
                <bean class="org.apache.ignite.cache.store.jdbc.CacheJdbcBlobStoreFactory">
                    <property name="user" value = "sa" />
                    <property name="dataSourceBean" value = "simpleDataSource" />
                </bean>
            </property>
            <property name="writeThrough" value="true"/>
            <property name="readThrough" value="true"/>
        </bean>
    </list>
</property>

Scalaプログラム

データをputしてgetするだけの単純なプログラムを書いた。

import org.apache.ignite.Ignition

object Main extends App {
  using(Ignition.start("example-ignite.xml")) { ignite =>
    using (ignite.getOrCreateCache[String, String]("testCache")) { cache =>
      cache.put("test1", "test1Value")
      cache.put("test2", "test2Value")

      println(s"test1 = ${cache.get("test1")}")
      println(s"test2 = ${cache.get("test2")}")
    }
  }

  def using[T <: AutoCloseable, A](resource: T)(proc: T => A): Unit = {
    try {
      proc(resource)
    } catch {
      case e: Throwable => e.printStackTrace()
    } finally {
      resource.close()
    }
  }
}

実行した

上記のScalaプログラムを実行した。igniteのログが表示され、getしたデータが取得できた

[22:58:03]    __________  ________________
[22:58:03]   /  _/ ___/ |/ /  _/_  __/ __/
[22:58:03]  _/ // (7 7    // /  / / / _/
[22:58:03] /___/\___/_/|_/___/ /_/ /___/
[22:58:03]
[22:58:03] ver. 2.4.0#20180305-sha1:aa342270
[22:58:03] 2018 Copyright(C) Apache Software Foundation
[22:58:03]
[22:58:03] Ignite documentation: http://ignite.apache.org
・・・・

永続化されたか確認する

H2 DatabaseのWeb管理画面から確認したところ、ENTRIESテーブルが新たに追加されていた。
内容を確認したところ先程putしたデータが保存されているようだ。

f:id:hkou:20180519000002p:plain

SELECT UTF8TOSTRING(akey), UTF8TOSTRING(val) FROM ENTRIES;

Akka Remoteを利用したServer, Clientの簡単なActor通信するサンプルで動作確認した

概要

akka remoteを使ったリモート間のActorプログラムに慣れるために、client -> server構成の単純なプログラムを作成して動作を確認した。

作成したプログラムは以下

github.com

動作環境

  • Windows 10 Pro 1709
    • JRE build 1.8.0_151-b12
  • scala 2.12.6
  • akka-actor 2.5.12
  • akka-remote 2.5.12

構成

  • メッセージを待ち受けるserverと、メッセージを送信するclientの2プロジェクト構成
  • serverとclientは別プロセスとする

f:id:hkou:20180512102432p:plain

動作シーケンス

  • client
    • serverのActorに対して一定時間間隔でメッセージを送信する
    • 最後にserverを停止するメッセージを送信する
  • server
    • メッセージ待受するActorを起動する
    • 受け付けたメッセージを標準出力に表示する

f:id:hkou:20180512104004p:plain

パケットキャプチャ

remote actorに対する通信を理解するためにパケットキャプチャを用いて通信の内容を確認する。
このサンプルプロジェクトはlocalhost環境で動かしている。WireSharkでは自マシン間での通信はキャプチャできない為、RawCapを利用した。

www.netresec.com

server起動

sbt 
project server
run

client起動

serverとは別のsbtで以下を実行する

sbt
project client
run

キャプチャ結果確認

RawCapは標準でpcap形式のファイルを出力するので、キャプチャ内容を確認するときはWireSharkを利用することができる。

f:id:hkou:20180512110621p:plain

  • 一度コネクションを張るとshutdownするまでずっとコネクションを維持し続ける
  • デフォルトでは4秒?毎にheart beatが投げられている
  • 小さいメッセージ(今回はString9文字程度)だとペイロードの大半がactor pathの情報が占めるように見える

ServerlessFrameworkでS3の静的サイトのホスティングをする

概要

S3に静的サイトのホスティング機能がある。静的ファイル(HTML, js, css等)をS3に配置すると、それらのファイルをウェブ公開してくれる機能だ。
ウェブホスティング用のS3バケットを作成したり、静的ファイルをS3にアップロードしたりするのをServerlessFramework経由で行う。

プロジェクトを作成

とりあえず以下のコマンドを実行してプロジェクトを作成する。プロジェクト名はs3-sync-testにした。

sls create --template aws-nodejs --path s3-sync-test

プラグイン導入

ファイルをS3にアップロードする機能はServerlessFramework標準には無いようなので以下のプラグインを利用する。

github.com

以下のコマンドでプラグインをインストールする。

sls plugin install -n serverless-s3-sync

serverless.ymlの末尾にpluginsの項目が追加されたはずだ。

plugins:
  - serverless-s3-sync

S3バケットの設定

resourcesの項目にS3バケット設定とS3バケットポリシーを記載する。

resources:
  Resources:
    StaticSite:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: ${self:custom.webSiteName}
        AccessControl: PublicRead
        WebsiteConfiguration:
          IndexDocument: index.html
          ErrorDocument: error.html
    StaticSiteS3BucketPolicy:
      Type: AWS::S3::BucketPolicy
      Properties:
        Bucket:
          Ref: StaticSite
        PolicyDocument:
          Statement:
            - Sid: PublicReadGetObject
              Effect: Allow
              Principal: "*"
              Action:
              - s3:GetObject
              Resource:
                Fn::Join: ["", ["arn:aws:s3:::",{"Ref": "StaticSite"},"/*"]]

customにウェブサイト名とS3にアップロードするファイルを配置しているディレクトリ名を記載する。

custom:
  webSiteName: s3-sync-test.com
  s3Sync:
    - bucketName: ${self:custom.webSiteName}
      localDir: static

HTML用意

<project>/static ディレクトリにindex.htmlerror.htmlを配置した。

デプロイ

以下のコマンドでデプロイする。

sls deploy -v

動作確認

AWSのマネジメントコンソールからS3のページへ遷移して、上記で作成したバケットがあるか確認する。
バケット内を確認し、HTMLファイルがアップロードされているか確認する。

f:id:hkou:20180507212858p:plain

ブラウザから確認

プロパティからStatic website hostingを選択してエンドポイントを開く。

f:id:hkou:20180507213123p:plain

ブラウザから表示することができた。

f:id:hkou:20180507213246p:plain

水辺の温泉 日帰りツーリングしてきた

GW, せっかく天気が良いのにずっと家に引き篭もっているのもアレなので、久しぶりに日本海側の温泉へ行くことにした。日本海側は天気が良い日が少ないので今日みたいな「全国的に晴れ」みたいな日を狙って行かないと満足度が低いのだ。

道程が長くなりそうなので、朝早めに出発した。
まずは滋賀県方面へ向かう。途中、木曽川河川敷で休憩した。

f:id:hkou:20180505065017j:plain

f:id:hkou:20180505065029j:plain

走ること2時間程度、琵琶湖の辺りに到着した。朝早めだったので他の車もおらず、快適に運転することができた(通常だと名古屋抜けるのに相当苦労する) f:id:hkou:20180505082216j:plain

敦賀湾のあたり。 f:id:hkou:20180505085802j:plain

敦賀湾を抜けると、道がどんどん低くなり殆ど海面と変わらないぐらいになってきた。波間の静かな湾と違い、ここまで来ると日本海の荒波を感じる。波消しブロックに波があたり鈍い低温が響いている。路面の位置も海と比べてそこまで高くないので、ちょっと波が強いと波しぶきが道路まではみ出していて、運転しているとちょっと怖かった。あと波しぶきでヘルメットが汚れた。 f:id:hkou:20180505091459j:plain

f:id:hkou:20180505091503j:plain

越前温泉露天風呂漁火

ここの温泉は道の駅に併設されており、食事施設と併せて利用できて便利。また、日本海側に面しているので大海原を見ながら露天風呂に浸かることができる。
以前、能登&金沢ツーリングへ行った時に見つけたスポットだ。
hkou.hatenablog.com

残念ながら、撮影禁止のため湯船の写真は無い。日本海の大海原を眺めながら露天風呂に浸かるとついつい長居してしまった。
朝ごはんを食べずに来たので、ここで朝ごはんを食べることにする。道の駅内のお食事処かねいちというお店でお刺身定食を食べた。 f:id:hkou:20180505110912j:plain

南砺市平ふれあい温泉センター ゆ~楽

予定よりも早く到着したので時間に余裕があった。このまま自宅へ帰るというのも味気ない感じがしたのでまた別の温泉へ行くことにした。
それがここである。少し距離は遠いが日本海側に来ることはあまりないのでせっかく来たのだしということで、足を伸ばそうという気分になった。 f:id:hkou:20180505155059j:plain

庄川の祖山ダム湖の辺りに併設された温泉で、高い位置にある露天風呂からダム湖全体を見渡せる景観の良い温泉です。
f:id:hkou:20180505155022j:plain

まとめ

f:id:hkou:20180506075117p:plain

  • 総走行距離508km(GoogleMapタイムラインから)
  • GWだからか結構ツーリングしている人達を見かけた
  • 日本海側のルートはヤエー返答率が高いような気がする
  • 一日中快晴だったが、早朝夜のあたりはバイクで走っているとまだまだ寒い

第6世代iPad(シルバーグレー)を購入した

概要

最近手書きでメモすることが多くなり、いつも紙に描いていたが、いつの間にかどこかへ行ってしまったり、整理がしづらかったのでデジタル化したいなぁと常々感じていた。
Apple PencilはiPad Proでしか利用できなかったが、この前新しく出た第6世代iPadでも利用できるようになったとのことで、 iPad or iPad Proのどちらにするかで迷っていた。

家電量販店に展示されていた実機を触ってみたところ、確かにiPad Proの方が書き味が良くレスポンスも早いが、自分にとっては無印iPadでも充分レスポンス早いし、いろいろ触っててもうこれで良いやと思えてきたので購入に踏み切った。

外箱

Apple製品らしいスッキリしたデザイン f:id:hkou:20180430122939j:plain

開封

f:id:hkou:20180430123058j:plain

Apple Pencil

Apple Pencilももちろん同時購入した。

f:id:hkou:20180430123146j:plain

電源ON

f:id:hkou:20180430123406j:plain

最近のiPadiPhoneと同期させることで初期設定をスキップすることができるようになったらしい。
画面中央のモヤモヤしたところをiPhoneのカメラで撮影すると同期される。

f:id:hkou:20180430123536j:plain

手書きノートアプリ

手書きノートアプリで一番有名どころのGoodNotes4をとりあえず購入してみた。

GoodNotes 4

GoodNotes 4

  • Time Base Technology Limited
  • 仕事効率化
  • ¥960

SplitView

iPadにはSplit Viewという画面分割してそれぞれ別のアプリを同時に動かす機能がある。
早速KindleとGoodNotes4で利用してみた。読書しながらメモが書けるようになった。 f:id:hkou:20180430153458j:plain

まとめ

良いところ

  • Apple Pencilの書き味、レスポンスは素晴らしい
    • GoodNotes4との組み合わせは最高だった
  • カメラの出っ張りがなくて良い
  • 低価格なので傷とかあまり気にせず使用することができる

悪いところ

  • Apple Pencilの持ち手がツルツルしてるので汗で滑る

木崎湖ツーリング行ってきた

今日は天気が良かったので木崎湖へツーリングしてきた。
山の上の方にはまだ雪が積もっているけど、下の方は初夏のような気温で、ツーリングするには最適だった。

f:id:hkou:20180421125910j:plain

ゆーぷる木崎湖で昼ごはんを食べる。休日のお昼時だというのに自分と他一組ぐらいしか客がいなくてガラガラだった。スキーの季節終わったから客が少なくなったのだろうか。木崎湖行くときはいつも利用するので潰れてしまうと困る。 f:id:hkou:20180421132319j:plain

今日は雲ひとつ無い快晴なので、パラグライダー場の方へ行ってみることにした。
通行止めの看板が立ててあったけど脇にずらされていた(これはゆるきゃんで見た通行できる通行止めというやつでは) f:id:hkou:20180421144613j:plain

こんな感じの道をずーっと登っていく。路面には砂利や木の枝、石や岩が転がってて何度かタイヤが滑りかけて怖かった。しかもこの道ガードレールないし。
途中ロードバイクで登っている人を何人か見かけた。 f:id:hkou:20180421143335j:plain

登っているとたまにこんな感じで切り開けた場所に出くわす。景色を見ながら小休止したりしていた。 f:id:hkou:20180421143326j:plain

40分ぐらいかかって、やっと頂上へ到着した。予想通り見渡す限りの絶景だった。 f:id:hkou:20180421141529j:plain

景色を堪能したので下に降りてきて湖畔を歩き回っていた。気温が高くなっているからかいつもよりも人が多いような気がする。 f:id:hkou:20180421150725j:plain

歩き周って温泉入りたくなってきたので、近くの「白馬八方温泉 みみずくの湯」へ行ってきた。ここの温泉は露天風呂から白馬三山を一望できて良い。 f:id:hkou:20180421153704j:plain

まとめ

  • 総走行距離465km
  • 木崎湖はいつ来ても良い
  • 久しぶりに長距離ツーリングしたので尻が痛くなった

f:id:hkou:20180421235041p:plain

API GatewayでAPIキー認証付きのHTTP APIを作る

やりたいこと

  • 以下の記事で作成したAPIは誰でも呼び出せる状態なので、ある特定のクライアントからしか呼び出せないように認証をかける

hkou.hatenablog.com

serverless.ymlを編集する

providerの項目にAPIキーと使用量プランの記述を追加する。

  • APIキー
    • とりあえず名前だけ指定
  • 使用量プラン
    • レート
    • バースト
    • クォーター
      • 1 日あたり 5,000 リクエスト数
provider:
  name: aws
  runtime: nodejs6.10
  region: ap-northeast-1
  apiKeys:
    - myFirstKey
  usagePlan:
    quota:
      limit: 5000
      offset: 0
      period: DAY
    throttle:
      burstLimit: 200
      rateLimit: 100

上記で設定したAPIキーを利用するAPIに対してprivate: trueを指定する。

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: api/hello
          method: get
          private: true
  add:
    handler: handler.add
    events:
      - http:
          path: api/add
          method: post
          private: true

デプロイする

deployコマンドでデプロイする。
作成されたAPIキーの値が出力されるので控えておく

sls deploy -v

(省略)

service: test-service
stage: dev
region: ap-northeast-1
stack: test-service-dev
api keys:
  test-api-key: (APIキーの値)
endpoints:
  GET - https://(URL).ap-northeast-1.amazonaws.com/dev/api/hello
  POST - https://(URL).ap-northeast-1.amazonaws.com/dev/api/add

動作確認

APIキーなしで呼び出す

403 ForbiddenがレスポンスされAPIが呼び出せなくなった。

f:id:hkou:20180419215925p:plain

APIキーありで呼び出す

APIキーをヘッダーに付加するとちゃんと呼び出せる。

f:id:hkou:20180419220121p:plain