有效地检查大型数据集的子字符串
Check for substring efficiently for large data sets
我有:
- 具有 400 000 000 行的数据库 table (Cassandra 3)
- 大约 10 000 个关键字的列表
- 两个数据集都有望及时增长
我需要:
- 检查指定列是否包含关键字
- 求和列中有多少行包含关键字
我应该选择哪种方法?
方法一(二级索引):
- 创建辅助SASI index on the table
- 随时查找给定关键字 "on fly" 的匹配项
- 但是,我害怕
- 容量问题 - 二级索引会消耗额外的 space 并且对于如此大的 table 它可能太多了
- 性能 - 我不确定是否可以在合理的时间内实现在数亿行中查找关键字
方法 2(Java 作业 - 蛮力):
- Java 连续迭代数据的作业
- 匹配项保存到缓存中
在下一次迭代期间更新缓存
// Paginate throuh data...
String page = null;
do {
PagingState state = page == null ? null : PagingState.fromString(page);
PagedResult<DataRow> res = getDataPaged(query, status, PAGE_SIZE, state);
// Iterate through the current page ...
for (DataRow row : res.getResult()) {
// Skip empty titles
if (row.getTitle().length() == 0) {
continue;
}
// Find match in title
for (String k : keywords) {
if (k.length() > row.getTitle().length()) {
continue;
}
if (row.getTitle().toLowerCase().contains(k.toLowerCase()) {
// TODO: SAVE match
break;
}
}
}
status = res.getResult();
page = res.getPage();
// TODO: Wait here to reduce DB load
} while (page != null);
问题
- 遍历整个 table 可能会很慢。如果我每 1000 行等待一秒钟,那么这个周期将在 4.6 天内完成
- 这需要额外的 space 缓存;此外,频繁从缓存中删除会在 Cassandra 中产生墓碑
更好的方法是使用像 SolR 这样的搜索引擎我们的 ElasticSearch。全文搜索是他们的专长。您可以轻松地将数据从 cassandra 转储到 Elasticsearch 并在 ElasticSearch 之上实施您的 java 作业。
编辑:
使用 Cassandra,您可以将结果查询作为 JSON 请求,而 Elasticsearch 'speak' 仅在 JSON 中,因此您将能够非常轻松地传输数据。
我有:
- 具有 400 000 000 行的数据库 table (Cassandra 3)
- 大约 10 000 个关键字的列表
- 两个数据集都有望及时增长
我需要:
- 检查指定列是否包含关键字
- 求和列中有多少行包含关键字
我应该选择哪种方法?
方法一(二级索引):
- 创建辅助SASI index on the table
- 随时查找给定关键字 "on fly" 的匹配项
- 但是,我害怕
- 容量问题 - 二级索引会消耗额外的 space 并且对于如此大的 table 它可能太多了
- 性能 - 我不确定是否可以在合理的时间内实现在数亿行中查找关键字
方法 2(Java 作业 - 蛮力):
- Java 连续迭代数据的作业
- 匹配项保存到缓存中
在下一次迭代期间更新缓存
// Paginate throuh data... String page = null; do { PagingState state = page == null ? null : PagingState.fromString(page); PagedResult<DataRow> res = getDataPaged(query, status, PAGE_SIZE, state); // Iterate through the current page ... for (DataRow row : res.getResult()) { // Skip empty titles if (row.getTitle().length() == 0) { continue; } // Find match in title for (String k : keywords) { if (k.length() > row.getTitle().length()) { continue; } if (row.getTitle().toLowerCase().contains(k.toLowerCase()) { // TODO: SAVE match break; } } } status = res.getResult(); page = res.getPage(); // TODO: Wait here to reduce DB load } while (page != null);
问题
- 遍历整个 table 可能会很慢。如果我每 1000 行等待一秒钟,那么这个周期将在 4.6 天内完成
- 这需要额外的 space 缓存;此外,频繁从缓存中删除会在 Cassandra 中产生墓碑
更好的方法是使用像 SolR 这样的搜索引擎我们的 ElasticSearch。全文搜索是他们的专长。您可以轻松地将数据从 cassandra 转储到 Elasticsearch 并在 ElasticSearch 之上实施您的 java 作业。
编辑:
使用 Cassandra,您可以将结果查询作为 JSON 请求,而 Elasticsearch 'speak' 仅在 JSON 中,因此您将能够非常轻松地传输数据。