我们正在使用Cassandra database in production environment
。我们有single cross colo cluster of 24 nodes
意思12 nodes in PHX
和12 nodes in SLC colo
。我们有一个replication factor of 4
,意思是2 copies will be there in each datacenter
。
以下是我们keyspace
创建column families
和Production DBA's
的方式。
使用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
,同时启用了KeyCaching
,SizeTieredCompactionStrategy
和Virtual Nodes
。 Cassandra节点部署在HDD instead of
SSD'上。
我正在使用Astyanax client
使用Cassandra database
从consistency level as ONE
读取数据。我使用50 Millions records
在生产群集中插入了Astyanax client
(总共大约285GB的24个节点的数据),压缩完成后,我开始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());
}
我大部分时间95th percentile read performance
8/9/10 ms
左右read performance
。
我试图看到有什么方法可以让Cassandra database
与1 or 2 ms
变得更好。我的印象是我将获得第95个百分点{ {1}}但是在对生产集群进行一些测试后,我的所有假设都出错了。从我运行客户端程序的地方到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。任何帮助将不胜感激。
感谢您的帮助。
答案 0 :(得分:0)
我会尝试以下方法:
将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
你可以做一些事情来优化读取。注意:我没有尝试过这些,但它们列在我要调查的事项列表中(所以我想我会分享)。
<强>缓存强>
启用密钥缓存和行缓存。
KeyCache
bin/nodetool --host 127.0.0.1 --port 8080 setcachecapacity MyKeyspace MyColumnFam 200001 0
RowCache
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级别最适合我们的设置。