仅在部署的服务上在所选节点上分发IgniteCache分区

时间:2016-10-17 15:32:30

标签: java apache ignite

我正在运行一个Apache Ignite集群,其中包含各种提供服务的节点。为每个节点分配一个特定的服务组(自定义节点属性),描述该节点正在提供的服务,例如,授权,付款,......

其中一些服务正在使用Ignite Cache,但我希望仅在关联的服务节点上部署这些特定于服务的缓存。所以我在缓存配置中添加了一个节点过滤器:

// configuration with custom attribute is provided at node start up
IgniteConfiguration nodeConfig = new IgniteConfiguration();
Map<String,String> nodeAttributes = Collections.singletonMap("role", "MyService");
nodeConfig.setUserAttributes(nodeAttributes);

CacheConfiguration cfg = new CacheConfiguration<>("MyServiceCache");
cfg.setNodeFilter((node) -> node.attribute("role") == nodeConfig .getUserAttributes().get("role"));

缓存部署按预期工作(至少没有显示错误)。但是,当我添加提供相同服务的第二个节点时(出于缩放的原因),会显示一个日志条目:

No server nodes found for cache client: MyServiceCache

一旦我停止第二个节点,就会显示另一条日志消息:

[17:26:29] Topology snapshot [ver=9, servers=1, clients=0, CPUs=4, heap=1.7GB]
[17:26:29] All server nodes for the following caches have left the cluster: 'MyServiceCache'
[17:26:29] Must have server nodes for caches to operate.

据我所知,第一个节点仍应提供服务和缓存。所以这些消息对我来说没什么意义。有人可以详细说明吗?

这是一个具体的例子:

  • 运行MyService.java两次或更多次
  • 停止第一个节点
  • 观看第二个节点的日志输出

NodeConfig.java

public class NodeConfig {

    public static IgniteConfiguration myServiceNode()
    {
        IgniteConfiguration nodeConfig = new IgniteConfiguration();
        Map<String,String> nodeAttributes = Collections.singletonMap("role", "myService");
        nodeConfig.setUserAttributes(nodeAttributes);
        return nodeConfig;
    }

}

CacheConfig.java

public class CacheConfig {

    public static CacheConfiguration<Long, String> myServiceCache() {

        CacheConfiguration<Long, String> cfg = new CacheConfiguration<>("MyServiceCache");

        cfg.setBackups(2);

        cfg.setNodeFilter((node) -> node.attribute("role") == NodeConfig.myServiceNode().getUserAttributes().get("role"));

        return cfg;
    }

}

MyService.java

public class MyService implements Service {

    @IgniteInstanceResource
    private Ignite ignite;
    private IgniteCache cache;

    @Override
    public void cancel(ServiceContext serviceContext) {
        System.out.println("Service " + serviceContext.name() + " cancelled.");
    }

    @Override
    public void init(ServiceContext serviceContext) throws Exception {
        System.out.println("Service " + serviceContext.name() + " initialized.");
    }

    @Override
    public void execute(ServiceContext serviceContext) throws Exception {

        CacheConfiguration config = CacheConfig.myServiceCache();
        cache = ignite.getOrCreateCache(config).withExpiryPolicy(new CreatedExpiryPolicy(Duration.ONE_MINUTE));

        System.out.println("Service " + serviceContext.name() + " executing.");
    }

    public static void main(String[] args) {

        Ignite ignite = Ignition.start(NodeConfig.myServiceNode());

        IgniteServices svcs = ignite.services(ignite.cluster().forAttribute("role", NodeConfig.myServiceNode().getUserAttributes().get("role")));

        svcs.deployNodeSingleton("MyService", new MyService());

    }

}

1 个答案:

答案 0 :(得分:0)

您不应使用==来比较属性值。这种情况很好:

cfg.setNodeFilter((node) -> Objects.equals(node.attribute("role"), NodeConfig.myServiceNode().getUserAttributes().get("role")));