我有一个由4个节点组成的Cassandra(2.2.1)集群,供Java客户端应用程序使用。复制因子为3,读写的一致性级别为LOCAL_QUORUM。每个节点有大约5 GB的数据。请求数量约为每秒2-4k。几乎没有删除操作,因此创建了少量的逻辑删除。
我注意到前一段时间的读写性能很差,并且随着时间的推移它变得越来越糟糕 - 群集变得非常慢。读取(主要是经常)和写入超时已经变得非常频繁。硬件不应该导致问题,部署集群的服务器在磁盘性能,CPU和RAM资源方面确实很好。
问题的原因我不清楚,但我注意到几个日志条目可能指向根本原因:
Java客户端应用程序日志中的异常堆栈跟踪:
com.datastax.driver.core.exceptions.ReadTimeoutException:读取查询期间的Cassandra超时一致性LOCAL_QUORUM(需要2个响应但只响应1个副本)
有趣的是,1个节点仍然响应。
失败提示错误的几个条目:
向/1.1.1.1重播提示失败;中止(135922已交付),错误:操作超时 - 仅收到0回复。
cassandra日志中有以下几个例外:
请求期间发生意外异常; channel = [id:0x10fc77df,/2.2.2.2:54459:> /1.1.1.1:9042] java.io.IOException:read(...)时出错:连接超时 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.SingleThreadEventExecutor $ 2.run(SingleThreadEventExecutor.java:116)〜[netty-all-4.0.23.Final.jar:4.0.23.Final] at io.netty.util.concurrent.DefaultThreadFactory $ DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)~ [netty-all-4.0.23.Final.jar:4.0.23.Final] 在java.lang.Thread.run(Thread.java:745)[na:1.8.0_66]
批处理错误失败:
[< ...>]的预准备报表批量大小为3453794,超过指定的阈值1024000 x 2429794.(请参阅batch_size_fail_threshold_in_kb)
看起来批次太大,顺便说一句,我们有很多批处理操作。批次可能影响系统吗?
最后,经常看到的异常 - 在将日志记录级别切换到DEBUG之后,这些条目一个接一个地出现:
TIOStreamTransport.java:112 - 关闭输出流时出错。 java.net.SocketException:Socket已关闭 在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] at 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:89)[libthrift-0.9.2.jar:0.9.2] 在org.apache.cassandra.thrift.CustomTThreadPoolServer $ WorkerProcess.run(CustomTThreadPoolServer.java:209)[apache-cassandra-2.2.1.jar:2.2.1] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)[na:1.8.0_66] at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617)[na:1.8.0_66] 在java.lang.Thread.run(Thread.java:745)[na:1.8.0_66]
您对可能导致此问题的原因有任何想法吗?
谢谢!
答案 0 :(得分:0)
对于第一点,我有一个想法:
当您发出查询时,总会有一个线程应该处理它。
如果有太多,则有一个队列应该组织它们。
线程在队列中等待的时间也会超时。
因此,您的副本回复速度不够快,因为服务于特定查询的线程的somne将被丢弃。
考虑使用一些写/读线程。如果您的系统足够好,您可以在该区域分配更多的工作人员。
我记得玩cassandra压力一段时间和速度线程= 其中默认值为32.考虑在cassandra.yaml中增加
的数量您也可以考虑减少数字。我建议测试并重新测试。
您也可以使用超时(线程可以在队列中存在多少来提供响应)
在第2点。我怀疑相同,你的节点正在尝试回复提示,所以发生了两件事:
未到达节点(检查一些网络问题)
也许你需要分配更多工作线程,影响max_hints_delivery_threads。
第3点看起来与第1点有关。
祝你好运。答案 1 :(得分:0)
它实际上可能连接到无法处理提示的线程有限内存。 它可以通过增加-Xss来解决 查看更多:https://issues.apache.org/jira/browse/CASSANDRA-4740