Azure弹性数据库合并GUI关键分片

3
在Azure中,我们有四个分片,我想移除其中两个,因为我们不再需要它们了。数据应该合并到另外两个分片中。
我使用一个带有GUID作为键的Listmap来标识分片(在我们的应用程序中,这是用户ID)。在教程中,我只找到了使用Range类型合并分片的示例。有没有一种更快速地合并这些类型的分片的方法,或者我必须编写自己的工具来完成这个任务?
如果合并是自动执行的,例如以下情况会发生什么: 用于标识分片的GUID是用户ID,现在将此数据从Shard A移动到Shard B。还有另一个名为Comments的表,它具有UserId作为ForeignKey。此表中的PrimaryKey是一个经典的数字自增值。如果将它们从Shard A移动到Shard B,它们会发生什么?它们会被插入并分配一个新的ID吗?还是根本行不通?
此外,还涉及到一些本地文件存储,它在路径中使用ID,所以我认为我仍然需要编写自己的工具。
为此,我查看了ShardMapManager,但我并没有完全理解它的工作原理。在ShardMappingsGlobal表中有一个名为MappingId的列。但这不是存储在Shard数据库中用于标识分片的Guid / UserId。如何获取实际用于标识分片的Guid,对于我的情况是UserId?
我也没有找到在分片之间移动数据的方法。现在我会使用自己的工具在分片之间传输数据,然后使用ListShardMap.UpdateMapping方法为该值设置一个新的分片。在操作结束时,我将使用ListShardMap.DeleteShard,或者有更好的方法吗?
编辑:
我编写了自己的工具来合并分片,但现在我遇到了奇怪的异常。以下是一些代码:
        Guid userKey = Guid.Parse(userId);
        ListShardMap<Guid> map = GetUserShardMap<Guid>();

        try
        {
            PointMapping<Guid> currentMapping = map.GetMappingForKey(userKey);

            PointMapping<Guid> mappingOffline = map.UpdateMapping(currentMapping, new PointMappingUpdate()
            {
                Status = MappingStatus.Offline
            });  
         }

UpdateMapping引起了以下异常: 存储错误:错误515,级别16,状态2,过程__ShardManagement.spBulkOperationShardMappingsLocal,行98,消息:无法将NULL值插入表“__ShardManagement.ShardMappingsLocal”的列“LockOwnerId” 我不明白为什么需要插入?我在本地和全局Shardmapping表中检查了mappingId,映射已经存在,所以我认为不需要进行插入。我还查看了所提到的spBulkOperationShardMappingsLocal存储过程的代码,链接在这里:https://github.com/Azure/elastic-db-tools/blob/master/Src/ElasticScale.Client/ShardManagement/Scripts/UpgradeShardMapManagerLocalFrom1.1To1.2.sql 在Insert语句中,没有传递LockOwnerId作为参数,因此它只能失败。 目前我正在使用测试设置,因为我当然不想在生产系统上操作。也许我犯了一个错误,但在我看来一切都很好。如果有关于此错误的任何提示,我将非常感激。

好的,新的异常问题也解决了。我将生产环境中的数据复制到了测试环境中,包括Shards和MapManager数据库。我在MapManager中更改了数据库名称和服务器设置,使其指向测试环境,但似乎这还不够……现在我插入了一些新的虚拟数据进行测试,现在它可以正常工作了。 - metabolic
1个回答

1
在教程中,我只找到了合并范围类型Shards的示例。是否有更快速的方法来合并这些类型的Shard,或者我必须编写自己的工具来完成?
是的,Split-Merge工具可以移动来自范围和列表Shard映射的数据。对于列表Shard映射,您可以为每个键发出Shardlet移动请求。不幸的是,Split-Merge工具需要一些复杂的设置,上次花费了我大约一个小时进行配置。我知道这不是很好,我将让您确定编写自己的定制版本需要更多还是更少的时间。
还有另一个名为Comments的表,其中UserId作为外键。该表的PrimaryKey是经典的数字自增值。如果将它们从Shard A移动到Shard B,这些值会发生什么?它们会被插入并分配一个新的ID,还是根本无法工作?
自增列的值不会被复制,它们将在目标位置重新生成。因此,这些行将被分配新的ID。
我查看了ShardMapManager,但并没有完全理解其工作原理。在ShardMappingsGlobal表中有一个名为MappingId的列。但这不是存储在Shard数据库中的Guid/UserId。我该如何获取用于标识分片(在我的情况下是UserId)的实际Guid?强烈建议不要尝试自行编辑ShardMapManager表,很容易出错。编辑ShardMapManager表正是Elastic Database Tools library的设计目的。您可以使用ListShardMap.UpdatePointMapping方法更新映射的元数据。请注意,这仅会更新ShardMapManager表对数据所在位置的知识。实际移动映射必须由更高层次完成。这是Split-Merge服务的高级摘要:
  1. 锁定映射以防止其他分片管理操作的并发更新
  2. 使用ListShardMap.UpdatePointMapping将映射标记为离线。这可以防止使用OpenConnectionForKey进行数据导向路由,从而访问具有该键的数据。它还会终止分片上的所有当前会话,以强制它们重新连接,以确保没有在现在离线的键上操作数据的活动连接。
  3. 使用分片映射的SchemaInfo移动基础数据,以确定需要移动哪些表
  4. 使用ListShardMap.UpdatePointMapping更新映射并将其标记为在线
  5. 解锁映射

谢谢你的回答。我设置了https://azure.microsoft.com/en-us/documentation/articles/sql-database-elastic-scale-configure-deploy-split-and-merge/中描述的工具。我选择了“合并”作为操作和“Guid”作为键类型,但是我必须为源和目标输入“范围低和高键”。对于ListShardMap,我应该在这里输入什么?谢谢。 - metabolic
选择Shardlet Move进行操作。干杯。 - Jared Moore
谢谢,我现在根据您的高级摘要自己写了代码。当我将映射设置为离线时,出现了一个奇怪的异常。我已经更新了我的问题。 - metabolic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接