簡體   English   中英

在一致性ONE的讀取查詢期間的Cassandra超時(需要1個響應但僅響應0個副本)

[英]Cassandra timeout during read query at consistency ONE (1 responses were required but only 0 replica responded)

我正在對具有500000行的表進行讀取和更新查詢,並且在處理大約300000行之后有時會低於錯誤,即使沒有節點關閉也是如此。

在一致性ONE的讀取查詢期間的Cassandra超時(需要1個響應但僅響應0個副本)

基建細節:
擁有5個Cassandra節點,5個spark和3個Hadoop節點,每個節點有8個內核和28 GB內存,Cassandra 復制因子3

卡桑德拉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)增加到20,000來嘗試相同的工作,但它沒有幫助。

我正在對兩張桌子進行查詢。 下面是其中一個表的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 = 'abcd345';

通常,當您收到超時錯誤時,這意味着您正在嘗試執行在Cassandra中無法正常擴展的操作。 修復通常是修改您的架構。

我建議您在運行查詢時監視節點,看看是否可以發現問題區域。 例如,您可以運行“watch -n 1 nodetool tpstats”來查看是否有任何隊列正在備份或刪除項目。 在此處查看其他監控建議

在您的配置中可能有一件事情就是你說你有五個Cassandra節點,但只有3個火花工人(或者你是說你在每個Cassandra節點上都有三個火花工人?)你至少需要一個火花工人每個Cassandra節點,以便將數據加載到spark中,在每個節點上本地完成,而不是通過網絡完成。

如果沒有看到您正在運行的架構和查詢,就很難說清楚。 你在閱讀單個分區嗎? 從單個分區讀取時,我開始在300,000行附近發生超時錯誤。 在這里查看問題。 到目前為止,我發現的唯一解決方法是在我的分區鍵中使用客戶端哈希將分區分成大約100K行的較小塊。 到目前為止,我還沒有找到一種方法告訴Cassandra沒有超時的查詢,我希望需要很長時間。

不要認為配置是根本原因,而是數據模型問題。

看到section_ks.encounters表的結構會很酷。

建議仔細考慮在設計表結構之前預期要運行的具體查詢。

據我所知,這兩個查詢期望section_ks.encounters的不同結構以良好的性能運行它們。

讓我們回顧一下每個提供的查詢並嘗試設計表:

第一:

SELECT encounter_uuid,encounter_start_date FROM section_ks.encounters WHERE patient_id ='1234'ANDy_start_date> ='“+ formatted_documentation_date +”'ALLOW FILTERING;

  • 第一點,如果Cassandra強迫你添加ALLOW FILTERING,那就是非最佳查詢或表結構的符號。
  • 第二點。 首要的關鍵。 如果patient_id列和encounter_start_date列將形成復合主鍵,那么關於什么是Cassandra Given查詢中的主鍵的一個很棒的解釋將快速並且沒有強制ALLOW FILTERING語句。 枚舉PRIMARY KEY()語句中的列應該對應於查詢中的過濾順序。
  • 為什么在原始查詢中必須允許過濾? 通過分區密鑰,Cassandra知道哪個節點數據位於何處。 如果patient_id列不是分區鍵,Cassandra必須掃描所有5個節點以查找請求的患者。 當我們跨節點有大量數據時,這種全掃描通常會因超時而失敗。

以下是表結構與給定查詢有效匹配的示例:

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)
);
  • patient_id列將是“分區鍵”。 負責跨Cassandra節點的數據分發。 簡單來說(省略復制功能):不同范圍的患者將存儲在不同的節點上。
  • encounter_start_date列將是一個“集群密鑰”負責分區內的數據排序。

現在可以從查詢中刪除允許過濾:

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

第二個查詢:

UPDATE section_ks.encounters SET testproblem_uuid_set = testproblem_uuid_set + {'1256'} WHERE encounter_uuid ='abcd345';

表結構應該看起來像接近:

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)
);

如果我們明確希望僅通過encounter_uuid進行快速過濾,則應將其定義為分區鍵。

關於有效數據模型設計的好文章:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM