2016-06-27 6 views
0

ユーザーデータを効率的に保存して照会したいと考えています。ユーザーは一意のUUIDで識別され、数百の異なる属性(すべてブール値、数値または文字列)の値を持つことができます。ただし、ほとんどのユーザーにとって、既知の属性の数は非常に限られているため、ほとんどの値はnullです。さらに、いくつかの属性は本質的に階層的です(例えば、女性(yes-no) - > likes_heels(yes-no) - > likes_red_heels(yes-no))。 1億人の異なるユーザーがおり、新しい可能性の高い属性が頻繁に追加されます。スパースユーザープロファイル用の適切なデータベース設計

私は、リレーショナルテーブル構造(例:Impala)、キー値ストレージ(HBaseなど)、JSONベースデータベース(MongoDBなど)の3つのオプションを検討しています。

焦点は、クエリを実行するには、現在ある(例えばどのように多くのユーザーである男性、30歳、中国語?以上)

私はあなたの勧告を楽しみにしています!

答えて

1

同様の使用例で私の経験を共有できます。このような属性を何千も格納するためにHBaseを使用しました。私たちの場合、属性値は常にtrue/false/nullでした。 Nullは、それが間違っているか真実であるかを決定的に判断できないことを意味しました。

目標は、複雑なブール式のための大規模な集約を実行するには

  • にしました。たとえば、女性で、2つの日付の間のかかとのようなすべてのユーザーの集計(カウント)を教えてください。
  • 例ほとんどで、サンプルは(非常に迅速に)私たちの動向の公正な表示を与えたので
  • サンプルの集計上で実行するためにストレージを最小限に抑え、ひいては回
をスキャンする属性
  • を追加する機能を許可します

    すべての属性をビットマップデータ構造にエンコードしました。すべての属性には一意のオフセット値(ビットマップ内の位置)があります。ビットが設定されている場合、ユーザは女性またはヒールのようなものです。ヌルを処理するために、私たちはすべてのユーザーのために追加のビットマップを保存しました。最初のビットマップでビットが偽である場合、2番目のビットマップで同じ位置をチェックして、それが真であるかどうかを確認します。 2番目のビットマップにビットがセットされていれば、それをnullに扱いました。

    BitMapを単独で使用すると、フットプリントが1桁小さくなります。 Roaring Bit Mapsのようなスパースビットマップ構造を使用してストレージを削減し、効率を上げることもできます。

    ビットマップ(バイト配列)内のビットを検索することは、一定の時間操作です。次に、HBaseコプロセッサを使用して集約を実行しました。クライアントは、

    のようにブール式を渡します。
    att1 && att2 && (att3 || att4) 
    

    クライアントは式の各属性のオフセットも渡します。これにより、コプロセッサは、オフセットに基づいてフィルタリングされた行のビットを走査することができた。

    私たちの行キーのデザインは、ユーザーIDのSHA1に基づいていました。それは

  • これは、私たちは可能な256個の破片(最初の2バイト)のうち、サンプルをスキャンし

    • へのHBaseのファジィ行フィルタを使用することを許可

      <FIRST 2 BYTES of SHA1><DD-MM-YYYY><40 bytes of SHA1> 
      

      た日付範囲のスキャン

    私はスパースビットマップのない約6000の属性とスパースビットマップの約15000の属性に対してこの方法をテストしました。場合によっては、数値属性をビットマップでモデル化することは可能です(明らかに連続値ではありません)。

    私たちは約50億人のユーザーを扱い、各ユーザーは約3回(平均)モデル化されており、そのようなイベント(ユーザーID - 日付モデル化属性セット)を約150億保存しました。また、同じユーザーが異なる日付でモデル化された属性を持つ可能性があるため、別個のカウントを実行する機能もサポートしました。

    Map/Reduceですべてのエンコードを実行し、非常に高速なロードを実行するためにHBaseのバルクロード機能を使用しました。

    このデザインの利点の1つは、HDFSにすべてのエンコードされたデータのコピーを保存しているため、カスタムHive/Impala/Spark UDFを作成してSQL経由のクエリのフィルタ/評価を行うことでした。また、HDFSのコピーは、コールドレイヤーとして長い時間(HBaseに保存できる時間より長く)保持することができます。

    また、Apache Phoenixを考慮しましたが、一度に1つの式ではなく、同時に100個の式で集計をサポートしたいと考えていたため、これを選択しませんでした。

    こちらがお役に立てば幸いです。

  • 関連する問題