使用复合主键在Cassandra中分页结果集 - 在行上丢失

Mar*_*dal 7 cassandra cql3

所以,我最初的问题是使用token()函数来浏览Cassandra 1.2.9中的大型数据集,如下所述:在Cassandra中使用带有varchar键的CQL3分页大型结果集

接受的答案是选择使用令牌和块大小,但另一个问题表现出来.

我的表在cqlsh中看起来像这样:

key           | column1               | value
---------------+-----------------------+-------
  85.166.4.140 |       county_finnmark |     4
  85.166.4.140 |       county_id_20020 |     4
  85.166.4.140 |     municipality_alta |     2
  85.166.4.140 | municipality_id_20441 |     2
 93.89.124.241 |        county_hedmark |    24
 93.89.124.241 |       county_id_20005 |    24
Run Code Online (Sandbox Code Playgroud)

主键是key和column1的组合.在CLI中,相同的数据如下所示:

get ip['85.166.4.140'];
=> (counter=county_finnmark, value=4)
=> (counter=county_id_20020, value=4)
=> (counter=municipality_alta, value=2)
=> (counter=municipality_id_20441, value=2)
Returned 4 results.
Run Code Online (Sandbox Code Playgroud)

问题

当使用限制为100的cql时,返回的结果可能会在记录中间停止,如下所示:

key           | column1               | value
---------------+-----------------------+-------
  85.166.4.140 |       county_finnmark |     4
  85.166.4.140 |       county_id_20020 |     4
Run Code Online (Sandbox Code Playgroud)

将这些留给"行"(列):

  85.166.4.140 |     municipality_alta |     2
  85.166.4.140 | municipality_id_20441 |     2
Run Code Online (Sandbox Code Playgroud)

现在,当我对下一页使用token()函数时,会跳过这两行:

select * from ip where token(key) > token('85.166.4.140') limit 10;
Run Code Online (Sandbox Code Playgroud)

结果:

key           | column1                | value
---------------+------------------------+-------
 93.89.124.241 |         county_hedmark |    24
 93.89.124.241 |        county_id_20005 |    24
 95.169.53.204 |        county_id_20006 |     2
 95.169.53.204 |         county_oppland |     2
Run Code Online (Sandbox Code Playgroud)

因此,没有跟踪前两个IP地址的最后两个结果.

如何在不跳过cql行的情况下使用token()进行分页?就像是:

select * from ip where token(key) > token(key:column1) limit 10;
Run Code Online (Sandbox Code Playgroud)

Mar*_*dal 5

好的,所以我使用这篇文章中的信息来制定解决方案:http: //www.datastax.com/dev/blog/cql3-table-support-in-hadoop-pig-and-hive("CQL3分页"一节").

首先,我执行这个cql:

select * from ip limit 5000;
Run Code Online (Sandbox Code Playgroud)

从结果集的最后一行,我得到密钥(即'85 .166.4.140')和column1的值(即'county_id_20020').

然后我创建一个准备好的语句来评估

select * from ip where token(key) = token('85.166.4.140') and column1 > 'county_id_20020' ALLOW FILTERING;
Run Code Online (Sandbox Code Playgroud)

(我猜它也可以在不使用token()函数的情况下工作,因为检查现在是相同的 :)

select * from ip where key = '85.166.4.140' and column1 > 'county_id_20020' ALLOW FILTERING;
Run Code Online (Sandbox Code Playgroud)

结果集现在包含此IP的剩余X行(列).然后该方法返回所有行,并且对该方法的下一次调用包括最后使用的键('85 .166.4.140').使用此键,我可以执行以下选择:

select * from ip where token(key) > token('85.166.4.140') limit 5000;
Run Code Online (Sandbox Code Playgroud)

它给了我'85 .166.4.140' 第一个IP的下一个5000行(包括).

现在,分页中没有列丢失.

UPDATE

Cassandra 2.0引入了自动分页,由客户端处理.更多信息:http://www.datastax.com/dev/blog/client-side-improvements-in-cassandra-2-0

(请注意,setFetchSize是可选的,并且不需要分页工作)