与 StackExchange.Redis 并行执行?

2024-06-22

我有一个 100 万件商品的商店List<Person>我正在序列化它以便插入到 Redis 中。 (2.8)

我将工作分配给10 Tasks<>其中每个都有自己的部分(List<>对于只读来说是线程安全的 ( 对 List 执行多次读取操作是安全的 http://msdn.microsoft.com/en-us/library/6sh2ey19%28v=vs.110%29.aspx)

简化:

example:

For ITEMS=100, THREADS=10 , each Task会捕获自己的PAGE并处理相关范围。

例如 :

void Main()
{
    var ITEMS=100;
    var THREADS=10;
    var PAGE=4;

    List<int> lst = Enumerable.Range(0,ITEMS).ToList();

    for (int i=0;i< ITEMS/THREADS ;i++)
    {
      lst[PAGE*(ITEMS/THREADS)+i].Dump();
    }
}
  • PAGE=0将处理:0,1,2,3,4,5,6,7,8,9
  • PAGE=4将处理:40,41,42,43,44,45,46,47,48,49

All ok.

现在回到SE.redis。

我想实现这个模式,所以I did https://i.stack.imgur.com/viRIl.jpg: (和ITEMS=1,000,000)

我的测试:

(这是dbsize每秒检查):

正如您所看到的,通过 10 个线程添加了 1M 条记录。

现在,我不知道它是否快,但是,当我从1M to 10M——事情得到really慢,我得到异常:

例外是在for loop.

未处理的异常:System.AggregateException:一个或多个错误 发生。 ---

System.TimeoutException:执行 SET 时超时:user>288257,inst:1,queu e:11,qu=0,qs=11,qc=0,wr=0/0,in=0/0 at StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](消息 消息、结果处理器1 processor, ServerEndPoint server) in c:\TeamCity\buildAgen t\work\58bc9a6df18a3782\StackExchange.Redis\StackExchange\Redis\ConnectionMultip lexer.cs:line 1722 at StackExchange.Redis.RedisBase.ExecuteSync[T](Message message, ResultProces sor1 个处理器,ServerEndPoint 服务器)中 c:\TeamCity\buildAgent\work\58bc9a6df 18a3782\StackExchange.Redis\StackExchange\Redis\RedisBase.cs:第 79 行 ... ... 按任意键继续 。 。 。

问题:

  • 我的工作分配方式是否正确(最快)
  • 我怎样才能更快地得到事情(示例代码将不胜感激)
  • 我该如何解决这个异常?

相关信息:

<gcAllowVeryLargeObjects enabled="true" />存在于 App.config 中(否则我会出现 outOfmemoryException ),另外 - 为 x64 位构建,我有 16GB、SSD 驱动器、i7 cpu)。


目前,您的代码正在使用同步 API (StringSet),并由 10 个线程同时加载。这不会给 SE.Redis 带来明显的挑战 - 它在这里工作得很好。我suspect这确实是一个超时,服务器花费的时间比您希望处理某些数据的时间长,很可能也与服务器的分配器有关。那么,一种选择就是简单地稍微增加超时时间。不是很多...尝试 5 秒而不是默认的 1 秒。无论如何,大多数操作可能都运行得非常快。

关于加速:这里的一种选择是not wait- 即保持数据流水线化。如果您不满足于检查每条消息的错误状态,那么一种简单的方法是添加, flags: CommandFlags.FireAndForget到你的结束StringSet称呼。在我的本地测试中,这将 1M 示例的速度提高了 25%(我怀疑剩余的大部分时间实际上都花在了字符串序列化上)。

我在 10M 示例中遇到的最大问题就是开销使用 10M 示例- 特别是因为这需要大量的内存redis-server和应用程序(以模拟您的设置)位于同一台计算机上。这会产生竞争性内存压力,例如托管代码中的 GC 暂停等。但也许更重要的是:开始做任何事情都需要很长时间。因此,我重构了代码以使用并行yield return生成器而不是单个列表。例如:

    static IEnumerable<Person> InventPeople(int seed, int count)
    {
        for(int i = 0; i < count; i++)
        {
            int f = 1 + seed + i;
            var item = new Person
            {
                Id = f,
                Name = Path.GetRandomFileName().Replace(".", "").Substring(0, appRandom.Value.Next(3, 6)) + " " + Path.GetRandomFileName().Replace(".", "").Substring(0, new Random(Guid.NewGuid().GetHashCode()).Next(3, 6)),
                Age = f % 90,
                Friends = ParallelEnumerable.Range(0, 100).Select(n => appRandom.Value.Next(1, f)).ToArray()
            };
            yield return item;
        }
    }

    static IEnumerable<T> Batchify<T>(this IEnumerable<T> source, int count)
    {
        var list = new List<T>(count);
        foreach(var item in source)
        {
            list.Add(item);
            if(list.Count == count)
            {
                foreach (var x in list) yield return x;
                list.Clear();
            }
        }
        foreach (var item in list) yield return item;
    }

with:

foreach (var element in InventPeople(PER_THREAD * counter1, PER_THREAD).Batchify(1000))

在此,目的是Batchify是为了确保我们不会因为每次操作之间花费大量时间而对服务器造成太大帮助 - 数据以 1000 为一组创建,并且每批都很快可用。

我还担心 JSON 性能,所以我改用 JIL:

    public static string ToJSON<T>(this T obj)
    {
        return Jil.JSON.Serialize<T>(obj);
    }

然后只是为了好玩,我将 JSON 工作移至批处理中(以便实际的处理循环:

 foreach (var element in InventPeople(PER_THREAD * counter1, PER_THREAD)
     .Select(x => new { x.Id, Json = x.ToJSON() }).Batchify(1000))

这使时间缩短了一些,因此我可以在 3 分 57 秒内加载 10M,速度为 42,194 转。大部分时间实际上是应用程序内部的本地处理。如果我改变它以便每个线程加载same item ITEMS / THREADS次,则变为 1 分 48 秒 - 速率为 92,592 转。

我不确定我是否真的回答了任何问题,但简短的版本可能只是“尝试更长的超时;考虑使用即发即弃”。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

与 StackExchange.Redis 并行执行? 的相关文章

  • 求 a 范围内的 pow(a^b)modN

    对于给定的b and N以及一系列a say 0 n 我需要找到ans 0 n 1 where ans i 没有a s为此pow a b modN i 我在这里搜索的是可能的重复pow a b modN对于一系列a 以减少计算时间 例子 i
  • 在宏中使用 # [重复]

    这个问题在这里已经有答案了 请解释一下代码 include
  • 多态性中基类缺少虚拟析构函数 = 资源泄漏?

    我们知道 如果要多态地使用基类 则需要将基类的析构函数指定为 virtual 否则程序中可能会出现资源泄漏 因为只会调用基类析构函数 而不会调用派生对象析构函数 我们还知道构造函数 析构函数纯粹是初始化 未初始化构造 而operator n
  • VS2010中VSHost.exe不断启动

    我正在 VS2010 中使用一个包含大量项目的解决方案 但它不断变得无响应 我注意到的一件事可能是一条线索 尽管我尚未开始任何调试 但 MyApplicationName vshost exe 不断出现在进程列表中 也许每当构建发生时它就会
  • ObjectTrackingEnabled 和 linq-to-sql

    I read here http www sidarok com web blog content 2008 05 02 10 tips to improve your linq to sql application performance
  • 如果 .txt 文件不存在,则创建一个,如果存在则追加新行

    我想创建一个 txt 文件并写入它 如果该文件已经存在 我只想添加更多行 string path E AppServ Example txt if File Exists path File Create path TextWriter t
  • 持续运行的 C# 代码 - 服务还是单独的线程?

    我有一个 NET 4 Web 应用程序 它有 3 个关联的独立项目 DAL BAL 和 UI 我正在使用实体框架进行数据库交互 我有代码循环遍历一堆数据库数据 根据找到的内容调用方法 然后更新数据库 我希望这段代码一直运行 同时 我希望用户
  • 如何让 PCRE 与 C++ 一起使用?

    这是一个新手问题 但我希望我能尽可能清楚地表达我的问题 我正在尝试用 C 进行模式匹配 我已经从以下位置下载了 PCRE 的 Win32 版本here http gnuwin32 sourceforge net packages pcre
  • 实体框架中的导航属性是什么

    我是实体框架的新手 当Visual Studio创建模型图时我们主要可以看到Entities Propertie和Navigation Properties这两个东西 那么这些Navigation Properties是什么 如何使用它们
  • 链接错误:xxx 已在 *****.LIB 中定义:: 究竟出了什么问题?

    Problem 我正在尝试使用一个名为DCMTK http dicom offis de dcmtk它使用了一些其他外部库 zlib libtiff libpng libxml2 libiconv 我已经从同一网站下载了这些外部库 LIB
  • Subsonic 3 ActiveRecord 嵌套选择导致 NotIn 错误?

    我有以下 Subsonic 3 0 查询 其中包含嵌套的 NotIn 查询 public List
  • 如何进行平衡组捕获?

    假设我有这个文本输入 tes tR R abc aD mnoR xyz 我想提取 ff 输出 R abc R xyz D mnoR xyz R R abc aD mnoR xyz 目前 我只能使用平衡组方法提取组内的内容 如中所示msdn
  • 是否可以在 Eclipse 中为除 Java 之外的 Eclipse 编写插件?

    谁能帮我用c 写一个eclipse插件 weekens 和 celavek 感谢您提供的信息 我正在研究 JNI 并将尝试实现它 celavek 我们必须做什么样的主控 控制 在C 和java接口中处理是否风险更大 我的要求是在 Java
  • 由于表扫描,表值参数的性能较低

    我有一个将参数传递给 SQL 过程的应用程序 其中一个参数是表值参数 其中包含要包含在 where 子句中的项目 因为当我将 TVP 连接到具有 200 万行的表时 表值参数没有附加任何统计信息 所以查询速度非常慢 我还有什么选择 同样 目
  • Task.Delay 到底是如何工作的?

    他们说 Task Delay 是一个异步 Thread Sleep 为了测试这一点 我写了下面的代码 我希望立即打印 One 然后 3 秒后将打印结果变量 15 2 秒后 将打印 Two 但似乎并非如此 一 不会立即打印 3 秒后打印 On
  • 64 位随机生成器种子

    我目前正在运行一个具有 8 个以上管道 线程 的多线程模拟应用程序 这些管道运行非常复杂的代码 该代码取决于种子生成的随机序列 然后该序列被归结为单个 0 1 我希望在将种子从主线程传递到处理管道后 这种 随机处理 具有 100 的确定性
  • 为什么变量 1 += 变量 2 比变量 1 = 变量 1 + 变量 2 快得多?

    我继承了一些 Python 代码 用于创建巨大的表 最多 19 列宽 5000 行 花了九秒用于在屏幕上绘制表格 我注意到每一行都是使用以下代码添加的 sTable sTable n GetRow where sTable是一个字符串 我将
  • 预览MouseMove 与 MouseMove

    我有相当多的 XAML 经验 但最近我注意到我的大多数同事都使用预览鼠标移动代替鼠标移动事件 我一直用鼠标移动它对我很有帮助 但我忍不住问我什么时候应该使用预览鼠标移动什么时候鼠标移动 有什么区别 各自有什么优点和缺点等等 PreviewM
  • 从不同的线程访问对象

    我有一个服务器类 它基本上等待来自客户端的连接 在该类中 我创建了一个 NetworkStream 对象 以便能够从客户端接收字节 由于 NetworkStream Read 方法不是异步的 这意味着它将等到从客户端读取字节才能继续执行类似
  • 如何从与 C# lambda 集成(而非代理集成)的 Amazon API 网关获取正确的 http 状态代码?

    我正在使用 C lambda 与 API 网关集成 我希望 API 网关返回正确的错误代码 例如 400 404 500 等 API网关模块tf文件 provider aws version lt 2 70 0 region var aws

随机推荐