2017-11-02 13 views
5

Elasticsearchインデックスの中に重複した文書がいくつか見つかりましたが、原因を解決できませんでした。影響を受ける各文書のコピーが2つあり、それらはまったく同じ_id,_typeおよび_uidフィールドを持っています。同一の_uidを持つElasticsearchインデックスの文書が重複しています

/index-name/document-type/document-idにGETリクエストは、ただ一つのコピーを返しますが、このようなクエリでドキュメントを検索すると、非常に驚​​くべきことである二つの結果、返されます。また、重複した文書を特定する_uidフィールドに集約

POST /index-name/document-type/_search 
{ 
    "filter": { 
    "term": { 
     "_id": "document-id" 
    } 
    } 
} 

を:

POST /index-name/_search 
{ 
    "size": 0, 
    "aggs": { 
    "duplicates": { 
     "terms": { 
     "field": "_uid", 
     "min_doc_count": 2 
     } 
    } 
    } 
} 

重複はすべて異なるシャードにあります。たとえば、文書はプライマリシャード0に1つのコピーを持ち、プライマリシャード1に1つのコピーを持つことができます。これは、前述の集計クエリをpreference parameterを使用して順番に実行することで検証しました。シャード

私たちの最高の推測では、何かがルーティングに間違っているということですが、コピーがどのように異なるシャードにルーティングされているのかわかりません。 routing documentationによれば、デフォルトルーティングはドキュメントIDに基づいており、ドキュメントを同じシャードに一貫してルーティングする必要があります。

デフォルトルーティングを上書きするカスタムルーティングパラメータは使用していません。重複したドキュメントに_routingフィールドがないことを確認して、これを再確認しました。

ルーティングにも影響する親子関係は定義しません。 (たとえば、問題と同じ症状のあるthis question in the Elasticsearch forumを参照してください。ドキュメントの親を設定していないため、原因は同じではないと思います)。

重複するドキュメントを押しつぶした新しいインデックスにインデックスを再作成することで、問題を直すことができました。私たちはまだデバッグのために古いインデックスを持っています。

問題を再現する方法が見つかりませんでした。新しい索引は文書を正しく索引付けしており、文書を更新しても重複したものを作成していない夜間処理ジョブを再実行しようとしました。

クラスタにはノードが3つ、プライマリシャードが3つ、レプリカが1つ(つまり、3つのレプリカシャード)があります。 minimum_master_nodesは2に設定されているため、split-brainの問題は発生しません。私たちはElasticsearch 2.4を実行しています(私たちは古いと知っています - すぐにアップグレードを予定しています)。

これらの重複の原因は何ですか?デバッグ方法の提案はありますか?

答えて

3

回答が見つかりました。問題は、索引が予期せずルーティングのために使用したハッシング・アルゴリズムを切り替えてしまい、更新された文書の一部が別の断片に元のバージョンで格納されてしまったことです。

/index-name/_settingsにGET要求は、この明らかにした:

"version": { 
    "created": "1070599", 
    "upgraded": "2040699" 
}, 
"legacy": { 
    "routing": { 
    "use_type": "false", 
    "hash": { 
     "type": "org.elasticsearch.cluster.routing.DjbHashFunction" 
    } 
    } 
} 

を "1070599" は1.7をElasticsearchを指し、そして "2040699" は、ES 2.4です。

インデックスが1.7から2にアップグレードしようとしたようです。4、それは既に実行されていたにもかかわらず、2.4。これは、ここで説明する問題である:https://github.com/elastic/elasticsearch/issues/18459#issuecomment-220313383

私たちは、この変更をトリガーするために何が起こったのかだと思う:

  1. 戻る我々はES 1.7から2.4へのインデックスをアップグレードするとき、我々はElasticsearchインをアップグレードしないことを決定しましたそれは停止時間の原因になるからです。代わりに、別々のES 2.4クラスタを作成しました。

    すべてのインデックス設定とデータ(versionの設定はyou should not set in ES 2.4を含む)をコピーしたツールを使用して、新しいクラスタにデータをロードしました。

  2. 最近の問題に対処しているうちに、インデックスを閉じて再度開いてしまいました。これは通常、すべてのデータを保存しますが、間違ったversion設定のため、Elasticsearchはアップグレードが処理されたと考えるようになりました。

  3. ESは、誤ったアップグレードのためにlegacy.routing.hash.typeの設定を自動的に設定します。これは、この時点以降に索引付けされたすべてのデータが、元々データをルーティングするために使用されていたデフォルトのMurmur3HashFunctionの代わりに古いDjbHashFunctionを使用したことを意味していました。

これは、問題を解決するためにデータを新しいインデックスに再インデックスすることが正しいことを意味します。新しいインデックスには正しいバージョン設定があり、従来のハッシュ関数設定はありません。

"version": { 
    "created": "2040699" 
} 
関連する問題