1. 程式人生 > 實用技巧 >準備執行Gremlin的圖形化環境

準備執行Gremlin的圖形化環境

背景

Gremlin是Apache TinkerPop框架下實現的圖遍歷語言,支援OLTP與OLAP,是目前圖資料庫領域主流的查詢語言,可類比SQL語言之於關係型資料庫。

HugeGraph是國內的一款開源圖資料庫,完全支援Gremlin語言。本文將講述如何基於HugeGraph搭建一個執行Gremlin的圖形化環境。

HugeGraph的github倉庫下有很多子專案,我們這裡只需要使用其中的兩個:hugegraphhugegraph-studio

部署HugeGraphServer

準備安裝包

方式一:原始碼編譯打包

進入hugegraph專案,克隆程式碼庫

進入終端

$ git clone git@github.com:hugegraph/hugegraph.git

完成後會在當前目錄下多出來一個hugegraph的子目錄,不過這個目錄裡面的檔案是原始碼,我們需要編譯打包才能生成可以執行包。

進入hugegraph目錄,執行命令:

$ git checkout release-0.7
$ mvn package -DskipTests

注意:一定要先切換分支,hugegraph主分支上版本已經升級到0.8.0了,但是studio似乎還沒有升級,為避免踩坑我們還是使用已釋出版。

經過一長串的控制檯輸出後,最後如果能看到BUILD SUCCESS表示打包成功。

打包成功日誌
這時會在當前目錄下多出來一個子目錄hugegraph-0.7.4
和一個壓縮包hugegraph-0.7.4.tar.gz,這就是我們即將要使用可以執行的包。

本人有輕微強迫症,不喜歡原始碼和二進位制包放在一起,容易混淆,所以把hugegraph-0.7.4拷到上一層目錄,然後刪除原始碼目錄,這樣上層目錄又迴歸清爽了。

$ mv hugegraph-0.7.4 ../hugegraph-0.7.4
$ cd ..
$ rm -rf hugegraph

到這兒安裝包就準備好了。不過,這樣操作是需要你本地裝了jdkgitmaven命令列工具的,如果你沒有安裝也沒關係,我們還可以直接下載hugegraph官方的release包。

方法二:直接下載release

點選github程式碼的上面的導航releases

可以看到hugegraph目前有兩個release,點選hugegraph-0.7.4.tar.gz就開始下載了。

releases

下載完之後解壓即可

$ tar -zxvf hugegraph-0.7.4.tar.gz

解壓完之後能看到一個hugegraph-0.7.4目錄,這個目錄和用原始碼包打包生成的是一樣的。

下面講解如何配置引數。

配置引數

雖然標題叫配置引數,但其實hugegraph的預設配置就已經能在大部分環境下直接使用了,不過還是說明一下幾個重要的配置項。

進入hugegraph-0.7.4目錄,修改HugeGraphServer提供服務的url (host + port)

$ vim conf/rest-server.properties
# bind url
restserver.url=http://127.0.0.1:8080

# gremlin url to connect
gremlinserver.url=http://127.0.0.1:8182

# graphs list with pair NAME:CONF_PATH
graphs=[hugegraph:conf/hugegraph.properties]

# authentication
#auth.require_authentication=
#auth.admin_token=
#auth.user_tokens=[]

restserver.url就是HugeGraphServer對外提供RESTful API服務的地址,host127.0.0.1時只能在本機訪問的,按需要修改其中的hostport部分即可。我這裡由於studio也是準備在本地啟動,8080埠也沒有其他服務佔用,所以不修改它。

graphs是可供連線的圖名與配置項的鍵值對列表,hugegraph:conf/hugegraph.properties表示通過HugeGraphServer可以訪問到一個名為hugegraph的圖例項,該圖的配置檔案路徑為conf/hugegraph.properties。我們可以不用去管圖的配置檔案,按需要修改圖的名字即可。我這裡仍然沒有修改它。

初始化後端

hugegraph啟動服務之前是需要手動初始化後端的,不過大家也不要看到“手動”兩個字就害怕,其實就是調一個命令的事。

$ bin/init-store.sh
Initing HugeGraph Store...
2018-09-07 16:02:12 1082  [main] [INFO ] com.baidu.hugegraph.cmd.InitStore [] - Init graph with config file: conf/hugegraph.properties
2018-09-07 16:02:12 1201  [main] [INFO ] com.baidu.hugegraph.HugeGraph [] - Opening backend store 'rocksdb' for graph 'hugegraph'
2018-09-07 16:02:12 1258  [main] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStore [] - Opening RocksDB with data path: rocksdb-data/schema
2018-09-07 16:02:12 1417  [main] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStore [] - Failed to open RocksDB 'rocksdb-data/schema' with database 'hugegraph', try to init CF later
2018-09-07 16:02:12 1445  [main] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStore [] - Opening RocksDB with data path: rocksdb-data/system
2018-09-07 16:02:12 1450  [main] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStore [] - Failed to open RocksDB 'rocksdb-data/system' with database 'hugegraph', try to init CF later
2018-09-07 16:02:12 1456  [main] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStore [] - Opening RocksDB with data path: rocksdb-data/graph
2018-09-07 16:02:12 1461  [main] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStore [] - Failed to open RocksDB 'rocksdb-data/graph' with database 'hugegraph', try to init CF later
2018-09-07 16:02:12 1491  [main] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStore [] - Store initialized: schema
2018-09-07 16:02:12 1511  [main] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStore [] - Store initialized: system
2018-09-07 16:02:12 1543  [main] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStore [] - Store initialized: graph
2018-09-07 16:02:13 1804  [pool-3-thread-1] [INFO ] com.baidu.hugegraph.backend.Transaction [] - Clear cache on event 'store.init'

這裡可以看到,hugegraph初始化了rocksdb後端,那為什麼是rocksdb而不是別的呢,其實就是上一步說的conf/hugegraph.properties中配置的。

$ vim conf/hugegraph.properties
# gremlin entrence to create graph
gremlin.graph=com.baidu.hugegraph.HugeFactory

# cache config
#schema.cache_capacity=1048576
#graph.cache_capacity=10485760
#graph.cache_expire=600

# schema illegal name template
#schema.illegal_name_regex=\s+|~.*

#vertex.default_label=vertex

backend=rocksdb
serializer=binary

store=hugegraph

# rocksdb backend config
#rocksdb.data_path=/path/to/disk
#rocksdb.wal_path=/path/to/disk
...

其中backend=rocksdb就是設定後端為rocksdb的配置項。

其他的後端還包括:memorycassandrascylladbhbasemysqlpalo。我們這裡不用去管它,用預設的rocksdb即可。

初始化完成之後,會在當前目錄下出現一個rocksdb-data的目錄,這就是存放後端資料的地方,沒事千萬不要隨意刪它或移動它。

注意:初始化後端這個操作只需要在第一次啟動服務前執行一次,不要每次起服務都執行。不過即使執行了也沒關係,hugegraph檢測到已經初始化過了會跳過。

啟動服務

終於到了啟動服務了,同樣也是一條命令

$ bin/start-hugegraph.sh
Starting HugeGraphServer...
Connecting to HugeGraphServer (http://127.0.0.1:8080/graphs)....OK

看到上面的OK就表示啟動成功了,我們可以jps看一下程序。

$ jps
...
4101 HugeGraphServer
4233 Jps
...

如果還不放心,我們可以發個HTTP請求試試看。

$ curl http://127.0.0.1:8080/graphs
{"graphs":["hugegraph"]}

到這裡HugeGraphServer的部署就完成了,接下來我們來部署HugeGraphStudio

部署HugeGraphStudio

步驟與部署HugeGraphServer大體類似,我們就不那麼囉嗦了。

記得先返回最上層目錄,避免目錄巢狀在一起了。

準備安裝包

克隆程式碼庫

$ git clone [email protected]:hugegraph/hugegraph-studio.git
Cloning into 'hugegraph-studio'...
mux_client_request_session: read from master failed: Broken pipe
remote: Counting objects: 326, done.
remote: Compressing objects: 100% (189/189), done.
remote: Total 326 (delta 115), reused 324 (delta 113), pack-reused 0
Receiving objects: 100% (326/326), 1.60 MiB | 350.00 KiB/s, done.
Resolving deltas: 100% (115/115), done.

編譯打包

studio是一個包含前端的專案,使用react.js實現,自行打包的話需要安裝npmwebpack等工具。

$ cd hugegraph-studio
$ mvn package -DskipTests

studio打包的時間會稍長一點。

...
[INFO] Reactor Summary:
[INFO]
[INFO] hugegraph-studio ................................... SUCCESS [  0.003 s]
[INFO] studio-api ......................................... SUCCESS [  4.683 s]
[INFO] studio-dist ........................................ SUCCESS [01:42 min]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:47 min
[INFO] Finished at: 2018-09-07T16:32:44+08:00
[INFO] Final Memory: 34M/390M
[INFO] ------------------------------------------------------------------------

將打包好的目錄拷到上一層,刪除原始碼目錄(純個人喜好)。

$ mv hugegraph-studio-0.7.0 ../
$ cd ..
$ rm -rf hugegraph-studio

至此,我的最上層目錄就只剩下兩個安裝包,如下:

$ ls
hugegraph-0.7.4        hugegraph-studio-0.7.0

配置引數

進入hugegraph-studio-0.7.0目錄,修改唯一的一個配置檔案。

$ cd  hugegraph-studio-0.7.0
$ vim conf/hugegraph-studio.properties
studio.server.port=8088
studio.server.host=localhost

graph.server.host=localhost
graph.server.port=8080
graph.name=hugegraph

# the directory name released by react
studio.server.ui=ui
# the file location of studio-api.war
studio.server.api.war=war/studio-api.war
# default folder in your home directory, set to a non-empty value to override
data.base_directory=~/.hugegraph-studio

show.limit.data=250
show.limit.edge.total=1000
show.limit.edge.increment=20

# separator ','
gremlin.limit_suffix=[.V(),.E(),.hasLabel(STR),.hasLabel(NUM),.path()]

需要修改的引數是graph.server.host=localhostgraph.server.port=8080graph.name=hugegraph。它們與HugeGraphServer的配置檔案conf/rest-server.properties中的配置項對應,其中:

  • graph.server.host=localhostrestserver.url=http://127.0.0.1:8080host對應;
  • graph.server.port=8080與的restserver.url=http://127.0.0.1:8080port對應;
  • graph.name=hugegraphgraphs=[hugegraph:conf/hugegraph.properties]的圖名對應。

因為我之前並沒有修改HugeGraphServer的配置檔案conf/rest-server.properties,所以這裡也不需要修改HugeGraphStudio的配置檔案conf/hugegraph-studio.properties

啟動服務

$ bin/hugegraph-studio.sh

studio的啟動預設是不會放到後臺的,所以我們會在控制檯上看到一大串日誌,在最底下看到如下日誌表示啟動成功:

資訊: Starting ProtocolHandler [http-nio-127.0.0.1-8088]
16:56:24.507 [main] INFO  com.baidu.hugegraph.studio.HugeGraphStudio ID:  TS: - HugeGraphStudio is now running on: http://localhost:8088

然後我們按照提示,在瀏覽器中輸入http://localhost:8088,就進入了studio的介面:

studio介面

圖中Gremlin下的框,就是我們輸入gremlin語句進而操作hugegraph的入口了,下面我們給出一個例子。

建立關係圖

以下內容參考CSDN部落格通過Gremlin語言構建關係圖並進行圖分析

在輸入框中輸入以下程式碼以建立一個“TinkerPop關係圖”:

// PropertyKey
graph.schema().propertyKey("name").asText().ifNotExist().create()
graph.schema().propertyKey("age").asInt().ifNotExist().create()
graph.schema().propertyKey("addr").asText().ifNotExist().create()
graph.schema().propertyKey("lang").asText().ifNotExist().create()
graph.schema().propertyKey("tag").asText().ifNotExist().create()
graph.schema().propertyKey("weight").asFloat().ifNotExist().create()

// VertexLabel
graph.schema().vertexLabel("person").properties("name", "age", "addr", "weight").useCustomizeStringId().ifNotExist().create()
graph.schema().vertexLabel("software").properties("name", "lang", "tag", "weight").primaryKeys("name").ifNotExist().create()
graph.schema().vertexLabel("language").properties("name", "lang", "weight").primaryKeys("name").ifNotExist().create()

// EdgeLabel
graph.schema().edgeLabel("knows").sourceLabel("person").targetLabel("person").properties("weight").ifNotExist().create()
graph.schema().edgeLabel("created").sourceLabel("person").targetLabel("software").properties("weight").ifNotExist().create()
graph.schema().edgeLabel("contains").sourceLabel("software").targetLabel("software").properties("weight").ifNotExist().create()
graph.schema().edgeLabel("define").sourceLabel("software").targetLabel("language").properties("weight").ifNotExist().create()
graph.schema().edgeLabel("implements").sourceLabel("software").targetLabel("software").properties("weight").ifNotExist().create()
graph.schema().edgeLabel("supports").sourceLabel("software").targetLabel("language").properties("weight").ifNotExist().create()

// TinkerPop
okram = graph.addVertex(T.label, "person", T.id, "okram", "name", "Marko A. Rodriguez", "age", 29, "addr", "Santa Fe, New Mexico", "weight", 1)
spmallette = graph.addVertex(T.label, "person", T.id, "spmallette", "name", "Stephen Mallette", "age", 0, "addr", "", "weight", 1)

tinkerpop = graph.addVertex(T.label, "software", "name", "TinkerPop", "lang", "java", "tag", "Graph computing framework", "weight", 1)
tinkergraph = graph.addVertex(T.label, "software", "name", "TinkerGraph", "lang", "java", "tag", "In-memory property graph", "weight", 1)
gremlin = graph.addVertex(T.label, "language", "name", "Gremlin", "lang", "groovy/python/javascript", "weight", 1)

okram.addEdge("created", tinkerpop, "weight", 1)
spmallette.addEdge("created", tinkerpop, "weight", 1)

okram.addEdge("knows", spmallette, "weight", 1)

tinkerpop.addEdge("define", gremlin, "weight", 1)
tinkerpop.addEdge("contains", tinkergraph, "weight", 1)
tinkergraph.addEdge("supports", gremlin, "weight", 1)

// Titan
dalaro = graph.addVertex(T.label, "person", T.id, "dalaro", "name", "Dan LaRocque ", "age", 0, "addr", "", "weight", 1)
mbroecheler = graph.addVertex(T.label, "person", T.id, "mbroecheler", "name", "Matthias Broecheler", "age", 29, "addr", "San Francisco", "weight", 1)

titan = graph.addVertex(T.label, "software", "name", "Titan", "lang", "java", "tag", "Graph Database", "weight", 1)

dalaro.addEdge("created", titan, "weight", 1)
mbroecheler.addEdge("created", titan, "weight", 1)
okram.addEdge("created", titan, "weight", 1)

dalaro.addEdge("knows", mbroecheler, "weight", 1)

titan.addEdge("implements", tinkerpop, "weight", 1)
titan.addEdge("supports", gremlin, "weight", 1)

// HugeGraph
javeme = graph.addVertex(T.label, "person", T.id, "javeme", "name", "Jermy Li", "age", 29, "addr", "Beijing", "weight", 1)
zhoney = graph.addVertex(T.label, "person", T.id, "zhoney", "name", "Zhoney Zhang", "age", 29, "addr", "Beijing", "weight", 1)
linary = graph.addVertex(T.label, "person", T.id, "linary", "name", "Linary Li", "age", 28, "addr", "Wuhan. Hubei", "weight", 1)

hugegraph = graph.addVertex(T.label, "software", "name", "HugeGraph", "lang", "java", "tag", "Graph Database", "weight", 1)

javeme.addEdge("created", hugegraph, "weight", 1)
zhoney.addEdge("created", hugegraph, "weight", 1)
linary.addEdge("created", hugegraph, "weight", 1)

javeme.addEdge("knows", zhoney, "weight", 1)
javeme.addEdge("knows", linary, "weight", 1)

hugegraph.addEdge("implements", tinkerpop, "weight", 1)
hugegraph.addEdge("supports", gremlin, "weight", 1)

點選右上角的三角按鈕,這樣就創建出了一個圖。

圖查詢

在輸入框中輸入:

g.V()

就能查出上面建立的圖的所有頂點和邊。

TinkerPop關係圖

至此,執行Gremlin的圖形化環境就已經搭建完成,後續就可以做各種各樣炫酷的gremlin查詢了。



作者:蘇黎世黃昏
連結:https://www.jianshu.com/p/618cf6667381
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。