ServiceStack.Redis原來從v4就開始收費(但v3沒這問題),
目的為支援小專案和評估,所以我又回頭使用StackExchange.Redis進行CRUD。
前天正當我想把SQL Server一些資料表轉入Redis時,
使用ServiceStack.Redis居然出現每小時不能超過6000的request錯誤,
查看官方網頁得知,原來從v4開始免費版本有些限制(如下圖)
圖片來源: servicestack.net
但ServiceStack.Redis處理entity真的很方便又高效能,於是我追了一下Sourcecode並重新recompile為XX終極測試版
(我擷取部分sourcecode,如果覺得好用還請付費支持)
話雖如此,公司還是要使用正式版本,於是我又轉回使用StackExchange.Redis(使用上還須注意不少Redis.config設定)。
直接看code
Program _Program = new Program();
//_Program.Flushdb();
//insert
_Program.Insert();
//Select
RedisKey[] mykeys = { "User1", "User2", "User3" };//注意大小寫
_Program.GetUser(mykeys);
//update
_Program.Update("User1", "ricoisme", DateTime.Parse( "1981-12-13"));
_Program.GetUser(mykeys);
//delete
_Program.DeleteUser("User1");
_Program.GetUser(mykeys);
private void Insert()
{
StackExchangeRedisHelper _StackExchangeRedisHelper = new StackExchangeRedisHelper();
conn = _StackExchangeRedisHelper.SafeConn;//create safe connection
if (conn == null || !conn.IsConnected)
{
Console.WriteLine("No connection is available");
return;
}
IDatabase database = conn.GetDatabase();
var user1 = new User
{
ID = 1,
Name = "rico",
Birthday = DateTime.Parse("1982-01-01 12:12:12"),
Sex = true
};
var user2 = new User
{
ID = 2,
Name = "sherry",
Birthday = DateTime.Parse("1982-02-01 12:12:12"),
Sex = false
};
var user3 = new User
{
ID = 3,
Name = "fifi",
Birthday = DateTime.Parse("1982-03-01 12:12:12"),
Sex = false
};
//key要注意大小寫
if (_StackExchangeRedisHelper.Add<User>(database, "User" + user1.ID, user1))
{
Console.WriteLine("User" + user1.ID + " has inserted");
}
else
{
Console.WriteLine("User" + user1.ID + " insert failed");
}
if (_StackExchangeRedisHelper.Add<User>(database, "User" + user2.ID, user2))
{
Console.WriteLine("User" + user2.ID + " has inserted");
}
else
{
Console.WriteLine("User" + user2.ID + " insert failed");
}
if (_StackExchangeRedisHelper.Add<User>(database, "User" + user3.ID, user3))
{
Console.WriteLine("User" + user3.ID + " has inserted");
}
else
{
Console.WriteLine("User" + user3.ID + " insert failed");
}
}
public void GetUser(RedisKey[] keys)
{
StackExchangeRedisHelper _StackExchangeRedisHelper = new StackExchangeRedisHelper();
conn = _StackExchangeRedisHelper.SafeConn;//create safe connection
IDatabase database = conn.GetDatabase();
var datas = _StackExchangeRedisHelper.Get<User>(database, keys);
if (datas == null)
Console.WriteLine("No Data");
else
{
foreach (var data in datas)
{
Console.WriteLine("ID:{0} ,Name:{1}, Birthday:{2}, Sex:{3}",
data.ID, data.Name, data.Birthday.ToShortDateString(), data.Sex);
}
}
}
public void DeleteUser(string key)
{
StackExchangeRedisHelper _StackExchangeRedisHelper = new StackExchangeRedisHelper();
conn = _StackExchangeRedisHelper.SafeConn;//create safe connection
IDatabase database = conn.GetDatabase();
if (_StackExchangeRedisHelper.DeleteKey(database, key))
Console.WriteLine("Delete OK");
else
Console.WriteLine("Delete failed");
}
public void Update(string key, string name, DateTime birthday)
{
StackExchangeRedisHelper _StackExchangeRedisHelper = new StackExchangeRedisHelper();
conn = _StackExchangeRedisHelper.SafeConn;//create safe connection
IDatabase database = conn.GetDatabase();
var data = _StackExchangeRedisHelper.Get<User>(database, key);
if (data == null)
Console.WriteLine("No Data");
else
{
data.Name = name;
data.Birthday = birthday;
_StackExchangeRedisHelper.Add<User>(database, key, data);
}
}
public class StackExchangeRedisHelper
{
private Lazy<ConnectionMultiplexer> conn = null;
private IServer redisserver = null;
public StackExchangeRedisHelper()
{
try
{
conn = new Lazy<ConnectionMultiplexer>(
() => ConnectionMultiplexer.Connect(configOptions.Value));
}
catch
{
throw;
}
}
public ConnectionMultiplexer SafeConn
{
get
{
return conn.Value;
}
}
public IServer RedisServer
{
get
{
string _RedisServer = ConfigurationManager.AppSettings["RedisServer"];
int _RedisPort = int.Parse(ConfigurationManager.AppSettings["RedisPort"]);
redisserver = conn.Value.GetServer(_RedisServer, _RedisPort);
return redisserver;
}
}
private Lazy<ConfigurationOptions> configOptions
= new Lazy<ConfigurationOptions>(() =>
{
var configOptions = new ConfigurationOptions();
string RedisServer = ConfigurationManager.AppSettings["RedisServer"];
int RedisPort = int.Parse(ConfigurationManager.AppSettings["RedisPort"]);
string ClientName = ConfigurationManager.AppSettings["ClientName"];
bool allowAdmin = bool.Parse(ConfigurationManager.AppSettings["allowAdmin"]);
bool ssl = bool.Parse(ConfigurationManager.AppSettings["ssl"]);
int ConnectTimeout = int.Parse(ConfigurationManager.AppSettings["connectTimeout"]);//5 sec
configOptions.EndPoints.Add(RedisServer, RedisPort);
configOptions.ClientName = ClientName;
configOptions.ConnectTimeout = ConnectTimeout;
configOptions.SyncTimeout = int.MaxValue;
configOptions.AllowAdmin = allowAdmin;//need Flushdb
configOptions.Ssl = ssl;
/*
StackExchange.Redis won't reconnect to the server automatically under some conditions.
We strongly recommend that you set abortConnect=false in your connection string so that SE.
Redis will auto-reconnect in the background if a network blip occurs.
*/
configOptions.AbortOnConnectFail = false;
return configOptions;
});
public bool Add<T>(IDatabase database, string key, T value, DateTimeOffset? expiresAt = null) where T : class
{
//serialize
var serializedObject = JsonConvert.SerializeObject(value);
if (expiresAt.HasValue)
{
var expiration = expiresAt.Value.Subtract(DateTimeOffset.Now);
return database.StringSet(key, serializedObject, expiration);
}
return database.StringSet(key, serializedObject);
}
public bool DeleteKey(IDatabase database, string key)
{
return database.KeyDelete(key);
}
public T Get<T>(IDatabase database, string key) where T : class
{
var serializedObject = database.StringGet(key);
//deserialize
return JsonConvert.DeserializeObject<T>(serializedObject);
}
public IEnumerable<T> Get<T>(IDatabase database, RedisKey[] keys) where T : class
{
var AllserializedObject = database.StringGet(keys);
//deserialize
List<T> allvalues = new List<T>();
foreach (RedisValue data in AllserializedObject)
{
if (data.HasValue)
allvalues.Add(JsonConvert.DeserializeObject<T>(data));
}
return allvalues;
}
}
Note:也可以透過StackExchange.Redis.Extensions實作。
參考