如何提高股票数据传输应用程序的性能?

时间:2011-10-18 18:52:47

标签: java performance

这是我已经工作了几年的问题,但现在我仍然没有得到一个好的解决方案。

我的申请有两个部分:

  1. 第一个是在名为“ROOT服务器”的服务器上运行。它将从香港交易所(香港证券及期货交易所)收到实时股票数据,并将其广播至其他5家儿童服务器。它将在广播时为每个数据项附加时间戳。

  2. 第二个正在“子”服务器中运行。他们将从ROOT服务器接收库存数据,解析每个库存数据,并获取重要信息。最后,他们将以新的文本格式将它们发送给客户。客户可能是数百到数千,他们可以注册某种股票,并获得他们的实时信息。

  3. 表现是最重要的。在过去的几年里,我尝试了各种解决方案,以加快速度。这里的“更快”意味着,第一个将尽可能快地接收数据并将数据发送到子服务器,子服务器将尽可能快地接收和解析数据并将数据发送给客户端。

    目前,当HKEx的数据速度为200K并且有5个子服务器时,第一个应用程序平均每个数据项的延迟时间为10ms。第二个不容易测试,这取决于客户数量。

    我正在使用的是什么:

    1. OpenSUSE 10
    2. Sun Java 5.0
    3. Mina 2.0
    4. 服务器硬件:

      1. 4核CPU(我不知道类型)
      2. 4G ram
      3. 我正在考虑如何改善表现。

        1. 我是否需要将并发框架用作akka
        2. 尝试另一种语言,例如Scala呢? C ++?
        3. 使用real-time java system
        4. 你的建议......
        5. 需要你的帮助!


          更新:

          应用程序已经记录了一些重要的信息用于分析,但我没有发现任何瓶颈。香港交易所将在明年提供更多数据,我不认为我的申请会足够快。

          我的一位客户测试了我们的应用程序和另一家公司,但我们的速度没有优势。我只是想找到一种让它更快的方法。

          第一个应用程序如何运行

          第一个申请将从香港交易所收到股票数据,并将其广播到其他几个服务器。步骤是:

          1. 连接香港交易所
          2. 登录
          3. 读取数据。数据是二进制格式,每个项目都有一个头,这是2个字节的整数,表示正文的长度,然后是正文,然后是下一个项目。
          4. 将它们放入内存中的hashmap。 Key是项的序列,value是字节数组。
          5. 将每个收到的项目的顺序记录到磁盘中。使用log4j的buffer appender。
          6. 守护程序线程尝试从hashmap读取数据,并每隔1分钟将它们插入postgresql。 (这仅用于备份数据)
          7. 当客户端连接到此服务器时,它接受它们并尝试从内存中发送hashmap中的所有数据。我在mina中使用了线程池,接受器和发送器在不同的线程中。
          8. 我认为逻辑非常简单。当有5个客户端时,我监控的传输速度最多只有1.5M / s。我用java编写了一个最简单的socket程序,发现它可以是10M / s。

            实际上,我花了一年多的时间在这个应用程序上尝试各种解决方案,只是为了让它更快。这就是为什么我感到绝望。我是否需要尝试另一种语言而不是Java?


            约10毫秒延迟

            当申请人收到香港交易所的资料时,我会记录该资料的时间戳。当根服务器将数据广播到子服务器时,它会将时间戳附加到数据。

            当子服务器获取数据时,它会向根服务器发送一条消息以获取当前时间戳,然后比较它们。

            因此,10ms延迟包含:

            1. root server获取数据--->子服务器获取数据
            2. 子服务器发送对根服务器的时间戳的请求--->根服务器得到它
            3. 但第二个非常小,我们可以忽略它。

3 个答案:

答案 0 :(得分:4)

要找到性能瓶颈,首先要找出大部分时间花在哪里。确定这一点的一种方法是使用分析器。

有可用的开源分析器,例如http://www.eclipse.org/tptp/,或商业分析器,例如Yourkit Java Profiler。

一件简单的事情可能是将JVM升级到Java SE6或Java 7.一般JVM的性能在版本6上有了很大改进。有关更多详细信息,请参阅http://java.sun.com/performance/reference/whitepapers/6_performance.html

答案 1 :(得分:1)

要追踪延迟的来源,我会在您的端到端流程中添加时间数据。您可以使用外部日志或向邮件添加元数据来执行此操作。

您想要获得的是应用程序关键阶段的时间戳3-5就足够了。通常我会使用System.nanoTime(),因为我正在寻找微秒延迟,但在你的情况下,System.currentTimeMillis()可能就足够了,尤其是如果你对很多样本求平均值(你仍然可以获得0.1 ms的精度)平均而言,用Ubuntu)

比较通过系统时相同消息的时间戳,并查找最高的平均延迟。一旦找到这个尝试,请尝试将此间隔分成更多阶段以放大问题。

我会分析任何阶段,因为你的情况有超过1毫秒的超时延迟。

如果客户每分钟更新一次,可能没有很好的技术理由这样做,但你不希望被视为缓慢而你的交易员处于不利的地位,即使实际上它不会差。

答案 2 :(得分:1)

如果您检查了所有内容,但未发现明显的性能优化,则可能需要更改体系结构以获得更好的性能。如果你至少可以确定你的应用程序在哪里花费时间,这显然是最富有成果的 - 听起来有几个主要组成部分:

  • HK Ex服务器(不受您控制)
  • Exchange与您的系统之间的网络
  • “root”服务器
  • “root”和“child”服务器之间的网络
  • “子”服务器
  • “子”服务器与客户端之间的网络
  • 客户

要知道在哪里花费你的时间,金钱和精力,我至少希望看到对这些组件的分析,每个组件需要多长时间(最小值,最大值,平均值)以及每个资源的规范是什么。

最容易改变的是硬件 - 更大的服务器,更多的内存等,或更好的带宽。你能看出这些资源是否受到约束?

接下来要看的是改变通信协议以提高效率 - 客户如何获得股票?你能减少数据量吗?只有5个客户的1.5M听起来很多......

接下来,您可能会考虑某种服务质量解决方案 - 为“高级”客户提供专用硬件,减少资源争用,增加服务器数量,增加带宽 - 这可能需要更改架构。

接下来,您可以考虑更改架构 - 现在,您的客户端从客户端服务器“拉”数据。相反,您可以“推送”数据 - 这样,您可以减少客户端上的轮询间隔。

在列表的最后,我会考虑使用不同的技术堆栈; Java是一种很好的编程语言,但如果绝对性能是关键优先级,那么C / C ++仍然更快。显然,这是一个巨大的变化,编写良好的Java应用程序将比编写得不好的C / C ++应用程序更快(并且更加稳定)。