Stratio 的 Cassandra Lucene Index 源自 Stratio Cassandra,是 Apache Cassandra 的一个插件,它扩展了其索引功能以提供近乎实时的搜索,例如 ElasticSearch 或 Solr,包括全文搜索功能和免费的多变量、地理空间和双时态搜索。它是通过基于 Apache Lucene 的 Cassandra 二级索引实现来实现的,其中集群的每个节点都为其自己的数据建立索引。 Stratio 的 Cassandra 索引是 Stratio BigData 平台所基于的核心模块之一。
索引相关性搜索允许您检索满足搜索的n 个以上相关结果。协调器节点将搜索发送到集群中的每个节点,每个节点返回其n 个最佳结果,然后协调器组合这些部分结果并给出其中的n 个最佳结果,从而避免完全扫描。您还可以根据字段组合进行排序。
表中的任何单元格都可以建立索引,包括主键和集合中的单元格。还支持宽行。您可以扫描令牌/键范围、应用其他 CQL3 子句并对筛选结果进行分页。
当使用 Apache Hadoop 或更好的 Apache Spark 等 MapReduce 框架分析存储在 Cassandra 中的数据时,索引过滤搜索是一个强大的帮助。在作业输入中添加 Lucene 过滤器可以显着减少要处理的数据量,避免完全扫描。
以下基准测试结果可以让您了解将 Lucene 索引与 Spark 结合使用时的预期性能。我们对 1% 到 100% 的存储数据进行连续查询。我们可以看到索引对于请求强过滤数据的查询具有高性能。然而,在限制较少的查询中,性能会下降。随着查询返回的记录数量增加,我们会达到索引变得比完整扫描慢的程度。因此,在 Spark 作业中使用索引的决定取决于查询选择性。两种方法之间的权衡取决于特定的用例。一般来说,对于检索不超过 25% 存储数据的作业,建议将 Lucene 索引与 Spark 结合使用。
该项目无意取代 Apache Cassandra 非规范化表、倒排索引和/或二级索引。它只是一个执行某种查询的工具,这些查询很难使用 Apache Cassandra 开箱即用的功能来解决,从而填补了实时和分析之间的空白。
更多详细信息请参阅 Stratio 的 Cassandra Lucene 索引文档。
Lucene 搜索技术集成到 Cassandra 中可以提供:
Stratio 的 Cassandra Lucene 索引及其与 Lucene 搜索技术的集成提供了:
尚不支持:
counter
列Stratio 的 Cassandra Lucene Index 作为 Apache Cassandra 的插件进行分发。因此,您只需构建一个包含该插件的 JAR 并将其添加到 Cassandra 的类路径中:
git clone http://github.com/Stratio/cassandra-lucene-index
cd cassandra-lucene-index
git checkout ABCX
mvn clean package
cp plugin/target/cassandra-lucene-index-plugin-*.jar <CASSANDRA_HOME>/lib/
特定的 Cassandra Lucene 索引版本针对特定的 Apache Cassandra 版本。因此,cassandra-lucene-index ABCX 旨在与 Apache Cassandra ABC 一起使用,例如 cassandra-lucene-index:3.0.7.1 用于 cassandra:3.0.7。请注意,生产就绪版本是版本标签(例如3.0.6.3),不要在生产中使用branch-X或master分支。
或者,也可以使用此 Maven 配置文件来完成修补,指定 Cassandra 安装的路径,此任务还会删除 CASSANDRA_HOME/lib/ 目录中以前插件的 JAR 版本:
mvn clean package -Ppatch -Dcassandra_home= < CASSANDRA_HOME >
如果您没有安装 Cassandra 版本,还有一个替代配置文件可以让 Maven 下载并修补正确版本的 Apache Cassandra:
mvn clean package -Pdownload_and_patch -Dcassandra_home= < CASSANDRA_HOME >
现在您可以运行 Cassandra 并使用 Cassandra 查询语言进行一些测试:
< CASSANDRA_HOME > /bin/cassandra -f
< CASSANDRA_HOME > /bin/cqlsh
Lucene 的索引文件将存储在与 Cassandra 相同的目录中。默认数据目录是/var/lib/cassandra/data
,每个索引都放置在其索引列族的 SSTable 旁边。
请记住,如果您使用地理形状搜索,则需要包含 JTS jar。
有关 Apache Cassandra 的更多详细信息,请参阅其文档。
我们将创建下表来存储推文:
CREATE KEYSPACE demo
WITH REPLICATION = { ' class ' : ' SimpleStrategy ' , ' replication_factor ' : 1 };
USE demo;
CREATE TABLE tweets (
id INT PRIMARY KEY ,
user TEXT ,
body TEXT ,
time TIMESTAMP ,
latitude FLOAT,
longitude FLOAT
);
现在您可以使用以下语句在其上创建自定义 Lucene 索引:
CREATE CUSTOM INDEX tweets_index ON tweets ()
USING ' com.stratio.cassandra.lucene.Index '
WITH OPTIONS = {
' refresh_seconds ' : ' 1 ' ,
' schema ' : ' {
fields: {
id: {type: "integer"},
user: {type: "string"},
body: {type: "text", analyzer: "english"},
time: {type: "date", pattern: "yyyy/MM/dd"},
place: {type: "geo_point", latitude: "latitude", longitude: "longitude"}
}
} '
};
这将为表中指定类型的所有列建立索引,并且每秒刷新一次。或者,您可以使用具有一致性ALL
空搜索显式刷新所有索引分片:
CONSISTENCY ALL
SELECT * FROM tweets WHERE expr(tweets_index, ' {refresh:true} ' );
CONSISTENCY QUORUM
现在,要搜索特定日期范围内的推文:
SELECT * FROM tweets WHERE expr(tweets_index, ' {
filter: {type: "range", field: "time", lower: "2014/04/25", upper: "2014/05/01"}
} ' );
可以执行相同的搜索,强制显式刷新所涉及的索引分片:
SELECT * FROM tweets WHERE expr(tweets_index, ' {
filter: {type: "range", field: "time", lower: "2014/04/25", upper: "2014/05/01"},
refresh: true
} ' ) limit 100 ;
现在,要搜索上述日期范围内正文字段包含短语“大数据给组织”的前 100 条更相关的推文:
SELECT * FROM tweets WHERE expr(tweets_index, ' {
filter: {type: "range", field: "time", lower: "2014/04/25", upper: "2014/05/01"},
query: {type: "phrase", field: "body", value: "big data gives organizations", slop: 1}
} ' ) LIMIT 100 ;
要优化搜索以仅获取姓名以“a”开头的用户撰写的推文:
SELECT * FROM tweets WHERE expr(tweets_index, ' {
filter: [
{type: "range", field: "time", lower: "2014/04/25", upper: "2014/05/01"},
{type: "prefix", field: "user", value: "a"}
],
query: {type: "phrase", field: "body", value: "big data gives organizations", slop: 1}
} ' ) LIMIT 100 ;
要获取最近 100 个过滤结果,您可以使用排序选项:
SELECT * FROM tweets WHERE expr(tweets_index, ' {
filter: [
{type: "range", field: "time", lower: "2014/04/25", upper: "2014/05/01"},
{type: "prefix", field: "user", value: "a"}
],
query: {type: "phrase", field: "body", value: "big data gives organizations", slop: 1},
sort: {field: "time", reverse: true}
} ' ) limit 100 ;
之前的搜索可以限制为靠近某个地理位置创建的推文:
SELECT * FROM tweets WHERE expr(tweets_index, ' {
filter: [
{type: "range", field: "time", lower: "2014/04/25", upper: "2014/05/01"},
{type: "prefix", field: "user", value: "a"},
{type: "geo_distance", field: "place", latitude: 40.3930, longitude: -3.7328, max_distance: "1km"}
],
query: {type: "phrase", field: "body", value: "big data gives organizations", slop: 1},
sort: {field: "time", reverse: true}
} ' ) limit 100 ;
还可以按到地理位置的距离对结果进行排序:
SELECT * FROM tweets WHERE expr(tweets_index, ' {
filter: [
{type: "range", field: "time", lower: "2014/04/25", upper: "2014/05/01"},
{type: "prefix", field: "user", value: "a"},
{type: "geo_distance", field: "place", latitude: 40.3930, longitude: -3.7328, max_distance: "1km"}
],
query: {type: "phrase", field: "body", value: "big data gives organizations", slop: 1},
sort: [
{field: "time", reverse: true},
{field: "place", type: "geo_distance", latitude: 40.3930, longitude: -3.7328}
]
} ' ) limit 100 ;
最后但并非最不重要的一点是,您可以将任何搜索路由到特定的令牌范围或分区,这样只有集群节点的子集会被命中,从而节省宝贵的资源:
SELECT * FROM tweets WHERE expr(tweets_index, ' {
filter: [
{type: "range", field: "time", lower: "2014/04/25", upper: "2014/05/01"},
{type: "prefix", field: "user", value: "a"},
{type: "geo_distance", field: "place", latitude: 40.3930, longitude: -3.7328, max_distance: "1km"}
],
query: {type: "phrase", field: "body", value: "big data gives organizations", slop: 1},
sort: [
{field: "time", reverse: true},
{field: "place", type: "geo_distance", latitude: 40.3930, longitude: -3.7328}
]
} ' ) AND TOKEN(id) >= TOKEN( 0 ) AND TOKEN(id) < TOKEN( 10000000 ) limit 100 ;
最后是 Hadoop、Spark 和其他 MapReduce 框架支持的基础。
请参阅 Stratio 的 Cassandra Lucene Index 综合文档。