0
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 3 years have passed since last update.

gremlin-server コンテナを立ち上げる

Last updated at Posted at 2021-09-05

はじめに

gremlin を気軽に使いたいなと思って始めたら、まあまあハマったので、他の方も同じ目に合わないために、記録しておきます。
gremlin console, gremlin python を使うための環境構築を中心に記録していきます。

とにかく、古い海外の情報しか見つけられず、情報整理・実験に時間がかなりかかりました・・

TL;DR

  • サンプルそのままでは動作しない
  • gremlin-server.yml をセットアップ
    • host を、0.0.0.0 に
    • serializer を設定
  • remote.yml をセットアップ
  • バージョンを揃える!
    • バージョンにかなりセンシティブな印象
      • gremlin-server
      • gremlin-console
      • gremlin python
  • コード一式は、こちら

環境

対象 バージョン
OS macOS Big Sur (11.5.2)
docker Docker version 20.10.8, build 3967b7d
docker-compose docker-compose version 1.29.2, build 5becea4c
python Python 3.8.10

セットアップでやったこと

Dockerfile

gremlin-server

以下の内容の Dockerfile を作成

docker/gremlin/server/Dockerfile
FROM tinkerpop/gremlin-server:3.4.8

WORKDIR /opt/gremlin-server/

ARG gremlin_version=3.4.8
RUN /bin/bash -c "bin/gremlin-server.sh install org.apache.tinkerpop gremlin-python ${gremlin_version}"
RUN /bin/bash -c "bin/gremlin-server.sh install org.apache.tinkerpop neo4j-gremlin ${gremlin_version}"

gremlin-python をインストールしておきます。
あとで、neo4j も試したいので、neo4j-gremlin も入れておきます。

gremlin-console

結局、Dockerfile 作らなくてもよかったんですが、何かインストールするかもしれないと作成していたので、そのまま Dockerfile に残しておきます。

docker/gremlin/console/Dockerfile
FROM tinkerpop/gremlin-console:3.4.8

ここで、tinkerpop/gremlin-server とバージョンがあってないと、console 利用時にうまく通信できずエラーになります。少なくとも、ためした範囲ではそうでした。

docker-compose.override.yml

docker-compose.yml に追記しても良かったのですが、開発用のコンテナ(app)がなくても動かせるように、override に切り出しました。

こんな感じです。

docker-compose.override.yml
version: '3.7'

services:
  gremlin-console:
    build:
      context: ./
      dockerfile: docker/gremlin/console/Dockerfile
    image: $project.gremlin-console
    container_name: $project.gremlin-console
    volumes:
      - ./data/:/data/
      - ./conf/gremlin/console/remote.yml:/opt/gremlin-console/conf/remote.yml
      - ./conf/gremlin/console/remote-research.yml:/opt/gremlin-console/conf/remote-research.yml

  gremlin-server:
    build:
      context: ./
      dockerfile: docker/gremlin/server/Dockerfile
    image: $project.gremlin-server
    container_name: $project.gremlin-server
    ports:
      - "8182:8182"
    volumes:
      - ./data/:/data/
      - ./conf/gremlin/server/gremlin-server.yml:/opt/gremlin-server/conf/gremlin-server.yml
      - ./conf/gremlin/server/gremlin-server-neo4j.yml:/opt/gremlin-server/conf/gremlin-server-neo4j.yml
      - ./conf/gremlin/server/neo4j.properties:/opt/gremlin-server/conf/neo4j.properties
    entrypoint: >
      /bin/bash bin/gremlin-server.sh conf/gremlin-server.yml
      # /bin/bash bin/gremlin-server.sh conf/gremlin-server-neo4j.yml

ここで、設定ファイルを変更するため、ローカルの設定ファイル(conf 配下)をマウントしておき、entrypoint を上書きしています。
tinkerpop/gremlin-server のエントリーポイントが、設定ファイルの host を sed -i で変更したり、拡張子が yml じゃなくて、yaml なのが好みに合わなかったので、entrypoint を上書きする方法を取りました。

※ Ubuntu 18.04 on WSL2 では、docker-server が、gremlin 用のユーザとグループ(100:101)で起動されるので、/data などにマウントしたり、ホストとファイル共有する際には、注意が必要です(自分は、この記事で紹介しているリポジトリではないですが、起動前に、chown する make タスクを作成しました。)

設定ファイルの作成&変更

gremlin-server のコンテナに入って、gremlin-server.yaml をマウントした共有フォルダ(/data など)を経由して、gremlin-server.yml として保存しておきます。(拡張子を変えておく、yaml -> yml

gremlin-server.yml の変更点

host を変更

よくある、バインドするhost について、localhost を、0.0.0.0 に変更します。

conf/gremlin/server/gremlin-server.yml
host: 0.0.0.0

serializers に追加

gremlin 3.4.8 では、GryoMessageSerializerV3d0 (V3) を使うみたいなので、追記しておきます。(設定しないと、console 利用時にエラーになります)

conf/gremlin/server/gremlin-server.yml
serializers:
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0, config: { useMapperFromGraph: graph }}            # application/vnd.gremlin-v1.0+gryo
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoLiteMessageSerializerV3d0, config: { useMapperFromGraph: graph }}        # application/vnd.gremlin-v1.0+gryo-lite
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0, config: { serializeResultToString: true }}        # application/vnd.gremlin-v1.0+gryo-stringd

remote.yml の作成

gremlin-console 利用時に、gremlin-server へ接続するための設定ファイルを作成しておきます。
ファイル名は、remote.yml でなくてもよいです、その際は、gremlin-console のプロンプトで :remote connect tinkerpop.server conf/remote.yml を実行する際に、remote.yml のところを変更したファイル名に変更してください。

conf/gremlin/console/remote.yml
hosts: [gremlin-server]
port: 8182

gremlin-python をインストール

開発用の Dockerfile でインストールに使う requirements.txt を作成しておきます。
gremlinpython の バージョンを、gremlin-server, gremlin-console に合わせて、3.4.8 を指定します。(ここも重要です!)

requirements.txt
# for sqa
pudb
pylint
flake8
black
coverage
pytest
pytest-flake8
pytest-cov
pytest-xdist
pytest-html
docutils==0.15
Sphinx

# for graph db
neo4j
neomodel
gremlinpython==3.4.8

以上で、セットアップは完了です。では、使っていきましょう

環境構築

リポジトリをクローン

リポジトリとして、まとめたのでクローンしてご利用ください。

git clone https://github.com/tkosht/gremlin
cd gremlin

コンテナのビルド&起動

make

起動確認

docker-compose ps または、make ps (docker-compose ps を Makefile でタスク定義したもの)で、確認します。

make ps
~/p/gremlin ❯❯❯ make ps
docker-compose ps
         Name                       Command               State                    Ports                  
----------------------------------------------------------------------------------------------------------
gremlin.app              /bin/bash                        Up                                              
gremlin.gremlin-server   /bin/bash bin/gremlin-serv ...   Up      0.0.0.0:8182->8182/tcp,:::8182->8182/tcp
~/p/gremlin ❯❯❯ 

上のような感じで表示されれば、OKです。

使ってみる

gremlin-console から使う

gremlin-console の コマンドを並べたものを、src/gremlin/test.gremlin として保存しているので、そのコマンドをリダイレクトして実行します。

~/p/gremlin ❯❯❯ make gremlin-console < src/gremlin/test.gremlin
docker-compose up -d app gremlin-server
gremlin.gremlin-server is up-to-date
gremlin.app is up-to-date
docker-compose run --rm gremlin-console
Creating gremlin_gremlin-console_run ... done
Sep 05, 2021 12:27:37 PM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.

         \,,,/
         (o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin> :remote connect tinkerpop.server conf/remote.yml
==>Configured gremlin-server/172.30.0.2:8182
gremlin> :remote console
==>All scripts will now be sent to Gremlin Server - [gremlin-server/172.30.0.2:8182] - type ':remote console' to return to local mode
gremlin> g.addV('person').property('name','hello')
==>v[0]
gremlin> g.addV('person').property('name','world')
==>v[2]
gremlin> g.V().values('name')
==>hello
==>world
gremlin> g.V().count()
==>2
gremlin> :exit
~/p/gremlin ❯❯❯ 

上のような出力結果が得られれば成功です!

python から使う

以下のように、make bash で開発用コンテナをインタラクティブモードで起動し、python モジュール src.trial を実行します。

~/p/gremlin ❯❯❯ make bash
docker-compose up -d app gremlin-server
gremlin.app is up-to-date
gremlin.gremlin-server is up-to-date
docker-compose exec app bash
dsuser@8307be2e3004:~/workspace$ python -m src.trial
names: ['hello', 'world']
dict: [{'name': ['hello']}, {'name': ['world']}]
count: 2
dsuser@8307be2e3004:~/workspace$ 

以上のように、表示されれば、成功です!

注意

コンテナを停止・削除(docker-compose down)すると、gremlin 上で作成・追加したグラフが消えます。

簡易エクスポート

エクスポートするための簡単な gremlin-console 用のスクリプト(src/gremlin/export.gremlin)を作成したので、ご利用ください。
data/test.json に保存します。

~/p/gremlin ❯❯❯ make gremlin-console < src/gremlin/export.gremlin
docker-compose up -d app gremlin-server
gremlin.app is up-to-date
gremlin.gremlin-server is up-to-date
docker-compose run --rm gremlin-console
Creating gremlin_gremlin-console_run ... done
Sep 05, 2021 12:37:37 PM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.

         \,,,/
         (o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin> :remote connect tinkerpop.server conf/remote.yml
==>Configured gremlin-server/172.30.0.2:8182
gremlin> :remote console
==>All scripts will now be sent to Gremlin Server - [gremlin-server/172.30.0.2:8182] - type ':remote console' to return to local mode
gremlin> // g.addV('person').property('name','hello')
==>null
gremlin> // g.addV('person').property('name','world')
==>null
gremlin> g.V().values('name')
==>hello
==>world
gremlin> g.V().count()
==>2
gremlin> g.io("/data/test.json").write()
gremlin> :exit
~/p/gremlin ❯❯❯ cat data/test.json
{"id":{"@type":"g:Int64","@value":0},"label":"person","properties":{"name":[{"id":{"@type":"g:Int64","@value":1},"value":"hello"}]}}
{"id":{"@type":"g:Int64","@value":2},"label":"person","properties":{"name":[{"id":{"@type":"g:Int64","@value":3},"value":"world"}]}}
~/p/gremlin ❯❯❯ 

簡易インポート

インポートするための簡単な gremlin-console 用のスクリプト(src/gremlin/import.gremlin)を作成したので、ご利用ください。
data/test.json からロードします。

動作確認のために、gremlin-server を down & up しておきます。

~/p/gremlin ❯❯❯ make reup
docker-compose down
Stopping gremlin.gremlin-server ... done
Stopping gremlin.app            ... done
Removing gremlin.gremlin-server ... done
Removing gremlin.app            ... done
Removing network gremlin_default
docker-compose up -d app gremlin-server
Creating network "gremlin_default" with the default driver
Creating gremlin.gremlin-server ... done
Creating gremlin.app            ... done
~/p/gremlin ❯❯❯ make gremlin-console < src/gremlin/ref.gremlin
docker-compose up -d app gremlin-server
gremlin.gremlin-server is up-to-date
gremlin.app is up-to-date
docker-compose run --rm gremlin-console
Creating gremlin_gremlin-console_run ... done
Sep 05, 2021 12:40:24 PM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.

         \,,,/
         (o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin> :remote connect tinkerpop.server conf/remote.yml
==>Configured gremlin-server/172.31.0.3:8182
gremlin> :remote console
==>All scripts will now be sent to Gremlin Server - [gremlin-server/172.31.0.3:8182] - type ':remote console' to return to local mode
gremlin> g.V().values('name')
gremlin> g.V().count()
==>0
gremlin> :exit
~/p/gremlin ❯❯❯ 

次に、インポートします。

~/p/gremlin ❯❯❯ make gremlin-console < src/gremlin/import.gremlin
docker-compose up -d app gremlin-server
gremlin.app is up-to-date
gremlin.gremlin-server is up-to-date
docker-compose run --rm gremlin-console
Creating gremlin_gremlin-console_run ... done
Sep 05, 2021 12:41:36 PM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.

         \,,,/
         (o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin> :remote connect tinkerpop.server conf/remote.yml
==>Configured gremlin-server/172.31.0.3:8182
gremlin> :remote console
==>All scripts will now be sent to Gremlin Server - [gremlin-server/172.31.0.3:8182] - type ':remote console' to return to local mode
gremlin> g.io("/data/test.json").read()
gremlin> g.V().values('name')
==>hello
==>world
gremlin> g.V().count()
==>2
gremlin> :exit
~/p/gremlin ❯❯❯ 

ロードできているか確認します。

~/p/gremlin ❯❯❯ make gremlin-console < src/gremlin/ref.gremlin
docker-compose up -d app gremlin-server
gremlin.gremlin-server is up-to-date
gremlin.app is up-to-date
docker-compose run --rm gremlin-console
Creating gremlin_gremlin-console_run ... done
Sep 05, 2021 12:42:30 PM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.

         \,,,/
         (o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin> :remote connect tinkerpop.server conf/remote.yml
==>Configured gremlin-server/172.31.0.3:8182
gremlin> :remote console
==>All scripts will now be sent to Gremlin Server - [gremlin-server/172.31.0.3:8182] - type ':remote console' to return to local mode
gremlin> g.V().values('name')
==>hello
==>world
gremlin> g.V().count()
==>2
gremlin> :exit
WARN  io.netty.channel.nio.NioEventLoop  - Selector.select() returned prematurely 512 times in a row; rebuilding Selector io.netty.channel.nio.SelectedSelectionKeySetSelector@239e1c3a.
~/p/gremlin ❯❯❯ 

hello, world が ロードされていることが確認できました。

おっと、WARN も出てますね。。
:exit 後なので、一旦、置いておきます。

まとめ

上位互換性を結構期待して、環境セットアップをやってたら、本当にハマりました。
gremlin は、バージョンセンシティブだとかなり、体験できました。今後、間違いなく気をつけるでしょう笑。

同じように苦労し始めている方の助けになれば幸いです。

サーバ down&up の度に、export & import するのは微妙なので、
次は、neo4j ファイルとして永続化する方法を整理したいと思います。

Makefile のタスクとして定義すれば、export & import を毎回やってもよいのですが、データ量が増えた時は、export & import コストも侮れないと思いますので。

参考URL

めちゃくちゃ調べたんですが、記憶に残っているサイトだけ・・
Stack Overflow のサイトとか・・忘れました( ; ; )

0
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
0
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?