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

  • 0
    Like
  • 2
    Comment

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

    クライアントからインデックスさせるシャードを指定する機能です。
    シャーディングしているインデックスに対しては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つ目はこの仕様をシステム担当者がずっと引き継いでいかないといけないことです。
    時が経って、仕様も忘れ去られた時に新しいグループの追加が発生すると大変なことになるかもしれません。

    まとめ

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