【问题标题】:Getting poor performance while saving to Redis cache (using ServiceStack.Redis)保存到 Redis 缓存时性能不佳(使用 ServiceStack.Redis)
【发布时间】:2015-06-02 16:28:14
【问题描述】:

在将数据保存到 Redis 缓存时性能非常差。

场景:

1) 使用 Redis 缓存服务(Microsoft Azure 提供)。
2) 在 Azure 上创建的虚拟机中运行代码。
3) VM 和缓存服务都创建在同一个位置

代码片段:

    public void MyCustomFunction()
    {
        Stopwatch totalTime = Stopwatch.StartNew();

        RedisEndpoint config = new RedisEndpoint();
        config.Ssl = true;
        config.Host = "redis.redis.cache.windows.net";
        config.Password = Form1.Password;
        config.Port = 6380;
        RedisClient client = new RedisClient(config);

        int j = 0;

        for (int i = 0; i < 500; i++)
        {
            var currentStopWatchTime = Stopwatch.StartNew();
            var msgClient = client.As<Message>();

            List<string> dataToUpload = ClientData.GetRandomData();
            string myCachedItem_1 = dataToUpload[1].ToString();

            Random ran = new Random();
            string newKey = string.Empty;
            newKey = Guid.NewGuid().ToString();

            Message newItem = new Message
            {
                Id = msgClient.GetNextSequence(), // Size : Long variable
                //Id = (long)ran.Next(),
                Key = j.ToString(),             // Size: Int32 variable
                Value = newKey,                 // Size : Guid string variable
                Description = myCachedItem_1    // Size : 5 KB
            };

            string listName = ran.Next(1, 6).ToString();
            msgClient.Lists[listName].Add(newItem);
            //msgClient.Store(newItem);

            Console.WriteLine("Loop Count : " + j++ + " , Total no. of items in List : " + listName + " are : " + msgClient.Lists[listName].Count);

            Console.WriteLine("Current Time: " + currentStopWatchTime.ElapsedMilliseconds + " Total time:" + totalTime.ElapsedMilliseconds);

            Console.WriteLine("Cache saved");
        }
    }

性能(保存时):

注意:(所有时间均以毫秒为单位)

循环计数:0,总数。列表中的项目:2 是:1 当前时间:310 总时间:342 缓存已保存 循环数:1,总数。列表中的项目数:3 是:1 当前时间:6 总时间:349 缓存已保存 循环数:2,总数。列表中的项目数:5 是:1 当前时间:3 总时间:353 缓存已保存 循环数:3,总数。列表中的项目数:5 是:2 当前时间:3 总时间:356 缓存已保存 循环数:4,总数。列表中的项目数:5 是:3 当前时间:3 总时间:360 缓存已保存

。 . . . .

循环数:330,总数。列表中的项目:4 是:69 当前时间:2 总时间:7057 缓存已保存
循环次数:331,总次数。列表中的项目数:4 是:70 当前时间:3 总时间:7061 缓存已保存
循环次数:332,总次数。列表中的项目:4 是:71 当前时间:2 总时间:7064 缓存已保存

性能(获取时)

列表:1 物品数量 : 110 时间:57

列表:2 物品数量 : 90 时间:45

列表:3 物品数量 : 51 时间:23

列表:4 物品数量 : 75 时间:32

列表:5 物品数量 : 63 时间:33

【问题讨论】:

  • 您能提供更多信息吗? Redis 的大小和定价层,与 VM 相同吗?可以使用连接池(PooledRedisClientManager)吗?
  • @Panagiotis Kefalidis,Redis 缓存:标准 1 GB VM:标准,A2(2 核,3.5 GB 内存)我第一次使用 Redis 缓存,我对 PooledRedisClientManager 不太了解。你能给它任何很好的参考吗?如果可能,我可以在多个线程上执行这些操作。
  • 关闭 SSL 会有不同吗?尝试将 SSL 设置为 false

标签: caching azure redis azure-caching servicestack.redis


【解决方案1】:

如果您要批量处理,则应考虑减少同步网络请求的数量,以减少延迟,这将成为与网络服务通信时的主要性能问题。

对于此示例,您在调用时正在读取:

msgClient.GetNextSequence();

当你做的时候写一个:

msgClient.Lists[listName].Add(newItem);

在单个线程中总共有 1000 个同步请求/回复网络请求,其中每个操作都依赖于并且必须在发送下一个操作之前完成,这就是为什么网络延迟将成为性能问题的主要来源您应该考虑优化。

批处理请求

如果您正在处理批处理请求,则可以通过在单个请求中获取所有 id 并使用 AddRange() 批处理操作存储它们来减少读取和写入的次数,从而大大优化这一点,例如:

var redisMessages = Redis.As<Message>();
const int batchSize = 500;

//fetch next 500 sequence of ids in a single request
var nextIds = redisMessages.GetNextSequence(batchSize); 

var msgBatch = batchSize.Times(i => 
    new Message {
        Id = nextIds - (batchSize - i) + 1,
        Key = i.ToString(), 
        Value = Guid.NewGuid().ToString(),
        Description = "Description"
    });

//Store all messages in a single multi operation request
redisMessages.Lists[listName].AddRange(msgBatch);

这会将 1000 个 redis 操作压缩为 2 个操作。

如果您需要,您可以通过以下方式获取所有消息:

var allMsgs = redisMessages.Lists[listName].GetAll();

或使用GetRange(startingFrom,endingAt) API 的特定范围。

【讨论】:

  • 感谢@mythz 的输入。实际上我不能批量操作(基于我们的场景),但我可以在这里使用多线程。当我尝试在多个线程上运行此代码时,我收到一个异常 The Read method cannot be called when another read operation is pending. 任何帮助将不胜感激。
  • @KushalArora RedisClient 是一个非线程安全的实例,不能跨线程重复使用,所以需要在每个线程中从RedisManager 中获取一个新的RedisClient。
猜你喜欢
  • 2015-11-06
  • 2017-08-01
  • 1970-01-01
  • 2020-04-22
  • 2012-02-04
  • 2014-10-07
  • 2020-10-17
  • 2022-08-03
  • 1970-01-01
相关资源
最近更新 更多