在数据操作中有三个考虑指标:大数据、精确性和实时性。三者难以同时满足。
精确 + 实时
数据可以存入单台机器的内存之中,我们可以随心所欲,使用任何想用的算法。结果会 100% 精确,响应会相对快速。
大数据 + 精确
传统的 Hadoop。可以处理 PB 级的数据并且为我们提供精确的答案,但它可能需要几周的时间才能为我们提供这个答案。
大数据 + 实时
近似算法为我们提供准确但不精确的结果。
Elasticsearch 目前支持两种近似算法( cardinality
和 percentiles
)。 它们会提供准确但不是 100% 精确的结果。
cardinality度量
提供字段的unique值数量。对应sql
SELECT COUNT(DISTINCT color)
FROM cars
dsl语句
GET /cars/transactions/_search { "size" : 0, "aggs" : { "distinct_colors" : { "cardinality" : { "field" : "color" } } } }
精度可以通过precision_threshold调节
GET /cars/transactions/_search { "size" : 0, "aggs" : { "distinct_colors" : { "cardinality" : { "field" : "color", "precision_threshold" : 100 } } } }
示例会确保当字段唯一值在 100 以内时会得到非常准确的结果。尽管算法是无法保证这点的,但如果基数在阈值以下,几乎总是 100% 正确的。高于阈值的基数会开始节省内存而牺牲准确度,同时也会对度量结果带入误差。
precision_threshold
接受 0–40,000 之间的数字,更大的值还是会被当作 40,000 来处理。
如果想在搜索时加速,可以在索引时提前对字段哈希。
percentiles
百分位数度量(看得不太懂,具体是数值怎么算出来的没看懂)
百分位数展现某以具体百分比下观察到的数值。对发现异常很有用。
GET /website/logs/_search { "size" : 0, "aggs" : { "load_times" : { "percentiles" : { "field" : "latency" } }, "avg_load_time" : { "avg" : { "field" : "latency" } } } }
更复杂的例子
GET /website/logs/_search { "size" : 0, "aggs" : { "zones" : { "terms" : { "field" : "zone" }, "aggs" : { "load_times" : { "percentiles" : { "field" : "latency", "percents" : [50, 95.0, 99.0] } }, "load_avg" : { "avg" : { "field" : "latency" } } } } } }
查看某个数值属于哪个百分比:percentile_ranks
GET /website/logs/_search { "size" : 0, "aggs" : { "zones" : { "terms" : { "field" : "zone" }, "aggs" : { "load_times" : { "percentile_ranks" : { "field" : "latency", "values" : [210, 800] } } } } } }
significant_terms 统计在背景流中显著异常的指标。有个很厉害的例子,关于电影推荐的。