短縮版
ユーザーをシャードに分割する場合、「ユーザー検索」を提供するにはどうすればよいですか? 明らかに、すべての検索がすべてのシャードにヒットすることは望んでいません。
ロングバージョン
シャードとは、複数のデータベースがあり、それぞれに全データの一部が含まれていることを意味します。(単純な) 例として、データベース UserA、UserB などには、名前が「A」、「B」などで始まるユーザーが含まれている可能性があります。データベース。戻ってきたユーザーがサインインすると、そのユーザーの名前をもう一度調べて、そのユーザーの情報を取得する正しいデータベースを判断します。
シャーディングと読み取りレプリケーションの利点は、読み取りレプリケーションが書き込みをスケーリングしないことです。マスターに送信されるすべての書き込みは、各スレーブに送信する必要があります。ある意味では、読み取り負荷が分散されていても、それらはすべて同じ書き込み負荷を担います。
一方、シャードは互いの書き込みを気にしません。Brian が UserB シャードにサインアップした場合、UserA シャードはそれについて知る必要はありません。Brian が Alex にメッセージを送信した場合、その事実を UserA シャードと UserB シャードの両方に記録できます。このようにして、Alex または Brian のいずれかがログインすると、すべてのシャードにクエリを実行することなく、送受信したすべてのメッセージを自分のシャードから取得できます。
ここまでは順調ですね。検索はどうですか?この例では、Brian が「Alex」を検索すると、UserA を確認できます。しかし、彼が姓の「Smith」で Alex を検索するとどうなるでしょうか。すべてのシャードにスミスがいます。ここから、次の 2 つのオプションが表示されます。
- アプリケーションで各シャードで Smiths を検索します。これは、ゆっくり (各シャードを連続してクエリする) または迅速に (各シャードを並行してクエリする) 行うことができますが、いずれにしても、すべてのシャードがすべての検索に関与する必要があります。読み取りレプリケーションが書き込みをスケーリングしないのと同じように、検索がすべてのシャードにヒットしても、検索はスケーリングされません。検索ボリュームが各シャードを圧倒するほど高くなる時期に達する可能性があり、シャードを追加しても検索ボリュームは同じになるため役に立ちません。
- それ自体がシャーディングに耐えられるある種のインデックス作成。たとえば、検索したい一定数のフィールドがあるとします: 名と姓です。UserA、UserB などに加えて、IndexA、IndexB などもあります。新しいユーザーが登録されると、そのユーザーを見つけてもらいたい各インデックスに追加します。そこで私は Alex Smith を IndexA と IndexS の両方に入れました。彼は "Alex" または "Smith" のいずれかで見つけることができますが、部分文字列はありません。この方法では、各シャードに対してクエリを実行する必要がないため、検索がスケーラブルになる可能性があります。
では、検索はスケーリングできますか? もしそうなら、この索引付けアプローチは正しいものですか? 他にある?