Должны ли объекты ShardMapManager и ShardMap глобально кэшироваться как одноэлементный?
У меня есть приложение с несколькими базами данных 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, что ShardMapManager
действительно должен быть создан один раз и сохранен в глобальной переменной.
Но как насчет ListShardMap
? Если у нас есть только один, можем ли мы сохранить его в глобальной переменной?
1 ответ
ShardMapManager содержит кэш отображений, и если бы у нас было несколько кешей, то (а) мы бы потребляли больше памяти из-за дубликатов, и (б) мы в целом получали бы больше пропусков кеша, что привело бы к снижению производительности. Поэтому мы хотим иметь одноэлементный ShardMapManager, чтобы иметь только одну копию кэша.
ListShardMap содержит внутреннюю ссылку на ShardMapManager, который его создал, чтобы он мог ссылаться на этот кеш. Если вы создаете несколько экземпляров ListShardMap из одного и того же ShardMapManager, они все ссылаются на один и тот же кеш (внутри этого SMM), так что это совершенно нормально.