【问题标题】:How to fix Redis Performance Issues?如何修复 Redis 性能问题?
【发布时间】:2017-08-21 19:57:02
【问题描述】:

我正在使用 C# 客户端“StackExchange.Redis”对 Redis 进行基准测试。 该数据集是一个包含近 1600 万条记录的文本文件。每条记录有六个条目,其中三个是双精度的,另外三个是整数。 当我使用 LPush(API 中的 LPushRight)时,将所有数据添加到 Redis 大约需要 4 分钟。 之后,当我使用(API 中的 LRange)检索数据时,检索所有列表大约需要 1.5 分钟。 我正在使用以下代码:

连接:

ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
IDatabase db = redis.GetDatabase();

插入:

IEnumerable<string> lines =
File.ReadLines(@"C:\Hep.xyz");
    List<string> linesList = lines.ToList();
    int count = lines.Count();
    string[] toks;
    RedisValue[] redisToks = { "", "", "", "", "", "" };
    for (int i = 0; i < count; i++)
    {
         toks = linesList[i].Split(' ', '\t');
         for (int j = 0; j < 6; j++)
         {
                redisToks[j] = toks[j];
         }
         db.ListRightPushAsync("PS:DATA:", redisToks);
         if (i % 1000000 == 0)
         {
              Console.WriteLine("Lines Read: {0}", i);
         }
    }
    Console.WriteLine("Press any key to continue ...");
    Console.ReadLine();

检索:

long len  = db.ListLength("PS:DATA:");

long start = 0;
long end = 99999;
while (end < len)
{
      RedisValue[] val = db.ListRange("PS:DATA:", start, end);
      int length = val.Length;
      start += 100000;
      end += 100000;
}
Console.WriteLine("Press any key to continue ...");
Console.ReadLine();

对于配置:

我已将 ma​​xmemory 设置为 4GB 并将 ma​​xmemory-policy 设置为 volatile-lru

我在我的系统上本地运行所有这些。我的系统规格是 8 GB 内存 Inter Core i7 - 5500U CPU @ 2.4GHz(4 个 CPU),~2.4 GHz

能否请您帮我确定我需要研究的因素,以提高性能。还有,redis适合这种数据集吗?

【问题讨论】:

    标签: c# redis stackexchange.redis


    【解决方案1】:

    这不是redis慢造成的。因为在redis中保存数据的时候,时间成本还包括文件io(磁盘io)和网络io,尤其是从磁盘文件中读取行的时间,时间成本比较大。所以你看到当你从 redis 中检索数据时,时间成本只有 1.5 分钟,而插入时大约需要 4 分钟。

    总之,redis 在您的情况下运行良好。加快插入的另一件事是您可以使用 redis 管道来减少网络传输时间。

    异步写入不像管道。但是您应该注意到异步写入不会阻塞客户端。但是管道是批量发送命令和批量读取回复。所以它是不同的。

    请参阅https://redis.io/topics/pipelining 这不仅仅是 RTT 部分的问题。流水线还节省了 redis 服务器的 read() 和 write() 时间。

    【讨论】:

    • 但是redis不应该把它保存在内存中吗?为什么要从磁盘读取它?这不是内存存储的全部目的吗?另外,我正在使用异步调用来写入数据,这不是流水线吗?
    • 您能在上面的回复中隐藏完整路径吗?我不小心把它弄丢了,现在我也把它换成了我的问题。
    • 我所说的读取文件需要大量时间的是您的 File.ReadLines 操作。关于与管道异步,我的答案已更新。
    • 并非如此。如果我评论,listpush 调用需要 30 秒,而 redis listpush 调用需要 4 分钟
    • 我还提到了网络IO。因为您的案例是批量加载。花费 4 分钟对于 redis 性能来说是正常的。
    【解决方案2】:

    是的,你遇到的就是Redis官网documentation提到的问题:

    Redis 列表是通过链表实现的。这意味着即使列表中有数百万个元素,在列表的头部或尾部添加新元素的操作也是在恒定时间内执行的。用 LPUSH 命令向一个有 10 个元素的列表的头部添加一个新元素的速度与向一个有 1000 万个元素的列表的头部添加一个元素的速度相同。

    这就是您的插入操作非常快的原因。该文件进一步继续:

    有什么缺点?通过索引访问元素非常快 使用 Array 实现的列表(恒定时间索引访问)和 not 在链表实现的列表中如此之快(其中操作 需要与访问的索引成比例的工作量 元素)。

    如果您想快速访问,该文档进一步建议使用 Sorted Sets:

    当快速访问大量元素的中间很重要时,可以使用一种不同的数据结构,称为排序集。本教程稍后将介绍排序集。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多