背景
Gremlin是Apache TinkerPop框架下實(shí)現(xiàn)的圖遍歷語言鹦蠕,支持OLTP與OLAP,是目前圖數(shù)據(jù)庫領(lǐng)域主流的查詢語言在抛,可類比SQL語言之于關(guān)系型數(shù)據(jù)庫钟病。
HugeGraph是國內(nèi)的一款開源圖數(shù)據(jù)庫,完全支持Gremlin語言刚梭。本文將講述如何基于HugeGraph搭建一個(gè)執(zhí)行Gremlin的圖形化環(huán)境肠阱。
HugeGraph的github倉庫下有很多子項(xiàng)目,我們這里只需要使用其中的兩個(gè):hugegraph
和hugegraph-studio
望浩。
部署HugeGraphServer
準(zhǔn)備安裝包
方式一:源碼編譯打包
進(jìn)入hugegraph項(xiàng)目辖所,克隆代碼庫
進(jìn)入終端
$ git clone git@github.com:hugegraph/hugegraph.git
完成后會(huì)在當(dāng)前目錄下多出來一個(gè)hugegraph
的子目錄,不過這個(gè)目錄里面的文件是源代碼磨德,我們需要編譯打包才能生成可以運(yùn)行包缘回。
進(jìn)入hugegraph
目錄,執(zhí)行命令:
$ git checkout release-0.7
$ mvn package -DskipTests
注意:一定要先切換分支典挑,hugegraph主分支上版本已經(jīng)升級(jí)到
0.8.0
了酥宴,但是studio似乎還沒有升級(jí),為避免踩坑我們還是使用已發(fā)布版您觉。
經(jīng)過一長串的控制臺(tái)輸出后拙寡,最后如果能看到BUILD SUCCESS
表示打包成功。
這時(shí)會(huì)在當(dāng)前目錄下多出來一個(gè)子目錄
hugegraph-0.7.4
和一個(gè)壓縮包hugegraph-0.7.4.tar.gz
琳水,這就是我們即將要使用可以運(yùn)行的包肆糕。
本人有輕微強(qiáng)迫癥,不喜歡源代碼和二進(jìn)制包放在一起在孝,容易混淆诚啃,所以把hugegraph-0.7.4
拷到上一層目錄,然后刪除源代碼目錄私沮,這樣上層目錄又回歸清爽了始赎。
$ mv hugegraph-0.7.4 ../hugegraph-0.7.4
$ cd ..
$ rm -rf hugegraph
到這兒安裝包就準(zhǔn)備好了。不過仔燕,這樣操作是需要你本地裝了jdk
造垛、git
和maven
命令行工具的,如果你沒有安裝也沒關(guān)系晰搀,我們還可以直接下載hugegraph
官方的release
包五辽。
方法二:直接下載release
包
點(diǎn)擊github
代碼的上面的導(dǎo)航releases
可以看到hugegraph目前有兩個(gè)release,點(diǎn)擊hugegraph-0.7.4.tar.gz
就開始下載了外恕。
下載完之后解壓即可
$ tar -zxvf hugegraph-0.7.4.tar.gz
解壓完之后能看到一個(gè)hugegraph-0.7.4
目錄奔脐,這個(gè)目錄和用源碼包打包生成的是一樣的俄周。
下面講解如何配置參數(shù)。
配置參數(shù)
雖然標(biāo)題叫配置參數(shù)髓迎,但其實(shí)hugegraph
的默認(rèn)配置就已經(jīng)能在大部分環(huán)境下直接使用了,不過還是說明一下幾個(gè)重要的配置項(xiàng)建丧。
進(jìn)入hugegraph-0.7.4
目錄排龄,修改HugeGraphServer
提供服務(wù)的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
對(duì)外提供RESTful API
服務(wù)的地址,host
為127.0.0.1
時(shí)只能在本機(jī)訪問的橄维,按需要修改其中的host
和port
部分即可。我這里由于studio
也是準(zhǔn)備在本地啟動(dòng),8080
端口也沒有其他服務(wù)占用委乌,所以不修改它。
graphs
是可供連接的圖名與配置項(xiàng)的鍵值對(duì)列表,hugegraph:conf/hugegraph.properties
表示通過HugeGraphServer
可以訪問到一個(gè)名為hugegraph
的圖實(shí)例耳贬,該圖的配置文件路徑為conf/hugegraph.properties
。我們可以不用去管圖的配置文件,按需要修改圖的名字即可挤渔。我這里仍然沒有修改它。
初始化后端
hugegraph
啟動(dòng)服務(wù)之前是需要手動(dòng)初始化后端的绕辖,不過大家也不要看到“手動(dòng)”兩個(gè)字就害怕,其實(shí)就是調(diào)一個(gè)命令的事。
$ 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
而不是別的呢肚医,其實(shí)就是上一步說的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
就是設(shè)置后端為rocksdb
的配置項(xiàng)。
其他的后端還包括:memory
搁痛、cassandra
、scylladb
谁尸、hbase
、mysql
和palo
。我們這里不用去管它破婆,用默認(rèn)的rocksdb
即可祷舀。
初始化完成之后,會(huì)在當(dāng)前目錄下出現(xiàn)一個(gè)rocksdb-data
的目錄亿鲜,這就是存放后端數(shù)據(jù)的地方,沒事千萬不要隨意刪它或移動(dòng)它。
注意:初始化后端這個(gè)操作只需要在第一次啟動(dòng)服務(wù)前執(zhí)行一次,不要每次起服務(wù)都執(zhí)行撬码。不過即使執(zhí)行了也沒關(guān)系夫否,hugegraph檢測到已經(jīng)初始化過了會(huì)跳過。
啟動(dòng)服務(wù)
終于到了啟動(dòng)服務(wù)了叫胁,同樣也是一條命令
$ bin/start-hugegraph.sh
Starting HugeGraphServer...
Connecting to HugeGraphServer (http://127.0.0.1:8080/graphs)....OK
看到上面的OK
就表示啟動(dòng)成功了凰慈,我們可以jps
看一下進(jìn)程。
$ jps
...
4101 HugeGraphServer
4233 Jps
...
如果還不放心驼鹅,我們可以發(fā)個(gè)HTTP
請求試試看微谓。
$ curl http://127.0.0.1:8080/graphs
{"graphs":["hugegraph"]}
到這里HugeGraphServer
的部署就完成了,接下來我們來部署HugeGraphStudio
输钩。
部署HugeGraphStudio
步驟與部署HugeGraphServer
大體類似豺型,我們就不那么啰嗦了。
記得先返回最上層目錄买乃,避免目錄嵌套在一起了姻氨。
準(zhǔn)備安裝包
克隆代碼庫
$ git clone git@github.com: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
是一個(gè)包含前端的項(xiàng)目,使用react.js
實(shí)現(xiàn)剪验,自行打包的話需要安裝npm
肴焊、webpack
等工具。
$ cd hugegraph-studio
$ mvn package -DskipTests
studio
打包的時(shí)間會(huì)稍長一點(diǎn)功戚。
...
[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] ------------------------------------------------------------------------
將打包好的目錄拷到上一層娶眷,刪除源碼目錄(純個(gè)人喜好)。
$ mv hugegraph-studio-0.7.0 ../
$ cd ..
$ rm -rf hugegraph-studio
至此啸臀,我的最上層目錄就只剩下兩個(gè)安裝包届宠,如下:
$ ls
hugegraph-0.7.4 hugegraph-studio-0.7.0
配置參數(shù)
進(jìn)入hugegraph-studio-0.7.0
目錄,修改唯一的一個(gè)配置文件壳咕。
$ 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()]
需要修改的參數(shù)是graph.server.host=localhost
席揽、graph.server.port=8080
、graph.name=hugegraph
谓厘。它們與HugeGraphServer
的配置文件conf/rest-server.properties
中的配置項(xiàng)對(duì)應(yīng)幌羞,其中:
-
graph.server.host=localhost
與restserver.url=http://127.0.0.1:8080
的host
對(duì)應(yīng); -
graph.server.port=8080
與的restserver.url=http://127.0.0.1:8080
的port
對(duì)應(yīng)竟稳; -
graph.name=hugegraph
與graphs=[hugegraph:conf/hugegraph.properties]
的圖名對(duì)應(yīng)属桦。
因?yàn)槲抑安]有修改HugeGraphServer
的配置文件conf/rest-server.properties
,所以這里也不需要修改HugeGraphStudio
的配置文件conf/hugegraph-studio.properties
他爸。
啟動(dòng)服務(wù)
$ bin/hugegraph-studio.sh
studio
的啟動(dòng)默認(rèn)是不會(huì)放到后臺(tái)的聂宾,所以我們會(huì)在控制臺(tái)上看到一大串日志,在最底下看到如下日志表示啟動(dòng)成功:
信息: 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
系谐,就進(jìn)入了studio
的界面:
圖中Gremlin
下的框,就是我們輸入gremlin
語句進(jìn)而操作hugegraph
的入口了,下面我們給出一個(gè)例子纪他。
創(chuàng)建關(guān)系圖
以下內(nèi)容參考CSDN博客通過Gremlin語言構(gòu)建關(guān)系圖并進(jìn)行圖分析鄙煤。
在輸入框中輸入以下代碼以創(chuàng)建一個(gè)“TinkerPop關(guān)系圖”:
// 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)
點(diǎn)擊右上角的三角按鈕,這樣就創(chuàng)建出了一個(gè)圖茶袒。
圖查詢
在輸入框中輸入:
g.V()
就能查出上面創(chuàng)建的圖的所有頂點(diǎn)和邊梯刚。
至此,執(zhí)行Gremlin的圖形化環(huán)境就已經(jīng)搭建完成薪寓,后續(xù)就可以做各種各樣炫酷的gremlin
查詢了亡资。