【问题标题】:Shared java HashMap in a clustered environment集群环境中的共享 java HashMap
【发布时间】:2015-04-01 14:45:56
【问题描述】:

我有一个客户端应用程序每 1 秒从一个 url 请求一些信息。

在服务器(一个servlet & JSP 应用程序)中,为了避免不必要的DB 访问,实现了下一个解决方案。这是一个sn-p:

//a static HashMap where we save the last record inserted in db
public static Map<Long, Long> VALUES = new HashMap<Long, Long>(); 

// A lastRecordRead sent by the client 
if (VALUES.get(id) != lastRecordRead) {     
    //Access the database to get some information 
    //cause the last value read is different from the last record inserted
    ...
}else{
    //Do nothing
    //It's not necessary access DB cause the parameters match
}

这在开发环境中按预期工作。

当我们有一个集群环境时,问题就来了。我们将服务器部署在两个节点中(使用 jboss),每个节点都有自己的 HashMap 和自己的值。所以根据我们攻击的节点,我们可以 获取不同的值...

¿有没有办法在两个节点之间共享这个 HashMap?我正在寻找一些不需要更新 2 个地图的答案,这意味着不需要在节点之间调用...

我们将不胜感激。

编辑:我现在正在玩 HazelCast,它看起来很容易,我担心我做错了什么......

在我的服务器中,我现在使用 HazelCast 而不是 HasMap:

public static Map<Long, Long> VALUES = (Hazelcast.newHazelcastInstance(new Config())).getMap("VALUES"); 

插入记录时:

        if (((VALUES.get(id) == null)||(VALUES.get(id) < lastIdInserted))) {
            VALUES.put(id, lastIdInserted);     
        }

当客户端应用调用服务器时:

// A lastRecordRead sent by the client 
if (VALUES.get(id) != lastRecordRead) {     
    //Access the database to get some information 
    //cause the last value read is different from the last record inserted
    ...
}else{
    //Do nothing
    //It's not necessary access DB cause the parameters match
}

我认为,仅此而已。任何人都可以确认这是否可以或我错过了什么..?这个解决方案是否真的遍布所有节点?我一直在用 2 个 tomcat 进行测试,它确实有效,但它可以与不同的 ips 一起工作吗?

【问题讨论】:

    标签: java production-environment


    【解决方案1】:

    你有两个选择:

    1. 使用一些分布式键值,例如: http://memcached.org/

    http://infinispan.org/about/

    http://basho.com/riak/

    http://hazelcast.org/

    ...还有很多其他的。

    1. 使用“发布者-订阅者”概念并通过事件更新每个 HashMap 实例。这通常通过一些 JMS 代理来实现:

      http://docs.oracle.com/cd/E19717-01/819-7759/aerbk/index.html https://www.rabbitmq.com/tutorials/tutorial-three-java.html

    选择取决于您的需求:对于最快的读取和查找,没有网络延迟但更新缓慢 - 使用第二个选项。对于不经常更改的数据,这是一个很好的解决方案:地名、地址等。

    一般情况下 - 使用拳头。

    【讨论】:

    • 我想我要试试memcached。如果它有效,我会接受正确的答案。不过,sn-p 将不胜感激......非常感谢!
    • 查看这篇文章javaworld.com/article/2078584/open-source-tools/… 还有一些代码示例。
    • 再次感谢。我使用jdbc而不是hibernate,但这无论如何都会有所帮助......据我所知,在阅读了互联网上的一些文章之后,似乎为了使用memcached,您需要安装服务器应用程序并且除了客户端... 它是否正确?在这种情况下,使用 Halzelcast 等其他选项对我来说似乎是一个更好的选择......
    • 是的,但是您询问的是分布式解决方案,而不是嵌入式解决方案,因此需要一些外部服务器,不管是 Memcached 还是 Halzelcast 或其他什么的。
    • 我不确定我是否没有正确理解解决方案,或者我没有很好地解释我的情况。问题是我只需要服务器访问这个“共享”地图来决定我是否需要去数据库。在生产环境中,有 2 个节点部署了相同的应用程序(我猜它是同一台物理机器,但它不在我的控制之下)我的客户端会询问其中一个节点服务器,这应该检查地图中插入的最后一条记录。如果它与客户端的最后一次读取不同,它会转到数据库...
    【解决方案2】:

    您需要使用分布式HashMap。那里有一些框架。 hazelcast 就是一个例子。您可以使用 Hazelcast 社区版(免费)。

    您也可以使用 Redisson(分布式计算):https://github.com/mrniko/redisson

    【讨论】:

    • 我正在尝试这种方法。我会告诉你。你能给我看一些sn-p或相关的文章吗?非常感谢!
    • 你应该看看 hazelcast 文档。
    • 我现在正在做。谢谢! ;)
    【解决方案3】:

    您确定访问数据库是您负担不起的开销吗?如果您使用数据库,那么您可以确保正确处理锁定和并发访问。使用 HashMap 意味着您必须自己处理并发读写访问,这可能会大大增加您的设计、构建和测试工作。

    您确定这不是过早的优化吗?

    【讨论】:

    • 会有很多客户端应用程序请求一些信息,所以这是必要的。此外,这是客户的必需品;)
    猜你喜欢
    • 2012-09-12
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多