3

我正在构建自己的分片解决方案。每个 ID 的构造如下:

  • 分片 ID(小整数)
  • 表类型 id(小整数)
  • 增量数(大整数)

前任。00001000010000000015

我使用虚拟分片,所以我可以将所有分片指向一个服务器,当我需要更多容量时,我只需添加另一台服务器并将一些虚拟分片指向该服务器,这样下次数据就会写入新的server 而不是第一个,尽管 read 将转到两台服务器,至少在我移动数据并在配置文件中更改它之前。

我的问题是增量数字。我希望那些是独一无二的。在 mysql 中为特定表使用 build int incremental id 并不好,因为我可能会将数据移动到另一台服务器,并且我可能有另一个数据使用其表的增量编号,因此我可能会得到重复的 ID。

所以我的问题是如何以可扩展的方式生成唯一 ID,而不使用将生成该 ID 的外部表,因为它不会扩展。我可以指出 Pinterest 如何在这里解决这个问题,这可能会有所帮助。我考虑给每个表一个增量值,该值在每个分片的不同值处跳过,所以它们在所有分片上的增量值永远不会相同。

我的想法是使用 Amazon RDS 构建我自己的分片解决方案,因此副本已经存在,平衡很容易,因为我可以利用从服务器提升为主服务器的优势,只需删除两台服务器上的数据并更改我的分片配置文件。我认为可以使用 Amazon RDS 构建一个可以轻松扩展的解决方案,而且它比今天其他公司提供的要便宜得多(我已经在这方面做了功课)。

我不想在我的 URL 中使用 GUID。我不介意使用长数字。Pinterest、Tumblr、Facebook 和许多其他人不使用 Guid,所以我知道他们是一个解决方案,只是想知道你认为哪种解决方案最有效,考虑到我想使用数字 ID。 

我正在用 ASP.NET C# 开发我的应用程序

4

2 回答 2

3

简而言之,你生成 ID 的方法注定要失败:如果你想生成唯一的 ID,你需要一个中央服务,这最终会成为一个瓶颈。

还包括分片 ID 味道不好;将数据移动到新分片时会发生什么?您是否必须更新所有 ID?

如果您想要一个可扩展的解决方案,您将不得不查看UUID或类似方法。

或者,您可以使用中央服务并为每次调用分配一个 ID 块(例如 10'000)。这样,您就不需要经常敲击中央服务,但如果服务失败,整个系统就会死机。

于 2012-11-09T15:49:49.290 回答
0

我使用 Int16 的分片 id 在创建表期间通过将分片 id 左移 (64 - 16) 并加 1 来为每个表设置 AUTO_INCREMENT 值。

下一个示例是使用 ServiceStack.ORMLite 库,但也可以在纯 SQL 中完成。当我需要创建一个新表时,我会遍历每个现有分片,打开与该分片的数据库连接(连接详细信息存储在查找表中)并调用此方法:

private static void CreateTableInShard<T>(IDbConnection db, bool overwrite = false, short shardId = 0) 
where T : IDataObject, new()
    {
        using (var trans = db.BeginTransaction())
        {
            db.CreateTable<T>(overwrite);

            if (overwrite)
            {
                var tableName = typeof(T).Name;
                var ai = ((long)shardId << 48) + 1;
                var sql = @"ALTER TABLE " + tableName + @"
                          AUTO_INCREMENT " + ai + @" ;";
                db.ExecuteSql(sql);
            }
            trans.Commit();
        }
    }

public interface IDataObject
    {
        long Id { get; set; }
    }

我有许多最初在一台机器上的逻辑分片。当我必须进行扩展时,我必须将整个分片移动到另一台机器上,并在我的查找表中更改分片 ID 的连接字符串。但移动后的 ID 生成不会受到影响。

要通过 id 查询分片表,我可以获取分片 id (id >> 48),然后查询特定的分片。

于 2013-05-29T15:09:15.727 回答