Должны ли объекты ShardMapManager и ShardMap глобально кэшироваться как одноэлементный? - PullRequest
0 голосов
/ 22 февраля 2019

У меня есть приложение с несколькими базами данных SQL Azure, защищенными ключом.Каждый раз, когда мы открываем соединение с базой данных шарда, мы получаем ShardMapManager и ListShardMap:

public static ShardMapManager CreateOrGetShardMapManager(string shardMapManagerConnectionString)
{
    // Get shard map manager database connection string
    // Try to get a reference to the Shard Map Manager in the Shard Map Manager database. If it doesn't already exist, then create it.
    ShardMapManager shardMapManager = default(ShardMapManager);
    bool shardMapManagerExists = ShardMapManagerFactory.TryGetSqlShardMapManager(shardMapManagerConnectionString, ShardMapManagerLoadPolicy.Lazy, out shardMapManager);

    if (!shardMapManagerExists)
    {
        // The Shard Map Manager does not exist, so create it
        shardMapManager = ShardMapManagerFactory.CreateSqlShardMapManager(shardMapManagerConnectionString);
    }

    return shardMapManager;
}

public static ListShardMap<T> CreateOrGetListMap<T>(ShardMapManager shardMapManager, string shardMapName) 
{
    // Try to get a reference to the Shard Map.
    ListShardMap<T> shardMap = null;
    bool shardMapExists = shardMapManager.TryGetListShardMap(shardMapName, out shardMap);

    if (!shardMapExists)
    {
        // The Shard Map does not exist, so create it
        shardMap = shardMapManager.CreateListShardMap<T>(shardMapName);
    }

    return shardMap;
}

И затем мы открываем соединение, передавая ключ шарда в OpenConnectionForKey():

public static DbConnection CreateShardConnection(int shardingKey, string connectionStr, string shardMapName)
{
    var shardMapManager = CreateOrGetShardMapManager(connectionStr);
    var shardMap = CreateOrGetListMap<int>(shardMapManager, shardMapName);
    SqlConnection conn = shardMap.OpenConnectionForKey<int>(shardingKey, GenerateCredentialsConnString(connectionStr), ConnectionOptions.Validate);
    return conn;
}

Мы используем только одну карту шардов и одну карту списка для всех шардов, поэтому мой вопрос - можем ли мы кэшировать эти объекты в глобальной переменной?Они разработаны, чтобы быть потокобезопасными, и это поможет производительности?

Обновление

Я нашел здесь https://docs.microsoft.com/en-us/azure/sql-database/sql-database-elastic-scale-shard-map-management#constructing-a-shardmapmanager, что ShardMapManager действительно должен бытьсоздается один раз и сохраняется в глобальной переменной.

А как же ListShardMap?Если у нас есть только один, можем ли мы сохранить его в глобальной переменной?

1 Ответ

0 голосов
/ 22 февраля 2019

ShardMapManager содержит кэш отображений, и если бы у нас было несколько кешей, то (а) мы бы потребляли больше памяти из-за дубликатов, и (б) мы в целом получали бы больше пропусков кеша, оба из которых привели бы к снижению производительности,Поэтому мы хотим иметь одноэлементный ShardMapManager, чтобы иметь только одну копию кэша.

ListShardMap содержит внутреннюю ссылку на ShardMapManager, который его создал, чтобы он мог ссылаться на этот кэш.Если вы создаете несколько экземпляров ListShardMap из одного и того же ShardMapManager, они все ссылаются на один и тот же кеш (внутри этого SMM), так что это совершенно нормально.

...