即使数据存在,Cassandra也不提供数据

时间:2017-12-05 09:39:08

标签: cassandra cqlsh cassandra-3.0

我有一个复制因子为3的密钥空间。我将数据插入到Cassandra(具有单个数据中心的4节点集群)中,写入一致性为1。插入完成后,我正在读取具有一致性级别法定数量的数据(2)。但是,即使数据存在,我也不会得到数据,经过一段时间后我得到的数据相同。我不知道Cassandra为什么会这样。

我的列族模式

CREATE TABLE input_data_profile.input_log_profile_1 (
    cid text,
    ctdon bigint,
    ctdat bigint,
    email text,
    addrs set<frozen<udt_addrs>>,
    asset set<frozen<udt_asset>>,
    cntno set<frozen<udt_cntno>>,
    dob frozen<udt_date>,
    dvc set<frozen<udt_dvc>>,
    eaka set<text>,
    edmn text,
    educ set<frozen<udt_educ>>,
    gen tinyint,
    hobby set<text>,
    income set<frozen<udt_income>>,
    interest set<text>,
    lang set<frozen<udt_lang>>,
    levnt set<frozen<udt_levnt>>,
    like map<text, frozen<set<text>>>,
    loc set<frozen<udt_loc>>,
    mapp set<text>,
    name frozen<udt_name>,
    params map<text, frozen<set<text>>>,
    prfsn set<frozen<udt_prfsn>>,
    rel set<frozen<udt_rel>>,
    rel_s tinyint,
    skills_prfsn set<frozen<udt_skill_prfsn>>,
    snw set<frozen<udt_snw>>,
    sport set<text>,
    status tinyint,
    z_addrs tinyint,
    z_asset tinyint,
    z_cntno tinyint,
    z_dob tinyint,
    z_dvc tinyint,
    z_eaka tinyint,
    z_educ tinyint,
    z_email tinyint,
    z_gen tinyint,
    z_hobby tinyint,
    z_income tinyint,
    z_interest tinyint,
    z_lang tinyint,
    z_levnt tinyint,
    z_like tinyint,
    z_loc tinyint,
    z_mapp tinyint,
    z_name tinyint,
    z_params tinyint,
    z_prfsn tinyint,
    z_rel tinyint,
    z_rel_s tinyint,
    z_skills_prfsn tinyint,
    z_snw tinyint,
    z_sport tinyint,
    PRIMARY KEY (cid, ctdon, ctdat, email)
) WITH CLUSTERING ORDER BY (ctdon ASC, ctdat ASC, email ASC)
CREATE INDEX input_log_profile_1_z_snw_idx ON input_data_profile.input_log_profile_1 (z_snw);
CREATE INDEX input_log_profile_1_z_prfsn_idx ON input_data_profile.input_log_profile_1 (z_prfsn);
CREATE INDEX input_log_profile_1_z_hobby_idx ON input_data_profile.input_log_profile_1 (z_hobby);
CREATE INDEX input_log_profile_1_z_rel_idx ON input_data_profile.input_log_profile_1 (z_rel);
CREATE INDEX input_log_profile_1_z_gen_idx ON input_data_profile.input_log_profile_1 (z_gen);
CREATE INDEX input_log_profile_1_z_mapp_idx ON input_data_profile.input_log_profile_1 (z_mapp);
CREATE INDEX input_log_profile_1_z_dvc_idx ON input_data_profile.input_log_profile_1 (z_dvc);
CREATE INDEX input_log_profile_1_z_skills_prfsn_idx ON input_data_profile.input_log_profile_1 (z_skills_prfsn);
CREATE INDEX input_log_profile_1_z_eaka_idx ON input_data_profile.input_log_profile_1 (z_eaka);
CREATE INDEX input_log_profile_1_z_name_idx ON input_data_profile.input_log_profile_1 (z_name);
CREATE INDEX input_log_profile_1_z_cntno_idx ON input_data_profile.input_log_profile_1 (z_cntno);
CREATE INDEX input_log_profile_1_z_educ_idx ON input_data_profile.input_log_profile_1 (z_educ);
CREATE INDEX input_log_profile_1_z_loc_idx ON input_data_profile.input_log_profile_1 (z_loc);
CREATE INDEX input_log_profile_1_z_email_idx ON input_data_profile.input_log_profile_1 (z_email);
CREATE INDEX input_log_profile_1_z_interest_idx ON input_data_profile.input_log_profile_1 (z_interest);
CREATE INDEX input_log_profile_1_z_asset_idx ON input_data_profile.input_log_profile_1 (z_asset);
CREATE INDEX input_log_profile_1_z_like_idx ON input_data_profile.input_log_profile_1 (z_like);
CREATE INDEX input_log_profile_1_z_rel_s_idx ON input_data_profile.input_log_profile_1 (z_rel_s);
CREATE INDEX input_log_profile_1_z_lang_idx ON input_data_profile.input_log_profile_1 (z_lang);
CREATE INDEX input_log_profile_1_z_addrs_idx ON input_data_profile.input_log_profile_1 (z_addrs);
CREATE INDEX input_log_profile_1_z_dob_idx ON input_data_profile.input_log_profile_1 (z_dob);
CREATE INDEX input_log_profile_1_z_income_idx ON input_data_profile.input_log_profile_1 (z_income);
CREATE INDEX input_log_profile_1_z_sport_idx ON input_data_profile.input_log_profile_1 (z_sport);
CREATE INDEX input_log_profile_1_z_params_idx ON input_data_profile.input_log_profile_1 (z_params);

我需要明智地处理字段,因此我将每个字段状态编入索引。我想改进读写tps。建议我对架构进行一些修改。

1 个答案:

答案 0 :(得分:2)

如果我理解正确,那么你真的在这里提出两个问题:

首先,您正在使用CL = 1编写数据并使用CL = Quorum读取数据,并想知道为什么您并不总是检索已编写的数据,但之后可以检索它。如果这是正确的,那么这就是Cassandra的预期行为。当使用CL = 1写入时,响应的3个副本中的第一个将返回成功写入客户端。如果您在将数据写入其他副本之前尝试使用Quorum进行读取,则可能无法获得返回给您的任何(或陈旧)数据。这是Cassandra最终的一致性部分。如果您在成功写入后立即尝试读取数据,那么这很可能是导致问题的原因,因为&#34;写入后读取&#34;是Cassandra和大多数其他分布式系统中的反模式。

其次,在您的数据模式中,您使用的索引不正确。如果您使用索引来允许您查询这些字段,那么这是一个反模式,尤其是您拥有的大数字。 Cassandra中的索引是一项昂贵的操作,只能在索引的列具有低基数的极少数情况下使用。见https://docs.datastax.com/en/cql/3.1/cql/ddl/ddl_when_use_index_c.html

如果需要按大量列进行查询,则需要重新评估数据模型,因为Cassandra是基于每个查询表的方法进行优化的,您只需在主键中查询字段。这需要您将数据反规范化为多个不同的表,以便构建任何合理复杂的应用程序。这是您在选择Cassandra提供的性能,高可用性和可扩展性时所做的权衡之一。如果您确实需要能够对数据执行即席查询,我建议您查看其他数据存储区。