集群/分发 Java 服务器应用程序的最佳方法是什么?我正在寻找一种允许您通过添加更多应用程序服务器和更多数据库服务器来水平扩展的方法。
- 您建议使用哪些技术(软件工程技术或特定技术)来解决此类问题?
- 您使用哪些技术来设计持久层以扩展到许多读取器/写入器 扩展应用程序事务并扩展对共享数据的访问(最好的方法是消除共享数据;您可以应用哪些技术来消除共享数据)。
- 根据您的事务是读取还是写入繁重,似乎需要不同的方法,但我觉得您是否可以优化“写入”繁重的应用程序,该应用程序对于“读取”也很有效
“最佳”解决方案将允许您为单个节点编写 Java 应用程序,并希望“隐藏”访问/锁定共享数据的大部分细节。
在分布式环境中,最困难的问题总是归结为让多个事务访问共享数据。似乎有两种常见的并发事务方法。
- 显式锁(极易出错且在分布式系统中跨多个节点协调缓慢)
- 软件事务内存(STM) AKA 乐观并发,如果事务发现共享状态已更改(并且事务可以稍后重试),则在提交期间回滚事务。哪种方法可以更好地扩展,分布式系统中的权衡是什么?
我一直在研究扩展解决方案(以及提供如何扩展示例的一般应用程序),例如:
- Terracotta - 通过使用 Java 的并发锁定机制(同步,ReentrantReadWriteLocks)扩展 Java 内存模型以包含分布式共享内存,从而提供“透明”缩放。
- Google App Engine Java - 允许您编写 Java(或 python)应用程序,这些应用程序将分布在“云”服务器中,您可以在其中分发处理事务的服务器,并使用 BigTable 存储持久数据(不确定访问共享的事务的方式数据或句柄锁争用能够有效地扩展)
- Darkstar MMO 服务器- Darkstar 是 Sun 的开源 MMO(大型多人在线)游戏服务器,它们以线程事务方式扩展事务,允许给定事务仅运行一定数量并提交,如果需要很长时间,它将回滚(有点像软件事务内存)。他们一直在研究支持多节点服务器设置以进行扩展。
- Hibernate 的乐观锁定- 如果您使用 Hibernate,您可以使用他们的乐观并发支持来支持软件事务内存类型行为
- Apache CouchDB应该自然地“扩展”到网格配置中的许多读写器数据库。(有没有一个很好的例子来说明如何管理锁定数据或确保事务隔离?):
- JCache - 通过将结果缓存到您可以在 Google appengine 中使用来访问 memcached 并缓存其他经常读取的数据的常见查询,来扩展“读取”繁重的应用程序。
Terracotta 似乎是最完整的解决方案,因为您可以“轻松”修改现有服务器应用程序以支持缩放(在定义 @Root 对象和 @AutoLockRead/Write 方法之后)。问题是要真正从分布式应用程序中获得最大的性能,分布式系统的优化并不是事后才想到的,你必须在设计它时知道对象访问可能会被网络 I/O 阻塞。
为了正确扩展,它似乎总是归结为分区数据和负载平衡事务,以便给定的“执行单元”(cpu 核心 -> 线程 -> 分布式应用程序节点 -> 数据库主节点)
似乎要通过集群使任何应用程序正确扩展,您需要能够根据数据访问读取/写入对事务进行分区。人们提出了哪些解决方案来分发他们的应用程序数据(Oracle、Google BigTable、MySQL、数据仓库),以及通常如何管理分区数据(许多写入主机,具有更多读取数据库等)。
在扩展您的数据持久层方面,哪种类型的配置在将您的数据分区到许多读者/许多作者方面表现最好(通常我会根据给定用户(或通常是您的任何核心实体)对我的数据进行分区“根”对象实体)由单个主数据库拥有)