1

我有一个由 Java 客户端应用程序使用的 4 个节点的 Cassandra (2.2.1) 集群。复制因子为 3,读写一致性级别为 LOCAL_QUORUM。每个节点都有大约 5 GB 的数据。请求量约为每秒 2-4k。几乎没有删除操作,因此创建了少量的墓碑。

前段时间我注意到读写性能很差,而且随着时间的推移变得更糟——集群变得非常慢。读取(大多数情况下)和写入超时变得非常频繁。硬件应该不是问题,部署集群的服务器在磁盘性能,CPU和RAM资源方面确实很好。

我不清楚问题的原因,但我注意到几个可能指向根本原因的日志条目:

  1. Java 客户端应用程序日志中的异常堆栈跟踪:

    com.datastax.driver.core.exceptions.ReadTimeoutException:Cassandra 在读取查询期间以一致性 LOCAL_QUORUM 超时(需要 2 个响应,但只有 1 个副本响应)

有趣的是 1 个节点仍然响应。

  1. 失败提示错误的几个条目:

    无法重播 /1.1.1.1 的提示;正在中止(已交付 135922),错误:操作超时 - 仅收到 0 个响应。

  2. cassandra 日志中有以下几个异常:

    请求期间出现意外异常;channel = [id: 0x10fc77df, /2.2.2.2:54459 :> /1.1.1.1:9042] java.io.IOException: Error while read(...): Connection timed out at io.netty.channel.epoll.Native .readAddress(Native Method) ~[netty-all-4.0.23.Final.jar:4.0.23.Final] at io.netty.channel.epoll.EpollSocketChannel$EpollSocketUnsafe.doReadBytes(EpollSocketChannel.java:675) ~[netty -all-4.0.23.Final.jar:4.0.23.Final] 在 io.netty.channel.epoll.EpollSocketChannel$EpollSocketUnsafe.epollInReady(EpollSocketChannel.java:714) ~[netty-all-4.0.23.Final. jar:4.0.23.Final] 在 io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:326) ~[netty-all-4.0.23.Final.jar:4.0.23.Final] 在 io。 netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:264) ~[netty-all-4.0.23.Final.jar:4.0.23.Final] 在 io.netty.util.concurrent。

  3. 失败的批处理错误:

    [<...>] 的准备语句批次大小为 3453794,超过指定阈值 1024000 到 2429794。(请参阅 batch_size_fail_threshold_in_kb)

看起来批处理太大了,顺便说一下我们有很多批处理操作。也许批次会影响系统?

  1. 最后,最常见的异常 - 在将日志记录级别切换为 DEBUG 后,这些条目一个接一个出现:

    TIOStreamTransport.java:112 - 关闭输出流时出错。java.net.SocketException: 套接字在 java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:116) 处关闭 ~[na:1.8.0_66] 在 java.net.SocketOutputStream.write(SocketOutputStream.java:153) 处~[na: 1.8.0_66] 在 java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) ~[na:1.8.0_66] 在 java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) ~[na:1.8.0_66]在 java.io.FilterOutputStream.close(FilterOutputStream.java:158) ~[na:1.8.0_66] 在 org.apache.thrift.transport.TIOStreamTransport.close(TIOStreamTransport.java:110) ~[libthrift-0.9.2. jar:0.9.2] 在 org.apache.cassandra.thrift.TCustomSocket.close(TCustomSocket.java:197) [apache-cassandra-2.2.1.jar:2.2.1] 在 org.apache.thrift.transport.TFramedTransport .close(TFramedTransport.java:

您对可能导致此问题的原因有任何想法吗?

谢谢!

4

2 回答 2

0

对于第一点,我有一个想法:

当您发出查询时,总会有一个线程来处理它。

如果有太多,有一个队列应该组织它们。

线程在队列中等待的时间也有超时。

因此,您的副本响应速度不够快,因为服务于特定查询的一些线程被丢弃了。

考虑使用一些写/读线程。如果您的系统足够好,您可以在该区域分配更多的工人。

我记得玩了一段时间的 cassandra 压力,rate threads= 默认为 32。考虑在 cassandra.yaml 中增加

  • concurrent_reads 从 32 到 128
  • concurrent_writes 从 32 到 128

您也可以考虑减少数字。我建议测试测试和重新测试。

您也可以使用超时(一个线程可以在队列中存活多少来提供响应)

  • read_request_timeout_in_ms 从 5000 到 10000
  • write_request_timeout_in_ms 从 2000 到大约 5000。

关于第 2 点。我怀疑相同,您的节点正在尝试回复提示,因此发生了 2 件事:

  1. 没有到达节点(检查一些网络问题)

  2. 也许你需要分配更多的工作线程,影响 max_hints_delivery_threads。

第 3 点看起来与第 1 点相关。

祝你好运。

于 2016-10-04T13:30:20.977 回答
0

它实际上可能连接到无法处理提示的线程有限内存。可以通过增加 -Xss 来解决查看更多:https ://issues.apache.org/jira/browse/CASSANDRA-4740

于 2016-10-18T20:10:31.707 回答