Azure弹性数据库合并GUI密钥碎片

时间:2016-09-21 16:43:07

标签: c# sql-server azure azure-elastic-scale

在Azure中我们有四个Shards,我想删除其中两个,因为我们不再需要它们了。数据应该合并到另外两个Shards中。

我使用带有GUID的Listmap作为Key来识别Shard(在我们的应用程序中,这是UserId)。 在教程中,我只找到了将Shards与Range类型合并的示例。 有没有办法以更快的方式合并这些类型的分片,还是我必须为此编写自己的工具?

如果自动执行合并,则会出现以下情况: 用于标识Shard的GUID是UserId,现在此数据从Shard A移动到Shard B.还有另一个名为Comments的表,其UserId为ForeignKey。此表中的PrimaryKey是经典的数字自动增量值。如果它们从碎片A移动到碎片B,会发生什么?它们是否会被插入并为它们分配一个新ID,或者这根本不起作用?

还有一些本地的FileStorage,它使用了Path中的ID,因此无论如何我都必须编写自己的工具。

为此,我查看了ShardMapManager,但没有完全理解它是如何工作的。在ShardMappingsGlobal表中是一个名为MappingId的列。但这不是存储在分片数据库中的Guid / UserId。我如何得到用于识别碎片的实际Guid,在我的例子中是UserId? 我也没有找到在Shards之间移动数据的方法。 我现在要做的是用自己的工具在Shards之间传输数据,然后使用ListShardMap.UpdateMapping方法为值设置一个新的Shard。 在操作结束时,我会使用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插入列'LockOwnerId',表__ShardManagement.ShardMappingsLocal

我不明白为什么甚至有插入?我在本地和全局Shardmapping表中检查了mappingId,并且映射是存在的,所以在我看来不需要插入。我还在这里看了一下提到的存储过程spBulkOperationShardMappingsLocal的代码:https://github.com/Azure/elastic-db-tools/blob/master/Src/ElasticScale.Client/ShardManagement/Scripts/UpgradeShardMapManagerLocalFrom1.1To1.2.sql 在Insert语句中,LockOwnerId不作为参数传递,因此它只能失败。 目前我正在使用testsetup,因为我当然不想在生产系统上玩。也许我犯了一个错误但对我来说一切都很好看。关于这个错误,我会非常感激。

1 个答案:

答案 0 :(得分:1)

  

在教程中,我只找到了将Shards与Range类型合并的示例。有没有办法以更快的方式合并这些类型的分片,还是我必须为此编写自己的工具?

是的,Split-Merge tool可以从范围和列表分片地图中移动数据。对于列表分片映射,您可以为每个密钥发出shardlet移动请求。不幸的是,Split-Merge工具有一些复杂的设置,上次花了大约一个小时来配置。我知道这不是很好,我会留给你,以确定是否需要更多或更少的时间来编写自己的自定义版本。

  

还有另一个名为Comments的表,其中UserId为ForeignKey。此表中的PrimaryKey是经典的数字自动增量值。如果它们从碎片A移动到碎片B,会发生什么?它们是否会被插入并为它们分配一个新ID,或者这根本不起作用?

不会复制自动增量列的值,它们将在目标位置重新生成。因此,新的ID将分配给这些行。

  

为此,我查看了ShardMapManager,但没有完全理解它是如何工作的。在ShardMappingsGlobal表中是一个名为MappingId的列。但这不是存储在分片数据库中的Guid / UserId。我如何得到用于识别碎片的实际Guid,在我的例子中是UserId?

强烈建议不要自己编辑ShardMapManager表,这很容易搞砸。编辑ShardMapManager表正是Elastic Database Tools library的目的。

您可以使用ListShardMap.UpdatePointMapping method更新映射的元数据。为了清楚起见,这只是更新了ShardMapManager表对应该对于密钥的位置的了解。实际上,移动映射必须由更高层完成。

这是Split-Merge服务的高级摘要:

  1. 锁定映射以防止从另一个分片映射管理操作进行并发更新
  2. 使用ListShardMap.UpdatePointMapping离线标记地图。这可以防止允许使用OpenConnectionForKey的数据导向路由访问具有该密钥的数据。它还会杀死分片上的所有当前会话以强制它们重新连接,这可确保没有活动连接使用now-offline密钥对数据进行操作
  3. 使用Shard Map的SchemaInfo移动基础数据以确定需要移动哪些表
  4. 更新地图并使用ListShardMap.UpdatePointMapping
  5. 在线标记
  6. 解锁映射