3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Docker内からPrivateサブネットに配置したNeptuneに接続する

Posted at

最近、東京リージョンにきたNeptuneを開発効率をあげるため、Docker内から接続してみようと思います。

環境

大まかな流れ

  • docker imageの用意
  • ポートフォワーディングの設定
    • publicなEC2の用意(省略)
  • docker-compose.ymlの設定
    • extra_hostsの追加
    • ホストの.ssh/configにポートフォワーディングの設定
    • 起動時にホストの.ssh/をイメージ内の適当なところにマウント

ssh/configにポートフォワーディングを書く

Host neptune
    HostName 踏み台EC2のPublicIP
    User ec2-user
    IdentityFile ~/.ssh/EC2の鍵ファイル.pem
    GatewayPorts   yes
    LocalForward 8182 接続したいNeptuneクラスターエンドポイント:8182

Dockerfileの用意

とりあえずpython3.6の公式イメージを使います。

FROM python:3.6

RUN apt-get update -y && apt-get upgrade -y
RUN apt-get install autossh -y

RUN mkdir /root/.ssh

docker-compose.ymlの用意

足りないところは補完してください。
私がやっていることは

  1. ホストの.ssh/configをコンテナの/root/.sshdummyにマウントする
  2. コンテナ内で、EC2の鍵ファイルを、/root/.sshにコピーする
  3. 鍵ファイルのパーミッションを設定する
  4. ポートフォワーディングする
  5. /bin/bashで起動

また、extra_hostsでローカルホストにNeptuneクラスターのエンドポイントを紐づけている理由は、今回pythonで使うgremlin-pythonhttps://localhostという接続だとエラーが起こるためです。

version: '3'
services:
  gremlin:
    command: >
      /bin/bash -c "cp /root/.sshdummy/config /root/.ssh/ && 
      cp /root/.sshdummy/EC2の鍵ファイル.pem /root/.ssh/ && 
      chmod 600 /root/.ssh/EC2の鍵ファイル.pem &&
      autossh neptune -f -N &&
      /bin/bash"
    volumes:
      - ~/.ssh:/root/.sshdummy
      - 
    extra_hosts:
      - "Neptuneクラスターエンドポイント:127.0.0.1"

とりあえず、接続チェック

docker-compose run gremlin

で、中にはいって以下を叩いてみます。

curl https://Neptuneクラスターのエンドポイント:8182

> {"requestId":"28b45dc4-842c-c129-2d4d-******","detailedMessage":"no gremlin script supplied","code":"MissingParameterException"}

帰ってきました。接続オッケーです。

gremlin-pythonを使ってみる

パッケージのインストールをします。

pip install gremlinpython

私は、現在駅すぱあとという経路検索サービスを提供する会社に現在勤めているので、駅データと路線データをNeptuneにロードして簡単な経路検索をしてみようと思います。

せっかくグラフDBを使うので、N頂点〜N頂点の経路検索を一度にやってみます。

from gremlin_python import statics
from gremlin_python.structure.graph import Graph
from gremlin_python.process.graph_traversal import __
from gremlin_python.process.strategies import *
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
from gremlin_python.structure.graph import VertexProperty
import time

graph = Graph()
g = graph.traversal().withRemote(DriverRemoteConnection('wss://Neptuneクラスターのエンドポイント:8182/gremlin','g'))

# 出発地点
origin = g.V().has('station', '県コードキー', '県コード').has('駅種別キー', 駅種別).sample(10).toList()

# 到着地点
destination = g.V().has('station', '県コードキー', '県コード').has('駅種別キー', 駅種別).sample(10).toList()

# 頂点IDの配列化
origin_ids = [x.id for x in origin]
destination_ids = [x.id for x in destination]

start_time = time.time()
result = g.V().hasId(*origin_ids).repeat(__.outE().hasLabel('特定の辺のラベルのみ').inV().simplePath()).until(__.hasId(*destination_ids)).path().limit(100).map(__.unfold().hasLabel('station').values('name').fold())

for path in result.toList():
    print('->'.join(path))

print(time.time() - start_time)

結果

大崎広小路->五反田->戸越->中延
大崎広小路->戸越銀座->荏原中延->旗の台->荏原町->中延
青物横丁->新馬場->北品川->品川->大崎->五反田->大崎広小路
大崎広小路->五反田->大崎->大井町->下神明->戸越公園->中延

〜〜〜〜 省略 〜〜〜〜〜

代田橋->笹塚->新宿->四ツ谷->御茶ノ水->秋葉原->浅草橋->両国->錦糸町->押上
大崎広小路->五反田->大崎->品川->新橋->東銀座->銀座->東京->上野->日暮里->新三河島
青物横丁->新馬場->北品川->品川->新橋->東銀座->銀座->東京->上野->日暮里->新三河島
代田橋->笹塚->新宿->池袋->板橋->十条(東京都)->赤羽->尾久->上野->日暮里->新三河島0.43123531341552734(←処理時間

できました。

気をつけたいこと

  • Neptuneで使えるGremlinは完全互換があるとは言えません。

  • Gremlinムズカシー(愚痴) :tired_face:

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?