在数据操作中有三个考虑指标:大数据、精确性和实时性。三者难以同时满足。

精确 + 实时

  数据可以存入单台机器的内存之中,我们可以随心所欲,使用任何想用的算法。结果会 100% 精确,响应会相对快速。

大数据 + 精确

  传统的 Hadoop。可以处理 PB 级的数据并且为我们提供精确的答案,但它可能需要几周的时间才能为我们提供这个答案。

大数据 + 实时

  近似算法为我们提供准确但不精确的结果。

Elasticsearch 目前支持两种近似算法( cardinality 和 percentiles )。 它们会提供准确但不是 100% 精确的结果。

cardinality度量

提供字段的unique值数量。对应sql

SELECT COUNT(DISTINCT color)
FROM cars

dsl语句

GET /cars/transactions/_search
{
"size" : ,
"aggs" : {
"distinct_colors" : {
"cardinality" : {
"field" : "color"
}
}
}
}

精度可以通过precision_threshold调节

GET /cars/transactions/_search
{
"size" : ,
"aggs" : {
"distinct_colors" : {
"cardinality" : {
"field" : "color",
"precision_threshold" :
}
}
}
}

示例会确保当字段唯一值在 100 以内时会得到非常准确的结果。尽管算法是无法保证这点的,但如果基数在阈值以下,几乎总是 100% 正确的。高于阈值的基数会开始节省内存而牺牲准确度,同时也会对度量结果带入误差。

precision_threshold 接受 0–40,000 之间的数字,更大的值还是会被当作 40,000 来处理。

如果想在搜索时加速,可以在索引时提前对字段哈希。

percentiles 百分位数度量(看得不太懂,具体是数值怎么算出来的没看懂)

百分位数展现某以具体百分比下观察到的数值。对发现异常很有用。

GET /website/logs/_search
{
"size" : ,
"aggs" : {
"load_times" : {
"percentiles" : {
"field" : "latency"
}
},
"avg_load_time" : {
"avg" : {
"field" : "latency"
}
}
}
}

更复杂的例子

GET /website/logs/_search
{
"size" : ,
"aggs" : {
"zones" : {
"terms" : {
"field" : "zone"
},
"aggs" : {
"load_times" : {
"percentiles" : {
"field" : "latency",
"percents" : [, 95.0, 99.0]
}
},
"load_avg" : {
"avg" : {
"field" : "latency"
}
}
}
}
}
}

查看某个数值属于哪个百分比:percentile_ranks

GET /website/logs/_search
{
"size" : ,
"aggs" : {
"zones" : {
"terms" : {
"field" : "zone"
},
"aggs" : {
"load_times" : {
"percentile_ranks" : {
"field" : "latency",
"values" : [, ]
}
}
}
}
}
}

significant_terms 统计在背景流中显著异常的指标。有个很厉害的例子,关于电影推荐的。

05-11 13:17