Neo4j 4.3 Introduced

Neo4j 4.3 が June 2021 にリリースされました。この Webinar で、4.3 で改善された点や新機能を、Neo4j の Director of Product Management である Ivan Zoratti が説明しています。

本記事では、Webinar 動画をベースに、4.3 における主な変更点を紹介していきます。

Neo4j 4.x

Neo4j 4.3 について説明する前に、そもそも Neo4j 4.x における目玉機能は何だったのかを振り返ってみましょう。

第一に、Multi-databases のサポートです。デフォルトでは 100 までのデータベース (dbms.max_databases = 100)を作成することができます。これによって、マルチテナント型のサービスを提供しやすくなったり、複数のテスト・開発環境を準備しやすくなったり、スケーラビリティの選択肢が増すことによって柔軟な運用が可能となりました。

第二に、Role-Based Access Control (RBAC) の手法を用いた Schema-based Security の機能です。具体的には、GRANT/DENYREVOKE といったコマンドによって、ユーザーごとに粒度の高いアクセス権限を管理できるようになりました。本番運用するアプリケーション、特に機密性の高いデータを扱う場合や、運用事故を防ぐために必須の機能です。

第三に、Fabric です。複数データベースに対して並列にクエリ実行をさせる手法ですが、ユーザーからは Fabric virtual database と呼ばれる論理的なインターフェースを通して隠蔽化されています。これによって、スケーラビリティが大きく向上しました。

第四に、Reactive drivers です。Neo4j のクライアント側とデータベース側の間で、データのやり取りを柔軟にコントローできるようになりました。具体的には、同期・非同期リクエストの選択、イベントドリブンなクエリ結果の受け取りなどです。例えば、ページネーションや長いクエリのバッチ化などのユースケースに適しています。

Neo4j 4.3

それでは、Neo4j 4.3 の主な変更点を見ていきましょう。

Relationship type/property indexes

第一に、リレーションに対してインデックスを貼れるようになりました。以前から INDEX クエリを利用してノードに対してインデックスは貼れましたが、リレーションに対しては不可能でした。この機能追加によって、リレーションを利用した複雑なクエリのチューニングをすることができます。

もちろんインデックスの作成はフリーミールではないので、本当にパフォーマンスチューニングが必要な箇所だけに作成するようにしましょう。

Dense node locking

第二に、新しいロックアルゴリズムを利用することで、Super nodes のような大量のリレーションが存在する密なグラフネットワーク (= Dense nodes) に対しても、効率的にロックを利用できるようになりました。

こちらのブログ に簡単な内部実装について紹介されています。そもそもノード間のリレーションは内部的にどのように表現されているかというと、実は全てのリレーションが一対一で紐付いているわけではありません(もちろんユーザーからはそのように見えています)。

IN/OUT/LOOP の三方向それぞれについて Relationship Chain と呼ばれる集合体で管理され、それらが Relationship Group と呼ばれる連結リストに紐付いて保存されています。リレーションの向き別に、一段階抽象レイヤーを挟んでいます。

Neo4j 4.3 からは、このチェーン構造と見立てた Relationship Chain ごとにロックの排他制御を行うようにすることで、Dense nodes に対しても効率的にロックを管理できるようになったということのようです。

For each relationship group there are up to three sets of records ... these chains consist of “nodes’’ that connect relationships in a chain. Neo4j can now obtain and release locks on these “nodes” when it needs to update a relationship or node in the graph.

Server-side routing

Neo4j 4.1 で Server-side routing (SSR) が導入されました。Neo4j 4.3 では、その機能がより大きく改善され、クラウド上の Private/Public ネットワークや、Kubernetes クラスター、また他のコンテナオーケストレーション上の様々なユースケースに対応できるようになりました。

具体的には、複数のマシンを稼働させているクラスター上で、サーバー側のリソースを考慮してクエリをルーティングさせたり、管理者コマンドはリーダーにルーティングさせたり、Client-side routing が利用できないネットワーク構成でもサーバーサイドでルーティングさせることによって負荷を分散させたり、といった用途に使えます。

Replica-only clusters

レプリカ専用のクラスターの作成も可能になりました。

書き込みの発生しない用途、例えば分析用や社内のステージング環境に、レプリカ専用のクラスターを作れることには大きな意義が有ります。

例えば、書き込みを必須とするユーザーフェイシングなクラスターと、負荷の高い分析クエリを投げたい分析用のクラスターを分離することで、分析クエリが本番ユーザーの何らかのユーザー体験に悪影響を与えないような分離性を実現することができます。

読み込み負荷の高いユースケースに対してスケールさせる選択肢が増えたことは、様々な要件を満たすという点に置いて価値が高いでしょう。

Leader Election も発生しないので、レプリカ専用のクラスターの運用負荷はリーダーが存在するクラスターよりもずっと楽になるでしょう。

最後に

以上、Neo4j 4.3 で導入された新機能やパフォーマンス改善について紹介しました。

リレーションに対するインデックス機能や、Super nodes に対するロックを必要とする書き込みのパフォーマンス改善など、本番環境にある大規模なデータセットに対しての利用ケースが広がるような差分でした。

より詳しく知りたい方は、こちらのブログ記事やドキュメントもぜひ確認してみてください。

2021-10-03