从 C* table 获取不同的分区键

Get distinct partition keys from C* table

cqlsh 不允许嵌套查询,所以我无法将所选数据导出到 csv.. 我正在尝试使用以下方法从 cassandra 导出选定数据(大约 200,000 行,单列):

echo "SELECT distinct imei FROM listener.snapshots;" > select.cql bin/cqlsh -f select.cql > output.txt

它永远卡住了,没有任何错误,而且文件没有增长。

如果我在最后一行使用 strace,我会得到很多行,例如:

select(0, NULL, NULL, NULL, {0, 2000})  = 0 (Timeout)
select(0, NULL, NULL, NULL, {0, 4000})  = 0 (Timeout)
select(0, NULL, NULL, NULL, {0, 8000})  = 0 (Timeout)
select(0, NULL, NULL, NULL, {0, 16000}) = 0 (Timeout)
select(0, NULL, NULL, NULL, {0, 32000}) = 0 (Timeout)
select(0, NULL, NULL, NULL, {0, 1000})  = 0 (Timeout)
select(0, NULL, NULL, NULL, {0, 2000})  = 0 (Timeout)
select(0, NULL, NULL, NULL, {0, 4000})  = 0 (Timeout)
select(0, NULL, NULL, NULL, {0, 8000})  = 0 (Timeout)
select(0, NULL, NULL, NULL, {0, 16000}) = 0 (Timeout)
select(0, NULL, NULL, NULL, {0, 32000}) = 0 (Timeout)
select(0, NULL, NULL, NULL, {0, 1000})  = 0 (Timeout)
select(0, NULL, NULL, NULL, {0, 2000})  = 0 (Timeout)
select(0, NULL, NULL, NULL, {0, 4000})  = 0 (Timeout)
select(0, NULL, NULL, NULL, {0, 8000})  = 0 (Timeout)

和--debug只给我:

cqlsh --debug -f select.cql > output.txt

Using CQL driver: <module 'cassandra' from '/usr/share/dse/resources/cassandra/bin/../lib/cassandra-driver-internal-only-2.5.1.zip/cassandra-driver-2.5.1/cassandra/__init__.py'>

怎么了? 是否有更好的方法从大型 C* 中获取不同的分区键 table?

通常您会使用 cqlsh "COPY ... TO ..." 命令将数据从 table 导出到 csv 文件。

请参阅文档 here

我不确定你尝试的为什么卡住了。要进行调试,我建议不要使用 DISTINCT 并添加 LIMIT 子句。可能是你的 table 很大,所以 cqlsh 正在对结果进行分页,但是没有人按 return 进入下一页结果,所以它永远等待。

我用了capture:

cqlsh> CAPTURE 'temp.csv'                                              
Now capturing query output to 'temp.csv'.
cqlsh> SELECT distinct imei FROM listener.snapshots;
---MORE---
---MORE---
---MORE---
---MORE---
.
.
.
cqlsh> 
cqlsh>

然后按回车直到完成。

更快的选择是使用 paging:

cqlsh> PAGING off
Disabled Query paging.
cqlsh> CAPTURE 'temp.csv'                                              
Now capturing query output to 'temp.csv'.
cqlsh> SELECT distinct imei FROM listener.snapshots;

它会立即将数据提取到文件中(如果您得到 OperationTimedOut,您应该在 cassandra.yaml 中编辑超时设置)。

我不敢相信这是最快的方式...我知道我可以通过使用 CassandraSQLContext 使用 spark 导出数据但是当我需要创建 rdd 查询 C* 时它不是那么快非常大的 table(2B 行~)中的不同列,并将它们打印到文件:

    val conf = new SparkConf().setAppName("ExtractDistinctImeis")
    val sc = new SparkContext(conf)
    val sqlContext = new SQLContext(sc)
    val connector = CassandraConnector(conf)
    val cc = new CassandraSQLContext(sc)

    val snapshots_imeis = cc.sql("select distinct imei from listener.snapshots").map(row => row(0).toString)

    val imeis = snapshots_imeis.collect 

    def printToFile(f: java.io.File)(op: java.io.PrintWriter => Unit) {
        val p = new java.io.PrintWriter(f)
        try { op(p) } finally { p.close() }
    }

    printToFile(new File("/path/to/file.txt")) { p => imeis.foreach(p.println) }

spark用了3.5个小时!通过捕获,我在 3 min/3 秒后设法获取了我的文件。