关于clickhouse:ClickHouse-使用-tokenbfv1-索引加速日志查询

9次阅读

共计 2319 个字符,预计需要花费 6 分钟才能阅读完成。

依据监控日志的特点,咱们对 message 字段增加了 tokenbf_v1 索引。

tokenbf_v1 索引的工作原理如下:

  1. 对于每个列,ClickHouse 会生成一个 tokenbf_v1 过滤器。
  2. 当插入新数据行时,ClickHouse 会将所有列的值分成独自的标记,并将这些标记增加到相应的 tokenbf_v1 过滤器中。
  3. 在执行查问时,如果查问蕴含 WHERE 子句并应用了反对 tokenbf_v1 索引的列,则 ClickHouse 将从 tokenbf_v1 过滤器中获取所有相干的标记,并查看这些标记是否存在于该列的值中。如果标记存在于 tokenbf_v1 过滤器中但不存在于列的值中,则该行数据不合乎查问条件,因而能够疾速被过滤掉。

因为 tokenbf_v1 索引应用了布隆过滤器算法,因而其大小绝对较小,能够无效地缩小文件 I/O 和内存开销。同时,它还反对多列索引和复合索引,使得在简单查问中也可能实现高效率的数据拜访。

在 Bloom filter 设置之前须要一个额定的参数,即要索引的 ngram 的大小。一个 ngram 是长度为 n 的任何字符串,比方如果 n 是 4,A short string 会被宰割为 ’A sh’, ‘ sho’, ‘shor’, ‘hort’, ‘ort ‘, ‘rt s’, ‘t st’, ‘ str’, ‘stri’, ‘trin’, ‘ring’。这个索引对于文本搜寻也很有用,特地是没有单词间断的语言,比方中文。

布隆过滤器参数与成果的查问:https://hur.st/bloomfilter/

依据评估不过过滤器的大小咱们设置为 30720,hash 次数 3;

加了 tokenbf_v1 索引的表构造:

CREATE TABLE monitor.qunhe_log
(`timestamp` DateTime64(3, 'Asia/Shanghai'),
    `hostGroup` String,
    `ip` String,
    `podname` String,
    `level` String,
    `cls` String,
    `behavior` String,
    `message` String,
    `id` String DEFAULT '',
    INDEX message_index message TYPE tokenbf_v1(30720, 3, 0) GRANULARITY 1
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/qunhelog', '{replica}')
PARTITION BY toYYYYMMDD(timestamp)
ORDER BY (level, hostGroup, podname, ip, timestamp)
SETTINGS storage_policy = 'hdd0_hdd1_only', index_granularity = 8192 

反对的 函数:

尽管反对 like 函数,然而 像 like ‘%hunter%’ 这样的查问显然是不会走索引的,因为 clickhouse 不晓得 hunter 是不是一个词。当应用 like ‘hunter’ 时等同于 = 办法,就会索引;

因而为了走索引,hasToken() 是一个比拟罕用的办法,应用 hasToken(‘hunter’) 也就意味着通知 clickhouse ‘hunter’ 是一个词,能够走分词索引,过滤后果是牢靠的;

查问索引成果

以查问某服务最近 10 分钟 taskId=L3D607S41ENDPFVB2EAUWI5ACLUF3P3XG888 为例:

含糊查问
SELECT 
  ip, 
  timestamp, 
  podname, 
  cls, 
  message, 
  level, 
  behavior, 
  hostGroup 
FROM 
  monitor.qunhe_log
WHERE 
  timestamp >= '2023-05-30 19:50:00.000' 
  AND timestamp < '2023-05-30 20:00:00.000' 
  AND hostGroup IN ('********* 隐衷信息 **********') 
  AND message LIKE '%L3D607S41ENDPFVB2EAUWI5ACLUF3P3XG888%' 
ORDER BY 
  (timestamp,) DESC 
LIMIT 
  50 OFFSET 0

耗时 10s

查看索引过滤成果

  • 用 like 查问:耗时 10S,读取了 2.47 million rows 行数据
分词查问
SELECT 
  ip, 
  timestamp, 
  podname, 
  cls, 
  message, 
  level, 
  behavior, 
  hostGroup 
FROM 
  monitor.qunhe_log 
WHERE 
  timestamp >= '2023-05-30 19:50:00.000' 
  AND timestamp < '2023-05-30 20:00:00.000' 
  AND hostGroup IN ('********* 隐衷信息 **********') 
  AND hasToken(message,'L3D607S41ENDPFVB2EAUWI5ACLUF3P3XG888') 
ORDER BY 
  (timestamp,) DESC 
LIMIT 
  50 OFFSET 0

耗时 0.28s

查看索引过滤成果

  • 用 hasToken 查问:耗时 0.24S,读取了 102.40 thousand rows 行数据;
  • 分词索引筛掉了 95% 以上的数据,成果十分好,能够显著看到排掉了 6 个 parts,查问速率显著晋升。

总结

  1. 须要留神的是尽管很多查询方法反对 tokenbf_v1 索引查问,然而不肯定能走索引,比方 like 查问;
  2. 应用 TokenBF_v1 索引须要思考到索引大小、误判率、创立工夫和资源耗费、更新和删除的限度,以及查问优化和版本兼容性等方面的因素。在理论利用中,依据数据集规模和查问需要做出正当的抉择和均衡。
正文完
 0