У меня есть требование для создания счетчика, который будет отправлен на некоторые вызовы api. Мое приложение работает на нескольких узлах, поэтому некоторые, как я хотел создать уникальный счетчик. Я попытался следующий кодRedis распределенный приращение с блокировкой
public static long GetTransactionCountForUser(int telcoId)
{
long valreturn = 0;
string key = "TelcoId:" + telcoId + ":Sequence";
if (Muxer != null && Muxer.IsConnected && (Muxer.GetDatabase()) != null)
{
IDatabase db = Muxer.GetDatabase();
var val = db.StringGet(key);
int maxVal = 999;
if (Convert.ToInt32(val) < maxVal)
{
valreturn = db.StringIncrement(key);
}
else
{
bool isdone = db.StringSet(key, valreturn);
//db.SetAdd(key,new RedisValue) .StringIncrement(key, Convert.ToDouble(val))
}
}
return valreturn;
}
и запустить протестировали его с помощью Task Parallel libray. Когда у меня есть граничные значения, что я вижу, что многократное время 0 запись устанавливается
Пожалуйста, дайте мне знать, что исправление мне нужно сделать
Update: Моя последняя логика заключается в следующем
public static long GetSequenceNumberForTelcoApiCallViaLuaScript(int telcoId)
{
long valreturn = 0;
int maxIncrement = 9999;//todo via configuration
if (true)//todo via configuration
{
IDatabase db;
string key = "TelcoId:" + telcoId + ":SequenceNumber";
if (Muxer != null && Muxer.IsConnected && (db = Muxer.GetDatabase()) != null)
{
valreturn = (int)db.ScriptEvaluate(@"
local result = redis.call('incr', KEYS[1])
if result > tonumber(ARGV[1]) then
result = 1
redis.call('set', KEYS[1], result)
end
return result", new RedisKey[] { key }, flags: CommandFlags.HighPriority, values: new RedisValue[] { maxIncrement });
}
}
return valreturn;
}
Почему вы не используете простую таблицу с только столбец идентификаторов, делать вставки и использовать возвращаемый SCOPE_IDENTITY() - это должно возвращать что-то уникальное все время. –
Я хотел избегать вставки db/db в оба конца. У меня есть поддержка Cache Via Redis, которую я хотел полностью дозировать –
@KamranShahid, пожалуйста, не используйте 'string.Format', чтобы параметризовать это; Я отредактирую свой пример, чтобы показать предпочтительный способ –