【问题标题】:Cassandra read performance with Astyanax client使用 Astyanax 客户端的 Cassandra 读取性能
【发布时间】:2013-05-06 07:08:28
【问题描述】:

我们正在使用Cassandra database in production environment。我们有一个single cross colo cluster of 24 nodes,意思是12 nodes in PHX12 nodes in SLC colo。我们有一个replication factor of 4,这意味着2 copies will be there in each datacenter

以下是我们的Production DBA's 创建keyspacecolumn families 的方式。

使用placement_strategy = 创建键空间配置文件 'org.apache.cassandra.locator.NetworkTopologyStrategy' 和 strategy_options = {slc:2,phx:2};

create column family PROFILE_USER
with key_validation_class = 'UTF8Type'
and comparator = 'UTF8Type'
and default_validation_class = 'UTF8Type'
and gc_grace = 86400;

我们正在运行Cassandra 1.2.2,它有org.apache.cassandra.dht.Murmur3Partitioner,同时启用了KeyCachingSizeTieredCompactionStrategyVirtual NodesCassandra 节点部署在HDD instead ofSSD 上。

我正在使用Astyanax client 使用consistency level as ONECassandra database 读取数据。我使用Astyanax client在生产集群中插入了50 Millions records(24个节点总共大约285GB的数据),压缩完成后,我开始做read against the Cassandra production database

下面是我使用Astyanax client创建连接配置的代码-

/**
 * Creating Cassandra connection using Astyanax client
 *
 */
private CassandraAstyanaxConnection() {

    context = new AstyanaxContext.Builder()
    .forCluster(ModelConstants.CLUSTER)
    .forKeyspace(ModelConstants.KEYSPACE)
    .withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl("MyConnectionPool")
        .setPort(9160)
        .setMaxConnsPerHost(100)
        .setSeeds("cdb03.vip.phx.host.com:9160,cdb04.vip.phx.host.com:9160")
        .setLocalDatacenter("phx") //filtering out the nodes basis on data center
    )
    .withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
        .setCqlVersion("3.0.0")
        .setTargetCassandraVersion("1.2")
        .setConnectionPoolType(ConnectionPoolType.ROUND_ROBIN)
        .setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE))
    .withConnectionPoolMonitor(new CountingConnectionPoolMonitor())
    .buildKeyspace(ThriftFamilyFactory.getInstance());

    context.start();
    keyspace = context.getEntity();

    emp_cf = ColumnFamily.newColumnFamily(
        ModelConstants.COLUMN_FAMILY, 
        StringSerializer.get(), 
        StringSerializer.get());
}

大多数时候,我在8/9/10 ms 附近得到95th percentile read performance

我想看看有什么方法可以让read performanceCassandra database 变得更好。 我的印象是我将在1 or 2 ms 获得第 95 个百分位,但之后在生产集群上做一些测试,我的所有假设都错了。我正在运行我的客户端程序的 Cassandra 生产节点的 Ping 时间是 0.3ms average

下面是我得到的结果。

Read Latency(95th Percentile)      Number of Threads    Duration the program was running(in minutes)    Throughput(requests/seconds)    Total number of id's requested    Total number of columns requested
    8 milliseconds                         10                      30                                               1584                              2851481                        52764072

谁能说明我可以尝试哪些其他方法来实现良好的读取延迟性能?我知道在我同样的情况下可能会有类似的人在生产中使用 Cassandra。任何帮助将不胜感激。

感谢您的帮助。

【问题讨论】:

    标签: java nosql cassandra astyanax netflix


    【解决方案1】:

    我会尝试以下方法:

    阿斯蒂亚纳克斯

    将 ConnectionPoolType 设置为 TOKEN_AWARE 而不是 ROUND_ROBIN。

    此外,我会使用一些 Astyanax 延迟感知连接池功能。例如:

    .withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl("MyConnectionPool")
            .setPort(9160)
            .setMaxConnsPerHost(100)
            .setSeeds("cdb03.vip.phx.host.com:9160,cdb04.vip.phx.host.com:9160")
            .setLocalDatacenter("phx") //filtering out the nodes basis on data center
            .setLatencyScoreStrategy(new SmaLatencyScoreStrategyImpl(10000,10000,100,0.50))
        )
    

    延迟设置是通过 ScoreStrategy 的构造函数提供的。例如SmaLatencyScoreStrategyImpl.

    我也在解决这个问题,所以如果我有任何其他知识,我会在这里发帖。

    见:Latency and Token Aware configuration

    卡桑德拉

    您可以做几件事来优化读取。注意:我没有尝试过这些,但它们在我的调查清单上(所以我想我会分享)。

    缓存

    启用 Key 缓存和 Row 缓存。

    密钥缓存

    bin/nodetool --host 127.0.0.1 --port 8080 setcachecapacity MyKeyspace MyColumnFam 200001 0
    

    行缓存

    bin/nodetool --host 127.0.0.1 --port 8080 setcachecapacity MyKeyspace MyColumnFam 0 200005
    

    然后在使用您的应用场景在该节点上敲击一段时间后检查命中率:

    bin/nodetool --host 127.0.0.1  --port 8080 cfstats
    

    一致性

    考虑 ONE 的读取一致性 请参阅this on Data Consistency(这是 DataStax 文档,但仍然相关)

    考虑降低读取修复的机会。

    update column family MyColumnFam with read_repair_chance=.5
    

    在降低 read_repair_chance 后,考虑调整复制因子以帮助提高读取性能(但这会杀死写入,因为我们将写入更多节点)。

    create keyspace cache with replication_factor=XX;
    

    磁盘

    不确定这里是否有任何事情要做,但我认为我应该将其包括在内。 确保最佳文件系统(例如 ext4)。如果你有一个高复制因子,我们可以围绕它优化磁盘(知道我们将从 Cassandra 获得持久性)。即哪种 RAID 级别最适合我们的设置。

    【讨论】:

    • 感谢您的建议。我也尝试将连接池类型设置为 TOKEN_AWARE,如果与 ROUND_ROBIN 连接池类型相比,我的性能非常差。所以我恢复到使用 RING DESCRIBE 作为 NodeDiscovery 的 ROUND_ROBIN 连接池。我尝试了 CONNECTION POOLING 类型和节点发现的各种组合。
    • 关于您的第二个建议。你确定getLatencyAwareWindowSize() 正在任何地方使用吗?我尝试放置断点,但它没有命中该代码。所以我不确定它是否对设置这些额外的属性有任何重要性。
    • 我认为这是基于偶然的观察。也就是说,如果它没有被使用,我不会感到惊讶,因为我已经看到 Astyanax 中的类似配置设置(例如 NodeDiscoveryType)在我预期的情况下会被忽略。
    • 我包含的代码不适用于最新的 Astyanax(正如您在latencyWindowSize 中发现的那样)。您已直接在 SMA 或 EMA LatencyScoreStrategy 构造函数的构造函数中设置延迟值。例如poolConfig.setLatencyScoreStrategy(new SmaLatencyScoreStrategyImpl(10000,10000,100,0.50));修复了我的示例代码。
    • 感谢您的建议。我只是好奇你在生产中使用的是什么版本的 Cassandra,你的集群规范是什么?也许通过那个我可以找到一些优化读取性能的东西。还有你在生产中使用 Astyanax 的哪些设置对我有很大帮助?谢谢。
    猜你喜欢
    • 2013-04-28
    • 1970-01-01
    • 1970-01-01
    • 2014-10-14
    • 1970-01-01
    • 2015-09-03
    • 2018-03-20
    • 2013-07-13
    • 2012-09-04
    相关资源
    最近更新 更多