我正在使用cassandra1.2和cql3。我的键空间中有三个列族。当我查询列族(phones)中的一个时,需要很长时间才能检索。这是我的问题
**select * from phones where phone_no in ('9038487582');**
下面是查询的跟踪输出。
activity | timestamp | source | source_elapsed
-------------------------------------------------+--------------+-------------+----------------
execute_cql3_query | 16:35:47,675 | 10.1.26.155 | 0
Parsing statement | 16:35:47,675 | 10.1.26.155 | 58
Peparing statement | 16:35:47,675 | 10.1.26.155 | 335
Executing single-partition query on phones | 16:35:47,676 | 10.1.26.155 | 1069
Acquiring sstable references | 16:35:47,676 | 10.1.26.155 | 1097
Merging memtable contents | 16:35:47,676 | 10.1.26.155 | 1143
Partition index lookup complete for sstable 822 | 16:35:47,676 | 10.1.26.155 | 1376
Partition index lookup complete for sstable 533 | 16:35:47,686 | 10.1.26.155 | 10659
Merging data from memtables and 2 sstables | 16:35:47,704 | 10.1.26.155 | 29192
Read 1 live cells and 0 tombstoned | 16:35:47,704 | 10.1.26.155 | 29332
Request complete | 16:35:47,704 | 10.1.26.155 | 29601
我在键空间上只有一个复制因子。有3个节点的集群。手机大约有4000万行,每行只有两列。它在29ms,15ms,8ms,5ms,3ms内返回,但不一致。你们能就我可能犯的错误给我一些建议吗?另外,我的用例将有极低的缓存命中率,所以缓存键不是我的解决方案。另外,这是我的列族定义。
CREATE TABLE phones (
phone_no text PRIMARY KEY,
ypids set<int>
) WITH
bloom_filter_fp_chance=0.100000 AND
caching='KEYS_ONLY' AND
comment='' AND
dclocal_read_repair_chance=0.000000 AND
gc_grace_seconds=864000 AND
read_repair_chance=0.100000 AND
replicate_on_write='true' AND
populate_io_cache_on_flush='false' AND
compaction={'class': 'LeveledCompactionStrategy'} AND
compression={'sstable_compression': 'SnappyCompressor'};
3条答案
按热度按时间xu3bshqb1#
从上面提供的表中,大部分查询时间都在索引查找和合并sstables中。这很常见,我不认为你做错了什么。
通过对数据进行非标准化处理,可以避免索引查找。cassandra的常见做法是围绕查询设计列族,而不是关系系统中典型的表。然后,这就给数据写入带来了负担,这也是cassandra最强大的地方,当然,由于数据重复和cassandra自然倾向于为客户提供不同的数据视图,以优化数据的群集可用性,因此存在数据一致性风险。
sstables的合并可以说是Cassandra的致命弱点。cassandra优化了写入速度和可靠性,同时牺牲了读取时间延迟和延迟一致性。对于Cassandra来说,持续时间不同的“较慢”读取是完全正常的。为了减少这个问题,有两种方法,第一种是避免对列族中的数据进行任何类型的更新或删除,因为这会导致以后的压缩。但即使这样,也只会延迟sstable的工作,因为插入会导致memtables被刷新。因此,如果变化/持续时间仍然太长,可以考虑的另一种解决方案是使用memcache之类的缓存来处理cassandra。这是netflix在这里记录的方法netflix对cassandra的基准测试。
为了完整性,我应该补充一点,cassandra中的列族设置可以进行调整、基准测试,然后再次调整以减少这个问题。但这只会得到一个,因为这个问题是Cassandra的设计固有的。您应该查看的设置是缓存大小,例如memtables及其溢出率,这是创建新sstable的点。压缩也有帮助,因为这有助于将更多数据压缩到内存中。通常情况下,根据amazonec2中的硬件和集群活动(这是我现在工作的环境),我希望未索引的读取需要2-10ms(平均5ms)。
mi7gmzs62#
索引查找速度相当快(可能是操作系统缓存了索引文件,因为它经常被访问);在这一步和“合并数据”这一步之间,您一直在浪费时间。两者之间发生的事情实际上是寻找sstable中的数据位置(我为1.2.6添加了一个新的跟踪条目,以明确这一点。)
这就解释了为什么有时是快速的,有时不是——如果您的seek是无竞争的,或者更好的是缓存的,那么查询将是快速的。否则会比较慢。
我看到了几种可能有用的方法:
切换到水平压实(http://www.datastax.com/dev/blog/when-to-use-leveled-compaction)
添加更多计算机以通过暴力获得更多iops
切换到ssd以通过更好的硬件获得更高的iops
添加更多的ram,使缓存更有效地掩盖iops的不足
您会注意到只有第一个选项不包括更多或不同的硬件,所以这是我首先要评估的。但是好处是有限的:最多你会把sstables的数量减少到1。
uajslkp63#
cassandra查询通常非常快,通常需要一个固定的时间。如果对列族中的单个列执行查询,与对所有列执行查询相比,返回所需的时间是多少?一些开销可能会导致更多的列,但不会太多,比如1或2毫秒。
如果查询全部和查询单个行之间存在很大差异(超过两倍),即使列族中没有太多数据,也可能是您的查询构造不正确。如果希望行中有可预测的列,可以尝试同时查询它们,而不是使用通配符进行查询。它可能会对查询速度产生显著影响。