JanusGraph:圖數據庫系統簡介
圖(graph)是《數據結構》課中第一次接觸到的一個概念,它是一種用來描述現實世界中個體和個體之間網絡關系的數據結構。
為了在計算機中存儲圖,《數據結構》中初步介紹了圖的邏輯結構和存儲結構。本文對圖的定義、圖的作用、圖的邏輯結構、圖的存儲結構進行了回顧,繼而引出了圖數據庫、主流的圖數據庫產品,最后重點介紹了JanusGraph圖數據庫的基本知識。
本文提綱:
1、圖的簡介
2、圖數據庫的概念
3、JanusGraph的簡介
1、圖的簡介
============
參考《數據結構》,說明圖的基本概念,舉兩個圖的例子,圖的存儲方法。
圖型結構中,節點間的關系可以是任意的,圖中任意兩個數據元素之間都可能相關。
2、圖數據庫的概念
==================
介紹清楚圖數據庫的基本概念,和目前主流的圖數據庫的簡介
圖數據庫源起歐拉和圖理論,也可稱為面向/基於圖的數據庫,對應的英文是Graph Database。圖數據庫的基本含義是以“圖”這種數據結構存儲和查詢數據,而不是存儲圖片的數據庫。它的數據模型主要是以節點和關系(邊)來體現,也可處理鍵值對。它的優點是快速解決復雜的關系問題。
圖將實體表現為節點,實體與其他實體連接的方式表現為聯系。我們可以用這個通用的、富有表現力的結構來建模各種場景,從宇宙火箭的建造到道路系統,從食物的供應鏈及原產地追蹤到人們的病歷,甚至更多其他的場景。
圖形數據庫是NoSQL數據庫的一種類型,它應用圖形理論存儲實體之間的關系信息。最常見的例子,就是社會網絡中人與人之間的關系。關系型數據庫用於存儲關系型數據的效果並不好,其查詢復雜、緩慢、超出預期,而圖形數據庫的獨特設計恰恰彌補了這個缺陷。 Google的圖形計算系統名為Pregel。
目前主流的圖數據庫有:Neo4j,FlockDB,GraphDB,InfiniteGraph,Titan,JanusGraph,Pregel等。
圖計算引擎多種多樣。最出名的是有內存的、單機的圖計算引擎Cassovary和分布式的圖計算引擎Pegasus和Giraph。大部分分布式圖計算引擎基於Google發布的Pregel白皮書,其中講述了Google如何使用圖計算引擎來計算網頁排名。
3、JanusGraph簡介
=================
3.1 JanusGraph簡介
----------------------------
JanusGraph是一個可擴展的圖數據庫,可以把包含數千億個頂點和邊的圖存儲在多機集群上。它支持事務,支持數千用戶實時、並發訪問存儲在其中的圖。(JanusGraph is a scalable graph database optimized for storing and querying graphs containing hundreds of billions of vertices and edges distributed across a multi-machine cluster. JanusGraph is a transactional database that can support thousands of concurrent users executing complex graph traversals in real time.)
我們可以將圖數據庫系統的應用領域划分成以下兩部分:
- 用於聯機事務圖的持久化技術(通常直接實時地從應用程序中訪問)。這類技術被稱為圖數據庫,它們和“通常的”關系型數據庫世界中的聯機事務處理(Online Transactional Processing,OLTP)數據庫是一樣的。
- 用於離線圖分析的技術(通常都是按照一系列步驟執行)。這類技術被稱為圖計算引擎。它們可以和其他大數據分析技術看做一類,如數據挖掘和聯機分析處理(Online Analytical Processing,OLAP)。
3.2 JanusGraph的發展歷史
-------------------------------------
JanusGraph是2016年12月27日從Titan fork出來的一個分支,之后TiTan的開發團隊在2017年陸續發了0.1.0rc1、0.1.0rc2、0.1.1、0.2.0等四個版本,最新的版本是2017年10月12日。
titan是從2012年開始開發,到2016年停止維護的一個分布式圖數據庫。最初在2012年啟動titan項目的公司是Aurelius,2015年此公司被 DataStax(DataStax是開發apache Cassandra 的公司)收購,DataStax公司吸收了TiTan的圖存儲能力,形成了自己的商業產品DataStax Enterprise Graph。
TiTan開發者們希望把TitTan放到Apache Software Foundation下,不過,DataStax不願意這樣做(可能考慮到要保護自己的商業產品DataStax Enterprise Graph的技術優勢吧,其實這點優勢是從Titan來的),而且自從2015年9月DataStax收購了Titan的母公司后,TiTan一直處於停滯狀態(應該是DataStax收購之后,忙於推出自己的商業產品DataStax Enterprise Graph,忙於整合Titan進自己的商業產品吧,可是Titan本身沒有得到發展)。鑒於此,2016年6月,TiTan的開發者們fork了一個TiTan的分支(因為Titan已經屬於DataStax了,所以他們必須另外弄一個商標),重命名為JanusGraph,並將其置於Linux Software Foundation下。
2017年4月6日發布了第一個版本0.1.0-rc1,目前最新版本是2017年10月12日發布的0.2.0版。
JanusGraph項目啟動的初衷是“通過為其增加新功能、改善性能和擴展性、增加后端存儲系統來增強分布式圖系統的功能,從而振興分布式圖系統的開發”,JanusGraph從Apahce TinkerPop中吸收了對屬性圖模型(Property Graph Model)的支持和對屬性圖模型進行遍歷的Gremlin遍歷語言。(“reinvigorate development of the distributed graph system to add new functionality, improve performance and scalability, and maintain a variety of storage backends,JanusGraph incorporates support for the property graph model with the open source graph computing framework Apache TinkerPop and its Gremlin graph traversal language”.)
3.2 JanusGraph的功能(Benefits)
------------------------------------------------
JanusGraph最大的一個好處就是:可以擴展圖數據的處理,能支持實時圖遍歷和分析查詢(Scaling graph data processing for real time traversals and analytical queries is JanusGraph’s foundational benefit.)。
因為JanusGraph是分布式的,可以自由的擴展集群節點的,因此,它可以利用很大的集群,也就可以存儲很大的包含數千億個節點和邊的圖。由於它又支持實時、數千用戶並發遍歷圖和分析查詢圖的功能。所以這兩個特點是它顯著的優勢。
它支持以下功能:
(1)分布式部署,因此,支持集群。
(2)可以存儲大圖,比如包含數千億Vertices和edges的圖。
(3)支持數千用戶實時、並發訪問。(並發訪問肯定是實時的,這個唉,沒必要強調好像)
(4)集群節點可以線性擴展,以支持更大的圖和更多的並發訪問用戶。(Elastic and linear scalability for a growing data and user base)
(5)數據分布式存儲,並且每一份數據都有多個副本,因此,有更好的計算性能和容錯性。(Data distribution and replication for performance and fault tolerance)
(6)支持在多個數據中心做高可用,支持熱備份。(Elastic and linear scalability for a growing data and user base)
(7)支持各種后端存儲系統,目前標准支持以下四種,當然也可以增加第三方的存儲系統:
-
- Apache Cassandra®
- Apache HBase®
- Google Cloud Bigtable
- Oracle BerkeleyDB
(8)通過集成大數據平台,比如Apache Spark、Apache Giraph、Apache Hadoop等,支持全局圖數據分析、報表、ETL
(9)支持geo(Gene Expression Omnibus,基因數據分析)、numeric range(這個的含義不清楚)
(10) 集成ElasticSearch、Apache Solr、Apache Lucene等系統后,可以支持全文搜索。
(11) 原生集成Apache TinkerPop圖技術棧,包括Gremlin graph query language、Gremlin graph server、Gremin applications。
(12) 開源,基於Apache 2 Licence。
(13) 通過使用以下系統可以可視化存儲在JanusGraph中的圖數據:
-
- Cytoscape
- Gephi plugin for Apache TinkerPop
- Graphexp
- KeyLines by Cambridge Intelligence
- Linkurious
3.3. JanusGraph的體系結構(architecture,架構)
-------------------------------------------------------------------
JanusGraph是模塊化的體系結構(JanusGraph has a modular architecture)。
它使用hadoop來做圖的分析和圖的批處理,使用模塊化接口來做數據持久化、索引和客戶端訪問。
在JanusGraph和磁盤之間有多個后端存儲系統和多個索引系統。(Between JanusGraph and the disks sits one or more storage and indexing adapters.)
它支持的外部存儲系統,目前標准支持的有(當然也可以將第三方的存儲系統作為JanusGraph的后端存儲系統):
-
- Apache Cassandra
- Apache HBase
- Oracle Berkeley DB Java Edition
- Google Cloud BigTable
支持的外部索引系統:
-
- Elasticsearch
- Apache Solr
- Apache Lucene
體系結構圖:

3.4 應用使用JanusGraph的方法
---------------------------------------------
作為一個數據庫系統,它是要用來為應用程序存儲數據用的,那么應用程序應該如何使用JanusGraph來為自己存儲數據呢?
一般來說,應用程序可以通過兩種不同的方式來使用JanusGraph:
(1)第一種方式:可以把JanusGraph嵌入到應用程序中去,JanusGraph和應用程序處在同一個JVM中。應用程序中的客戶代碼(相對JanusGraph來說是客戶)直接調用Gremlin去查詢JanusGraph中存儲的圖,這種情況下外部存儲系統可以是本地的,也可以處在遠程。
(2)第二種方式:應用程序和Janus Graph處在兩個不同JVM中,應用通過給JanusGraph提交Gremlin查詢給GremlinServer,來使用JanusGraph,因為JanusGraph原生是支持Gremlin Server的。(Gremlin Server是Apache Tinkerpop中的一個組件)。
3.5 JanusGraph的配置文件
----------------------------------------
JanusGraph集群包含一個、或者多個JanusGraph實例。每次啟動一個JanusGraph實例的時候,都必須指定JanusGraph的配置。在配置中,可以指定JanusGraph要用的組件,可以控制JanusGraph運行的各個方面,還可以指定一些JanusGraph集群的調優選項。
最小的JanusGraph配置只需要指定一下JanusGraph的后端存儲系統,也就是它的持久化引擎。
如果要JanusGraph支持高級的圖查詢,就需要為JanusGraph指定一個索引后端。
若果要提升JanusGraph的查詢性能,就必須為JanusGraph指定緩存,指定性能調優的選項。
以上提到的后端存儲系統、索引后端、緩存、調優選項等都可以在JanusGraph的配置文件中進行指定。默認情況下它的配置文件存放在JanusGraph_home/conf目錄下。
在JanusGraph_home/conf目錄下有一些JanusGraph的示例配置文件。
下面是一個JanusGraph的示例配置文件的內容,這個文件中為JanusGraph指定了cassandra作為后端存儲引擎,並且指定了elasticsearch作為索引后端。
storage.backend=cassandra storage.hostname=localhost index.search.backend=elasticsearch index.search.hostname=100.100.101.1, 100.100.101.2 index.search.elasticsearch.client-only=true
3.6 JanusGraph配置文件的加載方法
----------------------------------------------------
JanusGraph的配置文件如何加載呢?
(1)對於單獨安裝的JanusGraph,可以在Gremlin中使用JanusGraphFactory類的方法來加載配置文件
graph = JanusGraphFactory.open('path/to/configuration.properties')
(2)對於嵌入到應用中的JanusGraph來說,應用可以直接調用JanusGraph的公共API,只要在應用中調用JanusGraph的JanusGraphFactory就可以加載配置文件了
(3)還可以在JanusGraphFactory中使用簡寫來加載配置。
graph = JanusGraphFactory.open('cassandra:localhost');
graph = JanusGraphFactory.open('berkeleyje:/tmp/graph');
3.7 JanusGraph分布式集群的安裝方法
------------------------------------------------------
JanusGraph作為一個圖數據庫系統,其實還是比較復雜的,它的安裝可以是很簡單的單機安裝,也可以是很復雜的分布式安裝,最不可理解的是官網(janusgraph.org)上沒有專門介紹安裝的文檔。這里的安裝方法是從IBM Developer works搜索來的,下面着重介紹單機安裝,分布式集群的安裝較為復雜,目前還沒有時間做,以后在做吧,任務在即。
從JanusGraph的架構圖可以看出,Janus的安裝需要以下組件:

(1)外部存儲系統,上圖左下的橙色方框,JP也集成了一個Cassandra,可以用於單一數據庫使用
(2)外部索引系統,上圖右下的橙色方框,JP本身集成了一個ES,這個是可選的。
(3)啟動JanusGraph Server,上圖中部的橙色方框,它是從Apache Tinkpop項目中的Gremlin Server來的。
(4)啟動Gremlin客戶端去連接JanusGraph Server,上圖中部橙色方框中的小框Tinkpop API-Gremlin指的是Gremlin console這個客戶端是調用了Tinkpop API去訪問JanusGraph Server的。
由以上的架構分析可以看出,安裝JP的過程中最少要安裝一個外部存儲系統。這里按照以下順序安裝:
1、安裝后端存儲系統。這里下載了Cassandra,同時啟動Cassandra和thrift。
$cassandra_home/bin/cassandra
$cassandra_home/bin/nodetool enablethrift #開啟thrift,或者也可以在啟動cassandra之前,在conf/cassandra.yaml中修改start_rpc選項的值為true,那么啟動cassandra同時就啟動了thrift了,不需要單獨啟動thrift
2、安裝JanusGraph。它的安裝很簡單,就是解壓即可。
$janusgraph_home/bin/gremlin-server.sh #啟動JanusGraph Server
$janusgraph_home/bin/gremlin.sh #啟動gremlin console
3、在gremlin console中輸入gremlin query language,新建圖數據庫,在其中存入vertexs,edges、vertex labels、edge labels、property key等元素,來存入圖的組成元素。
3.8 JanusGraph的命令接口使用方法
-------------------------------------------
如下的命令會創建一個圖,如下所示:
它有3個頂點,2個邊
3 vertex:
v1: label student property id: 1
v2: no label, no property
v3: label studentproperty id: 2
2 edges with label friends

graph = JanusGraphFactory.open('conf/janusgraph-cassandra.properties');
mgmt = graph.openManagement();
student = mgmt.makeVertexLabel('student').make();
friends = mgmt.makeEdgeLabel('friends').make();
mgmt.commit();
v1 = graph.addVertex(label, 'student');
v1.property('id', '1');
v2 = graph.addVertex();
v3 = graph.addVertex(label, 'student');
v3.property('id', '2');
graph.tx().commit();
v1.addEdge('friends', v2);
v1.addEdge('friends', v3);
graph.tx().commit();
graph.traversal().V();
graph.traversal().V().values('id');
graph.traversal().E();
3.9 用Java訪問JanusGraph中的圖
-------------------------------------------------
如下為項目結構:

pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.cnic</groupId>
<artifactId>Connect2JanusGraph</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Connect2JanusGraph</name>
<description>a project to connect JanusGraph using java code</description>
<dependencies>
<dependency>
<groupId>org.janusgraph</groupId>
<artifactId>janusgraph-core</artifactId>
<version>0.1.1</version>
</dependency>
<dependency>
<groupId>org.janusgraph</groupId>
<artifactId>janusgraph-cassandra</artifactId>
<version>0.2.0</version>
</dependency>
</dependencies>
</project>
VisitJanusGraph.java源代碼:
import org.janusgraph.core.JanusGraph;
import org.janusgraph.core.JanusGraphFactory;
import org.janusgraph.core.JanusGraphTransaction;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.structure.Vertex;
public class VisitJanusGraph {
public static void main(String[] args)
{
createVertexAndEdge();
}
public static void createVertexAndEdge()
{
//First configure the graph
JanusGraphFactory.Builder builder = JanusGraphFactory.build();
builder.set("storage.backend", "cassandrathrift");
builder.set("storage.hostname", "192.168.192.128");
builder.set("storage.port", "9160");
//ip address where cassandra is installed
//builder.set("storage.username", “cassandra”);
//buder.set("storage.password", “cassandra”);
//builder.set("storage.cassandra.keyspace", "testing");
//open a graph database
JanusGraph graph = builder.open();
//Open a transaction
JanusGraphTransaction tx = graph.newTransaction();
//Create a vertex v1 with label student, add property to the vertex
Vertex v1 = tx.addVertex(T.label, "student");
v1.property("id", 1);
//create a vertex v2 without label and property
Vertex v2 = tx.addVertex();
//create a vertex v3 with label student, then add property to the vertex
Vertex v3 = tx.addVertex(T.label, "student");
v3.property("id", 2);
tx.commit();
//Create edge between 2 vertices
Edge edge12 = v1.addEdge("friends", v2);
Edge edge13 = v1.addEdge("friends", v3);
//Finally commit the transaction
tx.commit();
System.out.println(graph.traversal().V());
System.out.println(graph.traversal().E());
}
}
以上的源代碼創建了如下的圖:

至此,使用JanusGraph提供的JavaAPI訪問JG的Java程序就算是介紹完了。
進一步,探索JanusGraph作為一個gdbms的其他功能,需要認真閱讀它的官方文檔,配置、集群、HA、Failure and Failover等內容。
再深入想要對JanusGraph的源代碼進行閱讀,並為它貢獻代碼,得認真的閱讀JanusGraph Development Process(https://docs.janusgraph.org/latest/development-process.html)的內容。
參考資料:
1、嚴蔚敏,《數據結構》
2、百度百科-圖形數據庫,https://baike.baidu.com/item/圖形數據庫/5199451?fr=aladdin
3、JanusGraph picks up where TitanDB left off,https://www.datanami.com/2017/01/13/janusgraph-picks-titandb-left-off/
4、JanusGraph官方網站,http://janusgraph.org/
5、Janus集群搭建,http://www.itboth.com/d/YVvEja6jueA3/janusgraph-cassandra
6、JanusGraph with Cassandra,https://www.bluepiit.com/blog/janusgraph-with-cassandra/
7、圖數據庫——大數據時代的高鐵,https://blog.csdn.net/heyc861221/article/details/80128421
8、Getting started with JanusGraph, Part 1 – Deployment,https://developer.ibm.com/dwblog/2018/whats-janus-graph-learning-deployment/
9、Part VII. JanusGraph Development Process,https://docs.janusgraph.org/latest/development-process.html
