代码之家  ›  专栏  ›  技术社区  ›  lud0h

集群环境中的单例

  •  43
  • lud0h  · 技术社区  · 17 年前

    将单例对象重构为集群环境的最佳策略是什么?

    我们使用singleton从数据库中缓存一些自定义信息。它的 主要地 只读,但在某些特定事件发生时刷新。

    现在,我们的应用程序需要部署在集群环境中。根据定义,每个JVM都有自己的单例实例。因此,当刷新事件发生在单个节点上并且刷新了其缓存时,JVM之间的缓存可能不同步。

    保持缓存同步的最佳方法是什么?

    谢谢。

    编辑:缓存主要用于向UI提供自动完成列表(性能原因),我们使用WebSphere。所以欢迎使用任何与WebSphere相关的提示。

    9 回复  |  直到 14 年前
        1
  •  9
  •   pjp    17 年前

    最简单的方法是:

    1. 向单实例缓存中添加一个到期计时器,以便每隔一段时间清除一次缓存,然后子后续调用从源(例如数据库)中获取更新的数据。

    2. 使用类似于JMS主题/TIBRV的东西实现缓存的通知机制。获取每个缓存实例以订阅和响应在此主题上广播的任何更改消息。

        2
  •  16
  •   Chris Vest    17 年前

    将单实例缓存替换为分布式缓存。

    一个这样的缓存可以是 JBoss Infinispan 但我敢肯定还有其他分布式缓存和网格技术,包括商业技术,目前可能更成熟。

    对于一般的单例对象,我不确定。我想一开始我会尽量不要单件的。

        3
  •  8
  •   Rick    17 年前

    你可以用 DistributedMap 这是建立在过去。

    -里克

        4
  •  4
  •   monkey_p    17 年前

    或者类似memcached的东西

    http://www.danga.com/memcached/

    什么是memcached?MycCask是 高性能分布式内存 对象缓存系统,通用 性质,但用于 加速动态Web应用程序 通过减轻数据库负载。

    Danga Interactive开发的memcached 以提高 LiveJournal.com,一个 已经做了2000多万动态页面 每天100万用户的浏览量 一堆网络服务器和一堆 数据库服务器。已删除memcached 数据库加载到几乎为零, 为提供更快的页面加载时间 用户,更好的资源利用率, 以及更快地访问 Memcache未命中。

        5
  •  1
  •   skaffman    17 年前

    如果可能的话,使用应用服务器对此的支持,如果可能的话(有的有,有的没有)。例如,我们使用JBoss对“ha singleton”的支持,该服务只在集群主节点上运行。这并不完美(你必须处理偶尔会让大脑放屁的情况),但这已经足够好了。

    如果不能做到这一点,您可能可以使用jgroups来设计一些东西,jgroups提供集群节点自动发现和协商,但这并不简单。

    最后,您可以使用数据库锁定来管理集群单例,但这是 认真地 脆弱的。不推荐。

    作为集群单例的替代方案,您可以使用分布式缓存。我推荐 JBossCache (不需要运行jboss应用服务器)或ehcache(现在提供了分发机制)。您必须重新设计缓存才能以分布式方式工作(这不仅仅是奇迹般的工作),但它可能比集群单例更好。

        6
  •  1
  •   Chris K    17 年前

    我和维斯特·汉森先生在一起,尽可能远离单身汉。在经历了saaj和jaxp这样的噩梦,以及jboss上兼容的版本之后,我已经完成了对singleton和工厂的工作。SOAP消息不需要工厂来实例化它。

    好吧,怒吼一下,Memcache或者类似的东西呢?您的缓存需要什么样的亲和力?如果数据过时了,会不会很糟糕,或者在数据过时的情况下是否有一定的灵活性?

        7
  •  1
  •   BatchyX    17 年前

    有几种方法可以处理这一问题,具体取决于1)数据的不足程度,以及2)每个实例是否始终需要具有相同的值。

    如果您只需要符合数据要求的数据,但每个JVM都不需要具有匹配的数据,那么您可以让每个JVM按照相同的计划刷新其数据(例如,每30秒刷新一次)。

    如果刷新需要同时进行,可以让一个JVM向其余的JVM发送一条消息,说“现在该刷新了”。

    如果每个JVM总是需要相同的信息,那么您需要进行同步,此时主机会说“立即刷新”,所有缓存都会阻止任何新的查询,刷新,并告诉主机它们已经完成了。当主服务器从集群的每个成员那里得到一个应答时,它会发送另一条消息,指示继续。

        8
  •  1
  •   XpiritO    16 年前

    我也面临同样的情况,但我正在使用Oracle的 应用服务器 一致性 .

    我正在研究一个使用 散列表 从数据库中读取缓存数据(要显示的文本 网络表单 标签。为了实现这一点,开发人员使用了一个单实例来存储所有这些信息。这在单服务器环境中工作得很好,但是现在我们要进入集群解决方案,我将在这个单例实例中面临这个问题。

    从我现在读到的, this is the best solution to accomplish what I want . 我希望这也能帮助你解决你的问题。

        9
  •  0
  •   Yishai    17 年前

    在这种情况下,有一些产品可以提供分布式内存缓存(如memcache)。

    如果可能的话,一个更好的解决方案可能是让单例不是真正的单例,而是让应用程序能够容忍有单独的实例(比如所有实例都可以在需要刷新时识别),而不是让它们必须在JVM之间保持同步,这会使您的缓存成为瓶颈。