4

首先感谢您的时间...在google,github和here上搜索之后,对大词(partition/shard/fedorate)更加困惑,我想我必须描述我遇到的具体问题并四处询问.

我公司的数据库是处理海量用户和订单的,所以我们对数据库和表进行了多种拆分,下面分别介绍:

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

基本概念是数据库和表是根据一个字段(不一定是主键)分离的,并且数据库太多,表太多,因此为每个数据库和一个模型编写或神奇地生成一个 database.yml 配置对于每个表是不可能的,或者至少不是最好的解决方案。

我研究了drnic的魔术解决方案,datafabric,甚至是活动记录的源代码,也许我可以使用ERB生成database.yml并在过滤器周围进行数据库连接,也许我可以使用named_scope来动态决定表名找到,但更新/创建操作仅限于“self.class.quoted_table_name”,因此我无法轻松解决我的问题。甚至我可以为每个表生成一个模型,因为它的数量最多可达 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

用DbCharmer很容易实现案例二(只有数据库名称更改)。您需要在 DbCharmer 中创建自己的分片方法,该方法将根据密钥返回连接参数哈希。

其他两种情况不立即支持,但可以轻松添加到您的系统中:

  1. 您实现了分片方法,该方法知道如何处理分片数据库中的数据库名称,这将使您能够shard_for(key)调用模型以切换数据库连接。

  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 回答