【问题标题】:Cassandra JVM ConstraintCassandra JVM 约束
【发布时间】:2019-03-28 01:05:48
【问题描述】:

我正在构建一个简单的应用程序来使用 python cassandra-driver 查询 cassandra 数据库。我的要求是每秒获得 5k 次查询。

Spec goes as below:
1. Cassandra 3.11 has one keyspace and one table with 10k records
2. Using Python cassandra-driver to query the data from above table.
3. Deployed cassandra on kubernetes using statefulset on 3 nodes. I am using standard settings with 6 core vCPUs in GKE.

我在 2-3 分钟内触发了 10k 个请求。对于 80% 的请求,我可以在 10 毫秒内从表中获得响应,但有时对于其他 20% 的请求,它会超过 50 毫秒到 100 毫秒。当我调查发现这可能是由于JVM问题(2019-03-09T15:30:11.110-0530:908.491:应用程序线程停止的总时间:0.0203039秒)。

参考日志:

2019-03-09 15:30:11.076271     DB time taken !   0:00:00.011658
2019-03-09 15:30:11.080144     DB time taken !   0:00:00.013943
2019-03-09 15:30:11.080273     DB time taken !   0:00:00.013248
2019-03-09 15:30:11.148072     DB time taken !   0:00:00.079689
2019-03-09 15:30:11.148147     DB time taken !   0:00:00.079215
2019-03-09 15:30:11.148367     DB time taken !   0:00:00.067695
2019-03-09 15:30:11.148464     DB time taken !   0:00:00.066383
2019-03-09 15:30:11.154260     DB time taken !   0:00:00.069872 

代码sn-p:

t1 = datetime.now()
result = session.execute('SELECT * FROM a.b WHERE key = %s', [key])
t2 = datetime.now()

logger.debug('DB time ! ' + '  ' + str(t2 - t1))

在这里,我希望 95% 的请求在 50 毫秒内,但由于 JVM,其中 20-30% 的请求超过 50 毫秒。

当我使用压力工具进行负载测试时,结果令人满意,但当我通过上述代码触发请求时却没有:

Results:
Op rate                   :   33,700 op/s  [single_read: 33,700 op/s]
Partition rate            :    5,301 pk/s  [single_read: 5,301 pk/s]
Row rate                  :    5,301 row/s [single_read: 5,301 row/s]
Latency mean              :   11.6 ms [single_read: 11.6 ms]
Latency median            :    6.2 ms [single_read: 6.2 ms]
Latency 95th percentile   :   41.5 ms [single_read: 41.5 ms]
Latency 99th percentile   :   61.8 ms [single_read: 61.8 ms]
Latency 99.9th percentile :  100.9 ms [single_read: 100.9 ms]
Latency max               :  263.7 ms [single_read: 263.7 ms]
Total partitions          :    318,523 [single_read: 318,523]
Total errors              :          0 [single_read: 0]
Total GC count            : 0
Total GC memory           : 0.000 KiB
Total GC time             :    0.0 seconds
Avg GC time               :    NaN ms
StdDev GC time            :    0.0 ms
Total operation time      : 00:01:00

我已经提出了很多建议,但没有找到满足此要求的解决方案。

有人可以指导我如何减少 JVM 在 cassandra 中运行所花费的时间或缩短 cassandra 运行 JVM 所花费的时间吗?

注意: 我做了所有可能的调整指南(行缓存、布隆过滤器、压缩等)以获得上述性能。

cqlsh:a> select * from b where key = '34823049392304' ;

 key            | name | password
----------------+------+-----------
 34823049392304 | test | test33k23

(1 rows)

Tracing session: 467f0a90-4489-11e9-88ab-3ff1c33f5d2f

 activity                                                                             | timestamp                  | source     | source_elapsed | client
--------------------------------------------------------------------------------------+----------------------------+------------+----------------+-----------
                                                                   Execute CQL3 query | 2019-03-12 05:39:59.545000 | 10.12.88.4 |              0 | 127.0.0.1
 Parsing select * from b where key = '34823049392304' ; [Native-Transport-Requests-1] | 2019-03-12 05:39:59.545000 | 10.12.88.4 |            328 | 127.0.0.1
                                    Preparing statement [Native-Transport-Requests-1] | 2019-03-12 05:39:59.546000 | 10.12.88.4 |            565 | 127.0.0.1
                                                          Row cache hit [ReadStage-3] | 2019-03-12 05:39:59.547000 | 10.12.88.4 |           1467 | 127.0.0.1
                                 Read 1 live rows and 0 tombstone cells [ReadStage-3] | 2019-03-12 05:39:59.547000 | 10.12.88.4 |           1729 | 127.0.0.1
                                                                     Request complete | 2019-03-12 05:39:59.547018 | 10.12.88.4 |           2018 | 127.0.0.1

【问题讨论】:

  • 您能多谈谈您的集群吗?多少个节点?使用了多少堆?您是否调整了任何 JVM 参数?
  • @Mandraenke:我正在使用具有 8CPU/24GM 内存的 3 节点 statefulset 集群。在 Yaml 文件内部定义 cpu:“6000m”和内存:每个 3Gi。我已将堆大小(-名称:MAX_HEAP_SIZE 值:2400M 和-名称:HEAP_NEWSIZE 值:600M)设置为 yaml 文件中的 env 变量。堆内存 (MB):449.63 / 2340.00。只更新了以上两个,没有别的了。
  • @Mandraenke:我使用github.com/docker-library/cassandra 3.11 docker 文件构建映像并更新了行键缓存字段以保存 10k 行/25MB 数据。使用github.com/IBM/Scalable-Cassandra-deployment-on-Kubernetes/blob/… yaml 文件将其部署到 kubernetes 集群中。如果您需要更多信息,请告诉我。

标签: cassandra


【解决方案1】:

除非您使用 ZGC(jdk11 需要 C* 4.0),否则您将在 100 毫秒或更长时间内获得 GC,默认情况下会以这种方式显示在请求中。 Cassandra 通过推测性重试在内部缓解了彼此之间的这种情况,但这在协调器 GC 时无济于事。为了不影响您的客户端,您需要从客户端进行推测,请参阅:https://docs.datastax.com/en/developer/java-driver/3.2/manual/speculative_execution/ 这样,如果协调器遇到 GC,您将遇到第二个节点。对于低于 10 毫秒的时间,尽管您需要将推测设置为 0 毫秒,否则网络延迟往往会毁掉一切。

请注意,python 驱动程序是迄今为止性能最差的驱动程序,因此,如果您真的在推动低延迟高吞吐量请求,建议在 python 驱动程序之前使用 java、c++ 甚至 nodejs 驱动程序。仅此一项可能就是您在 cassandra-stress(java 驱动程序)和您的 python 应用程序之间看到的区别。

【讨论】:

  • 我还在研究java。一旦我有更新,会通知你。我尝试使用 Golang。在 Golang 中,我尝试了 go-routine 概念,例如触发对连接到 3 个节点的 3 个例程的请求。这样,如果任何与 JVM 节点接触的例程,我都可以从其他节点更快地获得响应。在这里,我发现了一个问题,我们不确定这 3 个例程中的哪一个首先触发。这是首先触发哪个例程将不知道的问题。所以,如果命中 JVM 节点的例程比其他两个例程来得快,那么这里就没有用了。
【解决方案2】:

根据 Chris 的建议,我尝试了 Go lang cassandra 驱动程序,我可以达到我需要的响应时间,即 90% 的请求在一毫秒内得到处理。我同意 cassandra 数据库节点将受到负担。完整代码在链接cassandra performance with Go

性能统计:

 Running 1m test @ http://10.12.206.8:8081/
  2 threads and 2 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.53ms  654.92us  30.59ms   96.60%
    Req/Sec   667.35     58.83   818.00     68.67%
  79763 requests in 1.00m, 14.91MB read
Requests/sec:   1328.29
Transfer/sec:    254.24KB

示例日志(如果您浏览代码,您可以关联日志详细信息):

    Seed 0  2019-03-23 09:25:42.416604785 +0000 UTC m=+1528.998487360   2019-03-23 09:25:42.41787099 +0000 UTC m=+1528.999753571   1.266211ms
  1.2236ms  In First Attempt
  1.244515ms
 Seed 0  2019-03-23 09:25:42.418236332 +0000 UTC m=+1529.000118895   2019-03-23 09:25:42.419480829 +0000 UTC m=+1529.001363410   1.244515ms
  949.845µs  In First Attempt
  969.877µs
 Seed 0  2019-03-23 09:25:42.419879164 +0000 UTC m=+1529.001761725   2019-03-23 09:25:42.420849019 +0000 UTC m=+1529.002731602   969.877µs
  1.30004ms  In First Attempt
  1.320535ms
 Seed 0  2019-03-23 09:25:42.421222097 +0000 UTC m=+1529.003104671   2019-03-23 09:25:42.422542624 +0000 UTC m=+1529.004425206   1.320535ms
  1.181071ms  In First Attempt
  1.199418ms
 Seed 0  2019-03-23 09:25:42.422874452 +0000 UTC m=+1529.004757012   2019-03-23 09:25:42.424073845 +0000 UTC m=+1529.005956430   1.199418ms

我对我的代码有疑问,所以请一些熟练的团队来看看,所以提出了一个问题,但该代码可以被别人使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-22
    • 1970-01-01
    • 2014-11-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-23
    • 1970-01-01
    相关资源
    最近更新 更多