DataStax Bulk Loader教程(四)
DataStax Bulk Loader系列教程共分为六篇,这是此系列的第四篇。在前三篇文章中,我们介绍了一些加载(load)的范例和和常规选项,例如日志和连接细节。在本篇文章中,我们会将重心放回卸载(unload)。
另外,我们也建议您在使用dsbulk时参考dsbulk 文档页面,从而了解所有的相关参数和选项。
范例 18:简易的卸载案例
让我们开始一个简易的卸载例子。我们会将数据卸载到/tmp/unload 目录下。
$ dsbulk unload -url /tmp/unload -k dsbulkblog -t iris_with_id
这将以标准错误(stderr)的形式在屏幕上显示很多内容,比如:
Operation directory: /tmp/logs/UNLOAD_20190314-170354-717718. total | failed | rows/s | mb/s | kb/row | p50 ms | p99ms | p999ms 150 | 0 | 232 | 0.01 | 0.05 | 171.44 | 171.97 | 171.97 Operation UNLOAD_20190314-170354-717718 completed successfully in 0 seconds.
我们可以将标准错误重新定向到 /dev/null 以避免看到这条信息。
$ dsbulk unload -url /tmp/unload -k dsbulkblog -t iris_with_id 2> /dev/null
你会注意到/tmp/unload 目录有两个文件:output-000001.csv 和 output-000002.csv. 至于为什么文件前缀是000001, 这是因为如果数据足够大,dsbulk会使用多个线程,平行卸载。因为我们的数据很小,所以它只会使用两条线程。提供的-url 是用来存放文件的目录。
请注意如果您指定了一个已经含有数据的目录,会产生以下错误。
Operation UNLOAD_20190314-170542-812259 failed: connector.csv.url target directory: /tmp/unload must be empty.
范例 18.1:指定输出文件的根名称
我们可以特别将输出根名称指定为output之外的名字。我们可以通过--connector.csv.fileNameFormat 参数,默认输出是-%0,6d.csv:
$ dsbulk unload -url /tmp/unload -k dsbulkblog -t iris_with_id --connector.csv.fileNameFormat "iris-%0,6d.csv"
现在我们看到/tmp/unload 目录含有两个文件:iris-000001.csv 与 iris-000002.csv。
范例 18.2:卸载到标准输出(Unloading to stdout)
默认的卸载位置其实是标准输出(stdout)。
$ dsbulk unload -k dsbulkblog -t iris_with_id
输出结果如下:
id,petal_length,petal_width,sepal_length,sepal_width,species 5,1.7,0.4,5.4,3.9,Iris-setosa 1,1.4,0.2,4.9,3.0,Iris-setosa ...
范例 18.3:将输出传递到其它程序
我们之前讨论了使用命令行工具改变输入,之后通过管道方法加载(load)入dsbulk。可以通过同样方法输出。例如,从species 列去除所有数据 Iris- 的前缀(我们仍然知道这些都是Iris)。
$ dsbulk unload -k dsbulkblog -t iris_with_id 2> /dev/null | sed 's/Iris-//g' > /tmp/unload/iris_shortname.csv
这文件的前几行是:
$ $ head -5 /tmp/unload/iris_shortname.csv id,petal_length,petal_width,sepal_length,sepal_width,species 144,5.7,2.5,6.7,3.3,virginica23,1.7,0.5,5.1,3.3,setosa 114,5.1,2.4,5.8,2.8,virginica53,4.0,1.3,5.5,2.3,versicolor
范例 19:卸载部分的列
在一些情况下,我们不希望从表中输出所有的列,我们可以通过许多不同的方法来完成。
范例 19.1:通过映射(mapping)指定卸载
我们可以通过 -m 的选项,简易映射指定一个子集(subset)。
$ dsbulk unload -k dsbulkblog -t iris_with_id -m "id,species"
以下是结果:
id,species 23,Iris-setosa 114,Iris-virginica 53,Iris-versicolor 110,Iris-virginica ...
范例 19.2:通过自定义查询指定卸载
我们可以通过自定义查询完成卸载,如:
$ dsbulk unload -query "SELECT id, species FROM dsbulkblog.iris_with_id"
结果类似于:
id,species 23,Iris-setosa 114,Iris-virginica 53,Iris-versicolor 110,Iris-virginica ...
范例 19.3:通过多线程的自定义查询指定卸载
之前的例子有一点低效,因为它是单线程的。我们可以用 :start 和 :end 字段完成一个多线程的版本:
$ dsbulk unload -query "SELECT id, species FROM dsbulkblog.iris_with_id WHERE Token(id) > :start AND Token(id) <= :end"
这将对每一个数据范围(token range)进行一次查询,并将每一个开始和结果的token替换。请注意,你必须要按顺序提供所有的分区键列,才能使用Token()函数。
范例 19.4:在自定义查询中添加额外列
在卸载数据中使用自定义查询选项并添加额外的列是可行的,如写入列的写入时间:
$ dsbulk unload -query "SELECT id, species, writetime(species) AS writetime FROM dsbulkblog.iris_with_id"
结果数据如下:
id,species,writetime 128,Iris-virginica,1552583016883989 23,Iris-setosa,1552583016820016 114,Iris-virginica,1552583016866729 53,Iris-versicolor,1552583016828860 110,Iris-virginica,1552583016867375 ...
范例 19.5:在自定义查询中指定谓词(predicate)
如果谓词是有效的CQL,那我们也可以在自定义查询中提供谓词:
$ dsbulk unload -query "SELECT id, species FROM dsbulkblog.iris_with_id WHERE id IN (101,102,103,104,105)"
会产生以下输出:
id,species 101,Iris-virginica 102,Iris-virginica 103,Iris-virginica 104,Iris-virginica 105,Iris-virginica
如果您想检查一个特别的token 范围,您也可以指定某一个特定的范围:
$ dsbulk unload -query "SELECT id, species FROM dsbulkblog.iris_with_id WHERE Token(id) > 0 AND Token(id) < 100000000000000000"
以下是返回的结果:
id,species 115,Iris-virginica
范例19.6:指定一个DSE Search的谓词
我们可以通过solr_query 机制提供一个DSE Search 谓词(注:此功能要求启用DSE Search)。为了展示此功能,我们创建一个新的表,同时启用search index:
$ cqlsh -e "CREATE TABLE dsbulkblog.iris_with_search (id int PRIMARY KEY, petal_length double, petal_width double, sepal_length double, sepal_width double, species text);"$ cqlsh -e "CREATE SEARCH INDEX IF NOT EXISTS ON dsbulkblog.iris_with_search"$ dsbulk load -url /tmp/dsbulkblog/iris.csv -k dsbulkblog -t iris_with_search
现在让我们请求一个只有包含Iris-setosa 行的查询:
$ dsbulk unload -query "SELECT id, petal_length, petal_width, sepal_length, sepal_width, species FROM dsbulkblog.iris_with_search WHERE solr_query = '{\\\"q\\\": \\\"species:Iris-setosa\\\"}'" --executor.continuousPaging.enabled false
请注意到这里有一些细节。首先我们禁用了连续分页(Continuous Paging)。因为DSE Search 不支持连续分页。其次,我们不只在solr_query 字符串里转译(escape)了双引号,同时我们将此字符串进行了二次转译,因为这里对字符串有额外的解释所以我们要这样做。最终,注意到我们投射了一些特别设定的列。如果我们进行以下操作:
$ dsbulk unload -query "SELECT * FROM dsbulkblog.iris_with_search WHERE solr_query = '{\\\"q\\\": \\\"species:Iris-setosa\\\"}'" --executor.continuousPaging.enabled false
我们最终会在结果中得到一个名为solr_query的列:
Operation directory: /tmp/logs/UNLOAD_20190320-180708-312514 total | failed | rows/s | mb/s | kb/row | p50ms | p99ms | p999ms 50 | 0 | 162 | 0.01 | 0.05 | 26.80 | 26.87 | 26.87 Operation UNLOAD_20190320-180708-312514 completed successfully in 0 seconds. id,petal_length,petal_width,sepal_length,sepal_width,solr_query,species 0,1.4,0.2,5.1,3.5,,Iris-setosa 1,1.4,0.2,4.9,3.0,,Iris-setosa 2,1.3,0.2,4.7,3.2,,Iris-setosa 3,1.5,0.2,4.6,3.1,,Iris-setosa 4,1.4,0.2,5.0,3.6,,Iris-setosa ...
这虽然有一些烦人,但很容易理解和使用。
范例 20:分隔符(Delimeter)
和加载一样,卸载中我们有时候需要使用一个非默认逗号的分隔符。例如:
$ dsbulk unload -k dsbulkblog -t iris_with_id -delim "\t"
这是一个以tab 作为分隔符的结果输出:
id petal_length petal_width sepal_length sepal_width species 23 1.7 0.5 5.1 3.3 Iris-setosa 114 5.1 2.4 5.8 2.8 Iris-virginica 53 4.0 1.3 5.5 2.3 Iris-versicolor 110 5.1 2.0 6.5 3.2 Iris-virginica 91 4.6 1.4 6.1 3.0 Iris-versicolor ...
范例 21:空值(Nulls)
类似于加载,我们也许需要将数据库中NULL的空值替换为一个空字符串(null string)。例如,在范例5.1 中,我们将iris_with_null_strings.csv 的数据加载到dsbulkblog.iris_with_id 表格中。现在我们想将数据卸载到文件里,同时将NULL替换为一个N/A 空的字符串。
$ dsbulk unload -k dsbulkblog -t iris_with_id -nullStrings "N/A"
结果如下所示:
id,petal_length,petal_width,sepal_length,sepal_width,species 23,1.7,0.5,5.1,3.3,N/A 114,5.1,2.4,5.8,2.8,N/A 53,4.0,1.3,5.5,2.3,N/A 110,5.1,2.0,6.5,3.2,N/A 91,4.6,1.4,6.1,3.0,N/A ...
范例 22:日期格式
如同加载,我们可以用-codec.date 参数来自定义日期的格式。
$ dsbulk unload -k dsbulkblog -t president_birthdates -delim "\t" --codec.date "EEEE MMMM d, y GGGG"
以下是输出结果:
president birthdate birthdate_string Thomas Jefferson Saturday April 13, 1743 Anno Domini April 13, 1743 James Monroe Friday April 28, 1758 Anno Domini April 28th, 1758 George Washington Friday February 22, 1732 Anno Domini February 22, 1732 John Adams Sunday October 30, 1735 Anno Domini October 30 1735 John Quincy Adams Saturday July 11, 1767 Anno Domini July 11, 1767 James Madison Tuesday March 16, 1751 Anno Domini March 16, 1751
点击这里下载 DataStax Bulk Loader。
本系列所有文章: