我在Solaris上有一个混合了Java和C++的应用程序。代码的Java方面运行web并在与我们交谈的设备上建立状态,C++代码对从设备返回的数据进行实时处理。共享内存用于将设备状态和上下文信息从Java代码传递到C++代码。Java代码使用PostgreSQL数据库来持久化其状态。
我们遇到了一些非常严重的性能瓶颈,现在我们唯一可以扩展的方法是增加内存和CPU数量。由于共享内存的设计,我们被困在一个物理盒子上。
真正大受欢迎的是C++代码。web接口用于配置设备相当轻松;我们真正挣扎的地方是处理设备一旦配置后交付的数据卷。
我们从设备返回的每一个数据都有一个标识符,它指向设备上下文,我们需要查找它。现在有一系列由Java/UI代码维护并由C++代码引用的共享内存对象,这是瓶颈。由于该体系结构,我们不能将C++数据处理移到另一台计算机上。我们需要能够扩展,以便不同的机器可以处理不同的设备子集,但是这样我们就失去了进行上下文查找的能力,这就是我试图解决的问题:如何将实时数据处理卸载到其他框,同时仍然能够引用设备上下文。
我应该指出,我们无法控制这些设备本身使用的协议,这种情况不可能发生改变。
我们知道,我们需要摆脱这种情况,才能通过向集群中添加更多的机器来进行扩展,而我现在还处在研究我们将如何做到这一点的早期阶段。
现在我正在研究Terracotta作为扩展Java代码的一种方法,但是我还没有想出如何扩展C++来匹配它。
除了扩展性能外,我们还需要考虑高可用性。应用程序需要在几乎所有的时间都是可用的--不是绝对的100%,这是不符合成本效益的,但是我们需要做一个合理的工作来从机器故障中幸存下来。
如果你必须承担我的任务,你会怎么做?
编辑:基于@john提供的数据,我同时查看了GigaSpaces和Gemstone。Oracle和IBM ObjectGrid似乎仅限于java。
发布于 2008-09-09 09:00:54
我要做的第一件事是构建一个系统模型,以映射数据流,并试图准确地了解瓶颈所在。如果您可以将您的系统建模为管道,那么您应该能够使用约束理论(大多数文献都是关于优化业务流程,但它同样适用于软件),以不断提高性能并消除瓶颈。
接下来,我将收集一些可靠的经验数据,准确地描述系统的性能。这是一个陈词滥调,你不能管理你不能衡量,但我看到许多人试图优化一个软件系统的基础上的预感,并悲惨地失败。
然后,我会使用帕累托原则(80/20规则)来选择少数能够产生最大收益的东西,并且只关注那些。
为了在水平上扩展Java应用程序,我广泛地使用了Oracle一致性。尽管有些人认为它是一个非常昂贵的分布式哈希表,但功能要丰富得多,例如,您可以从C++代码直接访问缓存中的数据。
水平缩放您的Java代码的其他选择是Giga空间、IBM对象网格或宝石宝石宝石。
如果您的C++代码是无状态的,并且完全用于数字处理,那么您可以考虑使用冰栅分发流程,它为您使用的所有语言都提供了绑定。
发布于 2008-09-09 06:05:04
你需要从侧面爬出去。也许像消息队列这样的东西可以成为前端和嘎吱嘎吱之间的后端。
发布于 2008-09-09 12:29:07
Andrew (除了建模为管道等),测量事物是很重要的。您是否在代码中运行了分析器,并获得了大部分时间是在哪里度过的?
对于数据库代码,多久更改一次?您现在正在考虑缓存吗?我想您已经查看了索引等数据,以加快Db?
你的前端有多大的流量?你在缓存网页吗?(可以说,使用JMS类型api在组件之间进行通信并不难。然后,您可以将Web组件放在一台计算机(或多台计算机)上,然后将集成代码( C++ )放在另一台机器上,对于许多C++产品,通常都有本机JMS的ie。ActiveMQ ),但是知道在Web (JSP ?)、C++、数据库操作中有多少时间是非常有帮助的。
数据库是存储业务数据,还是也用于在Java和C++之间传递数据?你说你用的是共享的我而不是JNI?应用程序中当前存在的多线程级别是什么?您认为代码本质上是同步的还是异步的?
Solaris代码与必须维护的设备之间是否存在物理关系(即。是否使用c++代码注册所有设备,或指定哪些设备)。即。如果你把一个网络负载均衡器放在前端,而今天只安装了2台机器,那么哪个设备是由一个预先初始化或预先初始化的盒子管理的呢?
医管局有甚麽要求?即。只是状态信息?HA能否仅在web层中通过对会话数据进行聚类来完成?
数据库在另一台机器上运行吗?
DB有多大?你的查询优化了吗?尝试使用显式内部/外部联接有时有助于与嵌套子查询(sometmes)相比较。(再次查看sql统计数据)。
https://stackoverflow.com/questions/51266
复制相似问题