与本地读取延迟相比,Cassandra高客户端读取请求延迟

时间:2017-11-02 22:32:52

标签: cassandra cassandra-3.0

我们有20个节点的Cassandra集群运行大量读取请求(峰值时约为900k /秒)。我们的数据集相当小,因此所有内容都直接从内存(OS Page Cache)提供。我们的数据模型非常简单(只是一个键/值),我们所有的读取都以一致性级别1(RF 3)执行。

我们将Java Datastax驱动程序与TokenAwarePolicy一起使用,因此我们所有的读取都应直接转到具有所请求数据的一个节点。

这些是从其中一个节点提取的有关客户端读取请求延迟和本地读取延迟的一些指标。

org_apache_cassandra_metrics_ClientRequest_50thPercentile{scope="Read",name="Latency",} 105.778
org_apache_cassandra_metrics_ClientRequest_95thPercentile{scope="Read",name="Latency",} 1131.752
org_apache_cassandra_metrics_ClientRequest_99thPercentile{scope="Read",name="Latency",} 3379.391
org_apache_cassandra_metrics_ClientRequest_999thPercentile{scope="Read",name="Latency",} 25109.16

org_apache_cassandra_metrics_Keyspace_50thPercentile{keyspace=“<keyspace>”,name="ReadLatency",} 61.214
org_apache_cassandra_metrics_Keyspace_95thPercentile{keyspace="<keyspace>",name="ReadLatency",} 126.934
org_apache_cassandra_metrics_Keyspace_99thPercentile{keyspace="<keyspace>",name="ReadLatency",} 182.785
org_apache_cassandra_metrics_Keyspace_999thPercentile{keyspace="<keyspace>",name="ReadLatency",} 454.826

org_apache_cassandra_metrics_Table_50thPercentile{keyspace="<keyspace>",scope="<table>",name="CoordinatorReadLatency",} 105.778
org_apache_cassandra_metrics_Table_95thPercentile{keyspace="<keyspace>",scope="<table>",name="CoordinatorReadLatency",} 1131.752
org_apache_cassandra_metrics_Table_99thPercentile{keyspace="<keyspace>",scope="<table>",name="CoordinatorReadLatency",} 3379.391
org_apache_cassandra_metrics_Table_999thPercentile{keyspace="<keyspace>",scope="<table>",name="CoordinatorReadLatency",} 25109.16

另一个重要细节是我们的大多数查询(约70%)都没有返回任何内容,即它们是针对未找到的记录。因此,布隆过滤器在这里发挥了重要作用,它们看起来很好:

Bloom filter false positives: 27574
Bloom filter false ratio: 0.00000
Bloom filter space used: 
Bloom filter off heap memory used: 6760992

可以看出,每个节点中的读取速度非常快,99.9%小于0.5 ms。但是,客户端请求延迟更高,在99%上超过4ms。如果我正在阅读CL ONE并使用TokenAwarePolicy,那么两个值是否应该彼此相似,因为不需要协调?我错过了什么吗?还有什么我可以检查看看发生了什么吗?

提前致谢。

3 个答案:

答案 0 :(得分:2)

@luciano

即使在客户端配置了令牌感知,协调器和副本也可以为报告延迟报告不同的第99个百分点有多种原因。

这些可以是协调器代码与读取路径中副本的存储引擎代码之间的任何内容。

示例可以是:

  • 读取修复(与特定请求没有直接关系,因为读取触发它是异步的,但可能导致问题),
  • 主机超时(和/或推测性重试),
  • 令牌识别失败(动态小故障根本无法跟上),
  • GC停顿,

查找每个主机的指标异常,与GC重叠,甚至尝试捕获一些较慢请求的跟踪,并调查他们是否正在执行您对C *的所有期望(例如令牌感知)。

经过充分调整和规范的集群也可能看到动态的飞贼根本无法跟上并完成预期的工作。在这种情况下,禁用动态snitch可以修复高端读取百分位数的高延迟。见https://issues.apache.org/jira/browse/CASSANDRA-6908

但是要小心,测量并确认假设,因为错误应用的解决方案容易产生负面影响!

答案 1 :(得分:1)

即使使用TokenAwarePolicy,当驱动程序不知道哪个分区密钥时,驱动程序也无法使用该策略。

如果您使用简单语句,则不提供路由信息。因此,您需要通过调用setRoutingKey来获取驱动程序的其他信息。

DataStax Java驱动程序手册是一位好朋友。 http://docs.datastax.com/en/developer/java-driver/3.1/manual/load_balancing/#requirements

如果TokenAware完全正常工作,则CoordinatorReadLatency值与ReadLatency大致相同。你也应该检查一下。

http://cassandra.apache.org/doc/latest/operating/metrics.html?highlight=coordinatorreadlatency

答案 2 :(得分:0)

感谢您的回复,并对延迟回复您感到抱歉。

我发现的一件事是我们的集群有: dynamic_snitch_badness_threshold = 0 在配置文件中。将其更改为默认值(0.1)对客户端请求延迟有很大帮助。

即使在高负荷下,GC似乎也很稳定。暂停是恒定的(约10毫秒/秒),我没有看到尖峰(甚至没有完整的gcs)。我们正在使用具有更大Xmn(2.5GB)的CMS。

读取修复始终发生(我们将其设置为10%几率),因此当系统处理800k rec / sec时,我们在后台进行了大约80k读取修复/秒。

似乎我们对20台机器集群的要求太高了。从客户端的角度来看,延迟在800k qps之前非常稳定,之后它开始出现一点点上升,但仍处于可控制的阈值之下。

感谢所有的提示,动态的飞贼事情真有帮助!