在一致性为1的读取查询期间cassandra超时(需要1个响应,但只有0个副本响应)

dy1byipe  于 2021-06-03  发布在  Hadoop
关注(0)|答案(2)|浏览(499)

我正在对一个有500000行的表执行读取和更新查询,有时在处理了大约300000行之后,甚至在没有节点关闭的情况下,也会出现低于错误的情况。
在一致性为1的读取查询期间,cassandra超时(需要1个响应,但只有0个副本响应)
基础设施详细信息:
有5个cassandra节点,5个spark和3个hadoop节点,每个节点有8个内核和28gb内存,cassandra复制因子是3。
cassandra 2.1.8.621 | dse 4.7.1 | spark 1.2.1 | hadoop 2.7.1。
Cassandra配置:

read_request_timeout_in_ms (ms): 10000
range_request_timeout_in_ms (ms): 10000
write_request_timeout_in_ms (ms): 5000
cas_contention_timeout_in_ms (ms): 1000 
truncate_request_timeout_in_ms (ms): 60000
request_timeout_in_ms (ms): 10000.

我也尝试过同样的工作 read_request_timeout_in_ms (ms)到20000,但没用。
我在两张table上做查询。下面是其中一个表的create语句:
创建表:

CREATE TABLE section_ks.testproblem_section (
    problem_uuid text PRIMARY KEY,
    documentation_date timestamp,
    mapped_code_system text,
    mapped_problem_code text,
    mapped_problem_text text,
    mapped_problem_type_code text,
    mapped_problem_type_text text,
    negation_ind text,
    patient_id text,
    practice_uid text,
    problem_category text,
    problem_code text,
    problem_comment text,
    problem_health_status_code text,
    problem_health_status_text text,
    problem_onset_date timestamp,
    problem_resolution_date timestamp,
    problem_status_code text,
    problem_status_text text,
    problem_text text,
    problem_type_code text,
    problem_type_text text,
    target_site_code text,
    target_site_text text
    ) WITH bloom_filter_fp_chance = 0.01
    AND caching = '{"keys":"ALL", "rows_per_partition":"NONE"}'
    AND comment = ''
    AND compaction = {'class': 
    'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'}
    AND compression = {'sstable_compression': 
    'org.apache.cassandra.io.compress.LZ4Compressor'}
    AND dclocal_read_repair_chance = 0.1
    AND default_time_to_live = 0
    AND gc_grace_seconds = 864000
    AND max_index_interval = 2048
    AND memtable_flush_period_in_ms = 0
    AND min_index_interval = 128
    AND read_repair_chance = 0.0
    AND speculative_retry = '99.0PERCENTILE';

查询:

  1. SELECT encounter_uuid, encounter_start_date FROM section_ks.encounters WHERE patient_id = '1234' AND encounter_start_date >= '" + formatted_documentation_date + "' ALLOW FILTERING; 2) UPDATE section_ks.encounters SET testproblem_uuid_set = testproblem_uuid_set + {'1256'} WHERE encounter_uuid = 'd345';
xwbd5t1u

xwbd5t1u1#

通常,当你得到一个超时错误,这意味着你正在尝试做一些不适合Cassandra扩展。解决方法通常是修改模式。
我建议您在运行查询时监视节点,看看是否可以发现问题区域。例如,您可以运行“watch-n1nodetooltpstats”来查看是否有任何队列正在备份或删除项。请参阅此处的其他监控建议。
在您的配置中,有一点可能是关闭的,即您说您有五个cassandra节点,但只有3个spark worker(或者您是说您在每个cassandra节点上有3个spark worker?),您希望每个cassandra节点上至少有一个spark worker,以便将数据加载到spark是在每个节点上本地完成的,而不是通过网络完成的。
如果看不到您的模式和正在运行的查询,很难说出更多的信息。你是从一个分区读的吗?当从单个分区读取数据时,我开始在300000行附近出现超时错误。请看这里的问题。到目前为止,我找到的唯一解决方法是在分区键中使用客户端散列,将分区分解为大约10万行的小块。到目前为止,我还没有找到一种方法来告诉Cassandra不要为一个我认为需要很长时间的查询超时。

5kgi1eie

5kgi1eie2#

不要认为配置是根本原因,而是数据模型问题。
如果能看到表的结构,那就太酷了。
建议在设计表结构之前仔细考虑具体的查询需要运行什么。
据我所知,这两个查询需要不同结构的section_ks.conferences以良好的性能运行它们。
让我们检查每个提供的查询并尝试设计表:
第一个:
从“遭遇”部分中选择“遭遇”和“遭遇开始日期”,其中“患者id=”1234“和遭遇开始日期>=”+格式化文档\u日期+“'允许筛选;
第一点,如果cassandra强制您添加allow filtering,那么这是一个非最佳查询或表结构的符号。
第二点。主键。如果patient\u id列和conference\u start\u date列将形成一个复合主键,那么在cassandra给定的查询中,关于什么是主键的一个非常棒的解释就可以快速工作,而不需要强制的allow filtering语句。primary key()语句中列的枚举应与查询中的筛选顺序相对应。
为什么在原始查询中允许强制筛选?通过分区键cassandra知道数据所在的节点。如果patient_id列不是分区键,cassandra必须扫描所有5个节点以查找请求的patient。当我们跨节点有大量数据时,这种完全扫描通常会超时而失败。
下面是一个表结构与给定查询有效匹配的示例:

create table section_ks.encounters(
    patient_id bigint, 
    encounter_start_date timestamp, 
    encounter_uuid text,
    some_other_non_unique_column text,
    PRIMARY KEY (patient_id, encounter_start_date)
);

“患者id”列将是“分区键”。负责跨cassandra节点的数据分发。简单地说(省略复制特性):不同范围的患者将存储在不同的节点上。
“开始日期”列将是一个“集群键”,负责分区内的数据排序。
现在可以从查询中删除“允许筛选”:

SELECT encounter_uuid, encounter_start_date 
FROM section_ks.encounters 
WHERE patient_id = '1234' AND encounter_start_date >= '2017-08-19';

第二个查询:
更新节_ks.conferences set testproblem_uuid_set=testproblem_uuid_set+{'1256'},其中conference_uuid='d345';
表结构应类似于:

create table section_ks.encounters(
    encounter_uuid text, -- partition key
    patient_id bigint,
    testproblem_uuid_set text, 
    some_other_non_unique_column text,
    PRIMARY KEY (encounter_uuid)
);

如果我们确定只想通过遇到uuid进行快速过滤,那么应该将其定义为分区键。
关于设计有效数据模型的好文章:
https://www.datastax.com/dev/blog/basic-rules-of-cassandra-data-modeling
https://opencredo.com/cassandra-data-modelling-patterns/

相关问题