4

最初に時間を割いていただきありがとうございます...グーグル、github、そしてここで検索した後、大きな単語(パーティション/シャード/フェドレート)についてもっと混乱しました、私は私が遭遇した特定の問題を説明し、周りに尋ねなければならないと思います。

私の会社のデータベースは大量のユーザーと注文を処理するため、データベースとテーブルをさまざまな方法で分割します。その一部を以下に説明します。

way             database and table name      shard by (maybe it's should be called partitioned by?)
YZ.X            db_YZ.tb_X                   order serial number last three digits
YYYYMMDD.       db_YYYYMMDD.tb               date
YYYYMM.DD       db_YYYYMM.tb_ DD             date too

基本的な概念は、データベースとテーブルがフィールド(必ずしも主キーではない)に従って分離され、データベースとテーブルが多すぎるため、データベースとモデルごとに1つのdatabase.yml構成を作成または魔法のように生成することです。各テーブルについては不可能であるか、少なくとも最善の解決策ではありません。

drnicの魔法のソリューション、datafabric、さらにはアクティブレコードのソースコードを調べました。ERBを使用してdatabase.ymlを生成し、フィルター周辺でデータベース接続を行うことができます。また、named_scopeを使用してテーブル名を動的に決定することもできます。検索しますが、更新/作成操作は「self.class.quoted_table_name」にバインドされているため、問題を簡単に解決できませんでした。また、テーブルごとに1つのモデルを生成することもできます。これは、その量が最大で30であるためです。

しかし、これはドライではありません!

私が必要としているのは、次のDSLのようなクリーンなソリューションです。

class Order < ActiveRecord::Base
   shard_by :order_serialno do |key|
      [get_db_config_by(key), #because some or all of the databaes might share the same machine in a regular way or can be configed by a hash of regex, and it can also be a const
       get_db_name_by(key), 
       get_tb_name_by(key),        
      ]
   end
end

誰かが私を啓発できますか?どんな助けでも大歓迎です~~~~

4

3 に答える 3

2

ケース2(db名のみが変更される場合)は、DbCharmerを使用して実装するのは非常に簡単です。DbCharmerで独自のシャーディングメソッドを作成する必要があります。これにより、キーに基づいて接続パラメーターのハッシュが返されます。

他の2つのケースはすぐにはサポートされませんが、システムに簡単に追加できます。

  1. シャーディングされたdabataseでデータベース名を処理する方法を知っているシャーディングメソッドを実装します。これによりshard_for(key)、モデルを呼び出してdb接続を切り替えることができます。

  2. 次のようなメソッドを追加します。

    class MyModel < ActiveRecord::Base
      db_magic :sharded => { :sharded_connection => :my_sharding_method }
    
      def switch_shard(key)
        set_table_name(table_for_key(key))  # switch table
        shard_for(key)                      # switch connection
      end
    end
    
  3. これで、次のようにモデルを使用できます。

    MyModel.switch_shard(key).first
    MyModel.switch_shard(key).count
    

    shard_for(key)また、メソッドから呼び出し結果が返されることを考えると、次のswitch_shardように使用できます。

    m = MyModel.switch_shard(key) # Switch connection and get a connection proxy
    m.first                       # Call any AR methods on the proxy
    m.count 
    
于 2011-10-13T12:47:02.040 に答える
1

この場合、SQLを使用しないことを検討する必要があるようです。

データセットが非常に大きく、キーと値のペアとして表現できる場合(少し非正規化)、couchDBまたは他のnoSQLソリューションを調べる必要があります。これらのソリューションは高速で完全にスケーラブルであり、RESTベースであるため、拡張、バックアップ、および複製が容易です。

私たちは皆、同じツールですべての問題を解決することに取り掛かっています(私を信じてください、私もそうしようとしています)。

noSQLソリューションに切り替えてから、activeRecordを書き換える方がはるかに簡単です。

于 2009-11-04T18:23:52.607 に答える
1

その特定のDSL、またはレガシーシャーディングの背後にあるロジックと一致するものが必要な場合は、ActiveRecordを掘り下げて、その種の機能を提供するgemを作成する必要があります。あなたが言及するすべての既存の解決策は、必ずしもあなたの状況を念頭に置いて書かれているわけではありません。あなたはあなたの意志に合わせていくつもの解決策を曲げることができるかもしれません、しかし結局あなたはあなたが探しているものを得るためにおそらくカスタムコードを書かなければならないでしょう。

于 2009-11-03T22:17:04.913 に答える