最近在研究遊戲程式中的結算功能,當結算筆數過多時,容易拖累資料庫效能,於是我想到利用 Redis Server 來暫存資料,只是 Redis 的效能如何並不清楚,所以這次就簡單寫了支程式來測試。

首先測試寫入的效能,一開始先建立測試資料:

public class User
{
    public string UserId { get; set; } = string.Empty;
    public string AccountName { get; set; } = string.Empty;
    public string Password { get; set; } = string.Empty;
    public string UserName { get; set; } = string.Empty;
    public string Email { get; set; } = string.Empty;
    public decimal Credit { get; set; } = 0;
    public string Token { get; set; } = string.Empty;
}

public class Stock
{
    public string Id { get; set; } = string.Empty;
    public string Name { get; set; } = string.Empty;
    public decimal Amount { get; set; }
    public decimal Winloss { get; set; }
    public float Odd { get; set; }
    public bool IsWin { get; set; } = false;
}
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost:7777,defaultDatabase=2");
IDatabase db = redis.GetDatabase();

int max = 34_000;
List<Stock> stocks1 = new List<Stock>();
List<Stock> stocks2 = new List<Stock>();
List<Stock> stocks3 = new List<Stock>();
List<List<Stock>> list = new List<List<Stock>>
{
    stocks1,
    stocks2,
    stocks3
};
ConcurrentBag<User> users = new ConcurrentBag<User>();
for (int i = 0; i < max; i++)
{
    Parallel.ForEach(list, (stocks, j) => 
    {
        CreateStockAndUserList(ref stocks, ref users);
    });
}
Console.WriteLine("All datas complete");

接下來將大量資料寫入 Redis Server:

Stopwatch stopwatch = Stopwatch.StartNew();
JsonSerializerOptions options = new JsonSerializerOptions
{
   WriteIndented = true
};
foreach (User user in users)
{
   string jsonStr = JsonSerializer.Serialize(user, options);
   db.StringSet(user.AccountName, jsonStr);
}
stopwatch.Stop();
Console.WriteLine($"Insert users total Time: {stopwatch.ElapsedMilliseconds}ms");
stopwatch = Stopwatch.StartNew();
Parallel.ForEach(list, (stockList) =>
{
    foreach (Stock stock in stockList)
    {
        string jsonStr = db.StringGet(stock.Name);
        User user = JsonSerializer.Deserialize<User>(jsonStr);
        user.Credit += stock.Winloss;
        jsonStr = JsonSerializer.Serialize(user, options);
        db.StringSet(user.AccountName, jsonStr);
    }
});
stopwatch.Stop();
Console.WriteLine($"Update stock total Time: {stopwatch.ElapsedMilliseconds}ms");

這裡為節省執行時間,有用到簡易的平行運算。

測試結果:

測試設備為 AERO 筆電,CPU 為 i7,記憶體 16 G,Redis 則是在本機的 Docker 上執行。