【问题标题】:Apache Geode servers ocassionally run out of connections during load testsApache Geode 服务器在负载测试期间偶尔会耗尽连接
【发布时间】:2019-11-19 23:47:18
【问题描述】:

下午好,

我们正在尝试将应用程序从 Redis 迁移到 Geode 集群,以获得更好的可扩展性和多 WAN 同步。 目前我们只测试一个集群。设置是:

  • 8 台硬件服务器(64 核 CPU、256GB RAM、Debian Linux v9 Stretch)
  • 16 个 Geode 服务器,每个硬件主机 2 个 (v1.10.0)。我们使用 JDK8 和 CMSGC 进行了测试,但决定升级到 OpenJDK13 和 ShenandoahGC 以获得低暂停,因为它应该是一个超快的缓存

服务器设置:

--max-connections=1200 --J=-Xmx12G --J=-Xms12G --J=-XX:+UnlockExperimentalVMOptions
--J=-XX:+UseShenandoahGC --J=-XX:+DisableExplicitGC --J=-XX:+AlwaysPreTouch
--J=-Xlog:gc*:file=gc-%p-%t.log:uptime,time:filecount=3,filesize=10m --J=-Dgemfire.conserve-sockets=false
  • 4 个定位器
  • 5 个区域:
    • 4 PARTITION_REDUNDANT 和冗余副本 1(具有不同的 entry-time-to-live-expiration-s 从 1 小时到 7 天和 entry-time-to-live-expiration-action 销毁)
    • 1 REPLICATE,entry-time-to-live-expiration 7 天

在负载测试期间,我们间歇性地(每小时一次)在服务器日志中遇到此错误:

[info 2019/11/18 16:46:03.561 PST <Pooled Waiting Message Processor 20> tid=0x925b] ...
[warn 2019/11/18 17:30:46.363 PST <Handshaker /XX.XXX.XXX.XXX:10001 Thread 152> tid=0xaed1] Rejected connection from /XX.XXX.XXX.XXX because current connection count of 1200 is greater than or equal to the configured max of 1200
[warn 2019/11/18 17:30:46.363 PST <Handshaker /XX.XXX.XXX.XXX:10001 Thread 155> tid=0xb503] Rejected connection from /XX.XXX.XXX.XXX because current connection count of 1200 is greater than or equal to the configured max of 1200
...[hundreds of these messages]

在客户端:

org.apache.geode.cache.client.ServerRefusedConnectionException: servername(servername:28165)<v145>:41001 refused connection: exceeded max-connections 1200
    at org.apache.geode.internal.cache.tier.sockets.Handshake.readMessage(Handshake.java:331)
    at org.apache.geode.cache.client.internal.ClientSideHandshakeImpl.handshakeWithServer(ClientSideHandshakeImpl.java:232)
    at org.apache.geode.cache.client.internal.ConnectionImpl.connect(ConnectionImpl.java:102)
    at org.apache.geode.cache.client.internal.ConnectionConnector.connectClientToServer(ConnectionConnector.java:71)
    at org.apache.geode.cache.client.internal.ConnectionFactoryImpl.createClientToServerConnection(ConnectionFactoryImpl.java:111)
    at org.apache.geode.cache.client.internal.pooling.ConnectionManagerImpl.createPooledConnection(ConnectionManagerImpl.java:202)
    at org.apache.geode.cache.client.internal.pooling.ConnectionManagerImpl.forceCreateConnection(ConnectionManagerImpl.java:212)
    at org.apache.geode.cache.client.internal.pooling.ConnectionManagerImpl.borrowConnection(ConnectionManagerImpl.java:319)
    at org.apache.geode.cache.client.internal.pooling.ConnectionManagerImpl.borrowConnection(ConnectionManagerImpl.java:70)

客户端代码:

        ClientCacheFactory cacheFactory = new ClientCacheFactory()
                .set("log-level", "ERROR");
        for (String locator : locators) {
            HostPort hostPort = new HostPort(locator);
            cacheFactory.addPoolLocator(hostPort.getHost(), hostPort.getPort());
        }
        this.cache = cacheFactory.create();

然后

    private <K,V> Region<K, V> getOrCreateRegion(String name, ClientRegionFactory<K, V> regionFactory) {
        Region<K, V> region = cache.getRegion(name);
        if (region == null) {
            region = regionFactory.create(name);
        }
        return region;
    }

要获取区域,没有设置自定义选项。

每台服务器上的正常客户端连接数约为 250,但在负载测试期间的某个随机时间(60k 读取 RPS / 60k 写入 RPS) 连接数量跃升至最大值(1200),客户端无法打开连接。 分区区域具有“分布式确认”范围,这会导致大量错误和数据损坏。 服务器在一两分钟内自我修复,连接数下降到正常,但到那时测试失败。 我尝试提高日志级别,但“INFO”什么也没显示(检查受影响的服务器和定位器日志),“DEBUG”生成了太多数据,服务器无法跟上大量的日志消息。 120k 读写 RPS 对我们来说是正常的生产流量,以 10k 整体 RPS 进行测试并没有导致异常。这些锁定与垃圾收集无关,因为 gc 日志显示在那段时间没有 gc 运行

您对如何调整 Geode 集群以避免这些异常和数据损坏有任何想法吗?

【问题讨论】:

    标签: java geode


    【解决方案1】:

    发生此“拒绝连接:超出最大连接数”错误的原因是客户端尝试创建的与服务器的连接数超过了您设置的最大连接数。

    客户端使用连接池,因此来自单个客户端的并发连接数与当前正在从客户端执行操作的线程数成正比。

    下一步是计算负载生成实际创建了多少线程。从理论上讲,每个线程一次应该只使用一个连接,因此如果负载非常不均匀并且所有客户端同时针对同一服务器,最大连接数的最坏情况应该是 num_threads * num_clients 左右。

    如果您无法控制客户端上的线程数,则池本身具有调整参数,例如 PoolFactory.setMaxConnections 将限制来自单个客户端的连接数。

    【讨论】:

    • 非常感谢丹的想法。连接到 Geode 的客户端是 Web 应用程序,因此线程数量主要受 Jetty 连接池的限制,但某些工作流可能会使用多个线程。我将使用客户端池设置。
    猜你喜欢
    • 2013-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多