solr
SolrDay 7

Solrのドキュメントルーティングのやり方

More than 1 year has passed since last update.

ドキュメントルーティングとは

クライアントからインデックスさせるシャードを指定する機能です。
シャーディングしているインデックスに対してはgroup.ngroups、group.facetが正常に機能しない(間違った値が取れる)という欠点がありますが、ドキュメントルーティングすることで、これらの機能を正常に動かすことができます。

参考資料

下記を参考にしました。
https://lucidworks.com/blog/2013/06/13/solr-cloud-document-routing/

やり方

ドキュメントルーティングをするには、下記の形式でunique keyを書き換えます。

routing key + ! + unique key 

hogehoge!00001

routing keyの文字列を元にしてハッシュ値(murmurhash3の32bit)が生成されます。
各シャードは自分が担当するハッシュの値域が予め設定されており、このハッシュ値が該当するシャードにドキュメントが振り分けられます。
各シャードの担当値域はstate.jsonの中で確認できます。

{"routing":{
    "replicationFactor":"3",
    "router":{"name":"compositeId"},
    "maxShardsPerNode":"1",
    "autoAddReplicas":"false",
    "shards":{
      "shard1":{
        "range":"80000000-d554ffff", //これ

調査用のインデックス

https://github.com/tkondo1223/solr-advent-calender2016/tree/master/routing

各種比較

ドキュメントの偏り

ドキュメントルーティング無し

全シャードにドキュメントが振り分けられています。
シャード1
image

シャード2
image

シャード3
image

ドキュメントルーティング有り

シャード1
image

シャード2
image

シャード3
image

キーと各シャードの担当範囲は下記の通りなので、正しくルーティングされています。

ルーティングキー mmh3 振り分け先 ドキュメント数
key1 9b970125 shard1 6
key2 737139b4 shard3 4
key3 a648eb58 shard1 9
担当範囲
shard1 80000000-d554ffff
shard2 d5550000-2aa9ffff
shard3 2aaa0000-7fffffff

groupingへの影響

group.ngroups

q=*:*&wt=json&start=0&rows=10&group=true&group.field=mmh3&group.ngroups=true

ドキュメントルーティング無し

ngroupsが正しくない

{
  "grouped": {
    "mmh3": {
      "matches": 19,
      "ngroups": 7, //間違い
      "groups": [
        {
          "groupValue": "a648eb58",
          "doclist": {
            "numFound": 9,
            "start": 0,
            "maxScore": 1,
            "docs": [
              {
                "id": "5",
                "mmh3": "a648eb58",
                "_version_": 1553056878448083000
              }
            ]
          }
        },
        {
          "groupValue": "9b970125",
          "doclist": {
            "numFound": 6,
            "start": 0,
            "maxScore": 1,
            "docs": [
              {
                "id": "18",
                "mmh3": "9b970125",
                "_version_": 1553056878470103000
              }
            ]
          }
        },
        {
          "groupValue": "737139b4",
          "doclist": {
            "numFound": 4,
            "start": 0,
            "docs": [
              {
                "id": "1",
                "mmh3": "737139b4",
                "_version_": 1553056878368391200
              }
            ]
          }
        }
      ]
    }
  }
}

ドキュメントルーティング有り

正しい結果が返ってきている

{
  "grouped": {
    "mmh3": {
      "matches": 19,
      "ngroups": 3, //正しい
      "groups": [
        {
          "groupValue": "737139b4",
          "doclist": {
            "numFound": 4,
            "start": 0,
            "docs": [
              {
                "id": "key2!1",
                "mmh3": "737139b4",
                "_version_": 1553055543823696000
              }
            ]
          }
        },
        {
          "groupValue": "9b970125",
          "doclist": {
            "numFound": 6,
            "start": 0,
            "docs": [
              {
                "id": "key1!2",
                "mmh3": "9b970125",
                "_version_": 1553055543823696000
              }
            ]
          }
        },
        {
          "groupValue": "a648eb58",
          "doclist": {
            "numFound": 9,
            "start": 0,
            "docs": [
              {
                "id": "key3!3",
                "mmh3": "a648eb58",
                "_version_": 1553055543826841600
              }
            ]
          }
        }
      ]
    }
  }
}

group.facet

q=*:*&wt=json&start=0&rows=10&group=true&group.field=mmh3&group.ngroups=true&group.facet=true&facet.field=mmh3&facet=true

mmh3単位での集計のため、全て1が正しい

ドキュメントルーティング無し

    "facet_fields": {
      "mmh3": [
        "9b970125",
        3,
        "a648eb58",
        3,
        "737139b4",
        1
      ]
    },

ドキュメントルーティング有り

    "facet_fields": {
      "mmh3": [
        "737139b4",
        1,
        "9b970125",
        1,
        "a648eb58",
        1
      ]
    }

デメリット

ドキュメントルーティングを使い振り分けをすればngourpsなどの機能が正常に処理できますが、デメリットも存在します。
1つ目はハッシュ値(ユーザーから確認できない)で振り分けがされるのですが、キーがどのハッシュ値になるかSolrからは確認できないので、事前にソースコードを書いてどのキーでどのシャードに振り分けられるか確認しておかないといけません。
2つ目はキー名の自由度が無いことです。
キー名をgroup[1-3]みたいなものにして、それぞれ対応するナンバリングのshardに振り分けたいと考えていても、group1とgroup3のハッシュがshard1の担当範囲に入るとキー名を変える必要があります。
3つ目はこの仕様をシステム担当者がずっと引き継いでいかないといけないことです。
時が経って、仕様も忘れ去られた時に新しいグループの追加が発生すると大変なことになるかもしれません。

まとめ

ドキュメントルーティング自体はクセがあって少し使いにくい機能だなと感じましたが、ドキュメント数が多くなるとインデキシングのパフォーマンス向上やインデックスをメモリに乗せきるために、シャーディングは必須なため、上手くこの仕様と付き合っていきたいところです。