首页 > 解决方案 > Apache Ignite 缓存为空,表有值

问题描述

我有一个基本的 Ignite 持久性设置工作。目前,它是在服务器模式下运行的单个节点,我从中连接两个客户端。当我通过 SQL 从这些客户端之一(下面的“客户端 1”)插入数据时,我可以使用 SQL 再次选择它并返回结果。从下面的“客户端 2”中,当我尝试获取应该创建来表示此表的缓存时,它为空。

服务器使用以下 Dockerfile 运行 apacheignite 映像:

服务器/Dockerfile:

FROM apacheignite/ignite

# for jdbc connection
EXPOSE 10800

EXPOSE 47100-47109
EXPOSE 47500-47509

# for rest api
EXPOSE 8080

WORKDIR /app

COPY ./config /app/config

RUN mv /opt/ignite/apache-ignite/libs/optional/ignite-aws /opt/ignite/apache-ignite/libs/

RUN mv /opt/ignite/apache-ignite/libs/optional/ignite-rest-http /opt/ignite/apache-ignite/libs/

CMD /opt/ignite/apache-ignite/bin/ignite.sh /app/config/ignite-config.xml -v

这里引用的相关部分ignite-config.xml如下:

/app/config/ignite-config.xml

<bean class="org.apache.ignite.configuration.IgniteConfiguration">
        <property name="dataStorageConfiguration">
            <bean class="org.apache.ignite.configuration.DataStorageConfiguration">
                <property name="defaultDataRegionConfiguration">
                    <bean class="org.apache.ignite.configuration.DataRegionConfiguration">
                        <property name="persistenceEnabled" value="true"/>
                    </bean>
                </property>
            </bean>
        </property>
        <property name="discoverySpi">
            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                <property name="ipFinder">
                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                        <property name="addresses">
                            <list>
                                <value>127.0.0.1:47500..47509</value>
                            </list>
                        </property>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>

我还确保在 Server 容器上激活集群,因为 Persistence 默认情况下将集群设置为非活动状态。

/opt/ignite/apache-ignite/bin/control.sh --activate

客户 1

客户端 1 通过瘦 JDBC 驱动程序连接并执行一些CREATE TABLEs 和INSERTs。当我稍后SELECT在 DBeaver 之类的东西中时,我可以看到这些数据。

这个客户端也运行在 docker 中,与 Compose 中的另一个一起运行。它实际上所做的只是在循环中调用以下内容,其中$file是一个包含CREATE TABLEINSERTs 等的 SQL 文件。

/opt/ignite/apache-ignite/bin/sqlline.sh -u jdbc:ignite:thin://server:10800 -f $file;

一个这样的 SQL 文件如下所示:

DROP TABLE IF EXISTS attributes;
DROP INDEX IF EXISTS idx_attributes_token;

CREATE TABLE attributes (
    token VARCHAR,
    attributeId LONG,
    name VARCHAR,
    PRIMARY KEY(token, attributeId)
) WITH "affinityKey=token";

CREATE INDEX idx_attributes_token ON attributes (token);

INSERT INTO attributes (token, attributeId, name) VALUES ('abc123', 123, 'some name');

客户 2

客户端 2 或多或少地连接到 Ignite,如下所示:

IgniteConfiguration igniteConfiguration = new IgniteConfiguration();
TcpDiscoverySpi discoverySpi = new TcpDiscoverySpi();
TcpDiscoveryMulticastIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();

ipFinder.setAddresses(igniteConfig.getAddresses()); // will be "localhost:10800" -- I map 10800:10800 when the "Server" container runs

discoverySpi.setIpFinder(ipFinder);
igniteConfiguration.setDiscoverySpi(discoverySpi);

Ignite ignite = Ignition.start(igniteConfiguration);

IgniteCache<Object, String> attributesCache = ignite.cache("SQL_PUBLIC_ATTRIBUTES"); // null

//  if i use ignite.getOrCreateCache("SQL_PUBLIC_ATTRIBUTES") instead then of course it's a cache of size 0.

最终,我希望能够抓住这个缓存并使用StreamVisitorIgnite 文档中描述的内容对每个缓存执行操作。据称,这看起来像:

... 
IgniteDataStreamer<Object, AttributeWithGroup> attributeStreamer = ignite.dataStreamer(attributesCache.getName());

attributeStreamer.receiver(StreamVisitor.from((cache, entity) -> {
    Object key = entity.getKey();
    Attribute attribute = entity.getValue();
    // do some stuff
}));

...但是 lambda 永远不会运行,因为缓存为空。

为什么我在 SQL 中看到的内容与在缓存中看到的内容之间存在这种脱节?

标签: dockerignite

解决方案


他们以您的方式启动“客户端 2”,它将作为没有缓存的单个服务器节点启动。

您还应该将 47500 用于发现端口,而不是 10800。10800 用于瘦客户端。

另请注意,您的 IpFinder、Vm 与多播不匹配。


推荐阅读