由于要做一个同一个页面上多种图表数据的下载,考虑到Azure上面的session很不稳定(可用Redis provider存储session,较稳定),故决定改为Azure支持的Redis,顺便也学习一下这种新的存储方式。
关于Redis的介绍这里不赘述了,他可存储多种类型的数据,不过还是相当基本的那些数据类型。
开始的设计是,利用Redis的Hashs存储每一个数据表的行列信息。在写了一系列代码后,发现这样的话执行速度上会有很大的影响。
后来经同事提醒,可以将table转换为json再进行Redis的String类型的存储。
在Azure门户上进行相应的Redis的配置。
然后先建立一个RedisClient类
public class RedisClient
{
private static readonly ILogger _logger = LoggerFactory.GetLogger(LoggerSourceName);
private const string LoggerSourceName = "RedisClient"; private static readonly Lazy<ConnectionMultiplexer> LazyConnection = new Lazy<ConnectionMultiplexer>(() =>
{
_logger.Info(LoggerSourceName, "Begin to create Redis connection"); //read connection information from storage/configuration-redis/Redis.config
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(Config.CloudStorageAccount);
CloudBlobContainer container = storageAccount.CreateCloudBlobClient().GetContainerReference("configuration-redis");
if (!container.Exists())
throw new ConfigurationErrorsException("fail to get redis connection string");
CloudBlockBlob blob = container.GetBlockBlobReference("Redis.config");
if (!blob.Exists())
throw new ConfigurationErrorsException("fail to get redis connection string");
string redisConnectionString;
using (var ms = new MemoryStream())
{
blob.DownloadToStream(ms);
ms.Position = ;
using (var sr = new StreamReader(ms))
{
redisConnectionString = sr.ReadToEnd();
}
} ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(redisConnectionString);
redis.ConfigurationChanged += redis_ConfigurationChanged;
redis.ConfigurationChangedBroadcast += redis_ConfigurationChangedBroadcast;
redis.ConnectionFailed += redis_ConnectionFailed;
redis.ConnectionRestored += redis_ConnectionRestored;
return redis;
}); private static IDatabase _db; public static ConnectionMultiplexer Connection
{
get { return LazyConnection.Value; }
} public static IDatabase Db
{
get { return _db ?? (_db = Connection.GetDatabase()); }
} private static void redis_ConnectionRestored(object sender, ConnectionFailedEventArgs e)
{
_logger.Info(LoggerSourceName, "Redis ConnectionRestored");
} private static void redis_ConnectionFailed(object sender, ConnectionFailedEventArgs e)
{
_logger.Info(LoggerSourceName, "Redis ConnectionFailed");
} private static void redis_ConfigurationChangedBroadcast(object sender, EndPointEventArgs e)
{
_logger.Info(LoggerSourceName, "Redis ConfigurationChangedBroadcast");
} private static void redis_ConfigurationChanged(object sender, EndPointEventArgs e)
{
_logger.Info(LoggerSourceName, "Redis ConfigurationChanged");
}
}
然后就是简单的写入啦。
public static void SetRedisTable(string key, DataTable dt)
{
if (dt != null && !string.IsNullOrEmpty(key))
{
string value = JsonHelper.ToJson(dt);
RedisClient.Db.StringSetAsync(key, value);
}
}
还有读取。
public static DataTable GetRedisTable(string key)
{
DataTable dt = new DataTable();
if (!string.IsNullOrEmpty(key))
{
string s = RedisClient.Db.StringGet(key).ToString();
if (!string.IsNullOrEmpty(s))
dt = JsonHelper.JsonToDataTable(s);
}
return dt;
}
以上很简单
另有一段代码还不知道干嘛用,先记录下来。
public static class StackExchangeExtesion
{
public static T Get<T>(this IDatabase cache, string key)
{
var cachedValue = cache.StringGet(key);
if (String.IsNullOrEmpty(cachedValue))
return default(T);
return JsonConvert.DeserializeObject<T>(cachedValue);
} public static object Get(this IDatabase cache, string key)
{
var cachedValue = cache.StringGet(key);
if (String.IsNullOrEmpty(cachedValue))
return null;
return JsonConvert.DeserializeObject<object>(cachedValue);
} public static void Set(this IDatabase cache, string key, object value, TimeSpan? expiry = null, When when = When.Always, CommandFlags flags = CommandFlags.None)
{
cache.StringSet(key, JsonConvert.SerializeObject(value), expiry, when, flags);
} public static void ListPush(this IDatabase cache, string key, object value)
{
cache.ListRightPush(key, JsonConvert.SerializeObject(value));
} public static RedisValue[] ListRange(this IDatabase cache, string key, long start, long stop)
{
if (start >= cache.ListLength(key))
return new RedisValue[]; return cache.ListRange(key, start, stop);
}
}