開發與維運

GDB Cypher:Cypher用戶的最佳選擇

Neo4J 是DB-Engines圖數據領域長期排名第一的數據庫產品,目前有社區版和企業版兩個版本:

• 社區版:單實例、無容災、不支持熱備、缺乏技術支撐
• 企業版:高性能、可擴展、高可用、多種安全級別、數據完整性、完全託管、豐富的監控&審計

企業版目前最便宜的4Core單實例一年價格將近30萬,高昂的價格讓國內中小企業望而卻步。目前國內大部分用戶都選擇社區版並在上面做定製開發,這需要企業投入額外人力成本進行圖數據自管理和運營。下面是Neo4j企業版和Gdb雲產品不同規格的價格對比:
1.png

兼容性

既然想要接入Gdb,那麼Gdb目前Cypher支持到什麼程度了?是否可以滿足業務的使用需求?
目前Gdb Cypher只支持bolt-v3協議;數據類型上目前支持Temporal外所有的數據類型,子句上基本支持所有常用的子句,函數上除過一些算數方法外基本也支持所有常用的函數,Procedure目前只支持少量的場景;Gdb相比Neo4j 4.0的差異主要提現在多圖、索引、導入導出、可視化等方面;Sessions目前支持常見的同步異步兩種模式。

數據類型

2.png

子句/函數

3.png

Neo4j差異性

4.png

接入方式

業務覺得目前支持的Cypher場景已經足夠接入,那麼想接入Gdb,該怎麼接入呢?

數據導入

假定數據可以在Neo4j社區版中,首先利用apoc導出為graphml格式,其次利用GraphML2CSV轉為CSV格式,然後將CSV文件上傳到OSS中,最後通過Gdb命令將OSS文件導入到Gdb中。
5.png

存量數據已經導入到Gdb中了,怎麼插入新的數據?怎麼查詢存儲數據?這裡就需要通過客戶端Driver來接入了。
官方4.0版本目前提供包括 Java, .Net, JavaScript三種接入形式,另外Go, Python正在開發中。 Gdb目前主要支持Java、 .Net兩個版本。以Java Driver為例,目前按業務需求可以支持兩種接入形態:

Java Driver

• 依賴

<dependency>
    <groupId>org.neo4j.driver</groupId>
    <artifactId>neo4j-java-driver</artifactId>
    <version>4.0.0</version>
</dependency>

• 初始化

public Demo() {
    String uri = "bolt://server-domain:server-port";
    String username = "your-gdb-username";
    String password = "your-gdb-password"
    Logging logging = new ConsoleLogging(FINE);
    Config config = Config.builder()
        .withLogging(logging)
        .withMaxConnectionLifetime(30, TimeUnit.MINUTES)
        .withMaxConnectionPoolSize(50)
        .withConnectionAcquisitionTimeout(2, TimeUnit.MINUTES)
        .build();
    private  Driver driver = GraphDatabase.driver(uri, 
         AuthTokens.basic(username, password), config);
}

• Simple Sessions

public void simpleSessions(final String dsl, final Map<String, Object> args) {
    try (Session session = driver.session()) {
        ///1. Transaction functions
        session.writeTransaction(tx -> {
            StringBuilder buffer = new StringBuilder();
            Result result = tx.run(dsl, args);
            result.stream().forEach(t -> 
                System.out.println(output(t)));
            return buffer.toString();
        });
        ///2. Auto-commit Transactions tested
        {
            Result result = session.run(dsl, args);
            result.stream().forEach(t -> 
                System.out.println(output(t)));
        }
    }
}

• Async Sessions

public void asyncSample(final String dsl, final Map<String, Object> args) {
    AsyncSession session = driver.asyncSession();
    ///1.  Transaction functions
    session.readTransactionAsync(tx ->
        tx.runAsync(dsl, args)
            .thenCompose(cursor -> cursor.forEachAsync(record ->
                System.out.println("asyncTransactionFuctions - " + record.get(0))))
    );
    ///2. Auto-commit Transactions tested
    session.runAsync(dsl, args)
        .thenCompose(cursor -> cursor.forEachAsync(record ->
            System.out.println("asyncAutoTransactions - " + record.get(0))));
}
Spring Data Neo4j
• 依賴
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>

• 配置環境
修改src/main/resources/application.properties文件,配置域名、用戶名、密碼

• 測試
這裡提供了一個Movie-Actor的Sample可以作為學習教程
恭喜您!到了這裡,您已經可以順利將Cypher數據導入Gdb,並根據業務具體場景進行簡單的添加、查詢、更新、刪除了。可能使用中會碰到一些小的困惑,下面的Tips或許可以提供一些幫助:

最佳實踐

• 參數化
用戶請求基本上一般只有幾種場景,參數化把每種類型的翻譯結果進行緩存,從而加速語句的執行時解析,比如

• Parameters:
{
  "name" : "Michael"
}

• Query:

MATCH (n:Person)
WHERE n.name STARTS WITH $name
RETURN n.name

• 設置線程池的大小
在初始化Neo4j的Driver時,需要配置MaxConnectionPoolSize、ConnectionTimeout、MaxConnectionLifetime等參數,這樣能充分利用線程池、並且控制連接的生命週期,更多的配置參考這裡

• 刪除時限制大小
由於Gdb對事務Buffer的大小限制為64M,如果一次刪除的數據量過大可能導致事務無法成功,建議通過LIMIT限制數據集

MATCH (n) LIMIT 1024 DETACH DELETE n;

• 關於Bolt協議
目前Neo4j 4.0最新的Bolt協議為V4,Gdb Server目前提供的最低版本為Bolt V3,建議Java driver使用版本為:4.0.0或者2.0.0-alpha01。

參考

1. Neo4j企業版能力
2. Neo4j企業版價格
3, Neo4j Cypher Manual 4.0
4. Neo4j Driver列表

Leave a Reply

Your email address will not be published. Required fields are marked *