Neo4j Bolt Protocol - Routing Table

本記事では、Bolt Protocol においてどのデータベースインスタンスに接続するかのルーティングを実現するために利用される、Routing Table について紹介します。

Routing Table

Routing Table とは、クラスター構成を組んでいる Neo4j クラスターに対して、適切なデータベースインスタンスに接続するために必要な情報です。

具体的には、サーバーの IP アドレスとポートのリストと、サーバーの役割(WRITE データベースなのか READ データベースなのか)の HashMap です。

例えば、以下の Routing Table を見てみましょう。

address role
x.example.com:7687 ROUTE
x.example.com:7687 WRITE
y.example.com:7687 ROUTE
y.example.com:7687 READ
z.example.com:7687 ROUTE
z.example.com:7687 READ

x.example.com, y.example.com, z.example.com でアクセスできる三つの異なるデータベースインスタンスが稼働していることがわかります。また、x.example.com が、書き込みリクエストを受け付けるリーダーであることがわかります。

Get Routing Recommendations

dbms.routing.getRoutingTable(routingContext, databaseName) プロシージャを利用すると、Routing Table の情報を取得することができます。

例えば、以下の Cypher クエリを Neo4j Aura で稼働しているクラスターに対して実行してみてください。

CALL dbms.routing.getRoutingTable({}, "neo4j")

以下のようなリストが返却されることでしょう。ここでは、三つの異なるデータベースインスタンスが稼働しており、その内 neo20:7687 が書き込みリクエストを受け付けるリーダーであることが確認できます。

{
    "ttl": 300,
    "servers": [
        {
            "addresses": ["neo20:7687"],
            "role": "WRITE"
        },
        {
            "addresses": ["neo21:7687", "neo22:7687", "neo34:7687", "neo28:7687", "neo31:7687"],
            "role": "READ"
        },
        {
            "addresses": ["neo20:7687", "neo21:7687", "neo22:7687"],
            "role": "ROUTE"
        }
    ]
}

ROUTE Request Message

Bolt Protocol v4.3 より加わった新しい Request Message に、ROUTE タイプがあります。

ROUTE リクエストタイプは、現在接続しているデータベースに対して、Routing Table を返却するよう依頼します。

メッセージのフィールドとしては、以下の三つが存在します。

routing::Dictionary,
bookmarks::List<String>,
db:String

データベースインスタンスのアドレスを含むルーティング情報は routing フィールドに格納されます。

そのほかのメタ情報として、ブックマーク(トランザクションごとのグループを表現する論理的概念)情報は bookmark に、データベース名は db に格納されます。

例えば、以下の ROUTE リクエストメッセージは、x.example.com:9001 経由で neo4j データベースに接続できることを示しています。

ROUTE {"address": "x.example.com:9001"} ["neo4j-bookmark-transaction:1", "neo4j-bookmark-transaction:2"] "neo4j"

最後に

以上、Bolt Protocol における Routing Table について紹介しました。

2021-11-08